-
Notifications
You must be signed in to change notification settings - Fork 5
[VPD-817] Upgrade VBep20Delegate for core pool markets #684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
2e783f0
feat: add VIP-608 to upgrade VBep20Delegate for 43 core pool markets
Debugger022 98adfa1
feat: add per-network address constants for VIP-608
Debugger022 fe87557
feat: add VIP-608 cross-chain proposal for isolated pool VToken upgrade
Debugger022 bdd61a7
feat: add isolated pool ABIs for VIP-608 simulations
Debugger022 7fc3d19
feat: add VIP-608 simulation tests for isolated pool VToken upgrade
Debugger022 301b167
feat: add ACM permissions for syncCash in VIP-608 cross-chain upgrade
Debugger022 9b434ba
test: update VIP-608 simulation block numbers and address checksums
Debugger022 e92b7ee
feat: update VIP-608 NEW_VTOKEN_IMPLEMENTATION addresses from isolate…
Debugger022 554ab6d
feat(vip-608): update implementation addresses and split cross-chain …
Debugger022 685b52e
fix(vip-608): correct proxy comments and update simulations
Debugger022 df6f39c
chore: prepare VIP-600/601/602 for proposal (THE attack fix)
fred-venus 52a28d7
chore: prettier format simulation files after rebase
fred-venus File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| [ | ||
| { | ||
| "inputs": [{ "internalType": "address", "name": "implementation_", "type": "address" }], | ||
| "stateMutability": "nonpayable", | ||
| "type": "constructor" | ||
| }, | ||
| { | ||
| "anonymous": false, | ||
| "inputs": [ | ||
| { "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, | ||
| { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" } | ||
| ], | ||
| "name": "OwnershipTransferred", | ||
| "type": "event" | ||
| }, | ||
| { | ||
| "anonymous": false, | ||
| "inputs": [{ "indexed": true, "internalType": "address", "name": "implementation", "type": "address" }], | ||
| "name": "Upgraded", | ||
| "type": "event" | ||
| }, | ||
| { | ||
| "inputs": [], | ||
| "name": "implementation", | ||
| "outputs": [{ "internalType": "address", "name": "", "type": "address" }], | ||
| "stateMutability": "view", | ||
| "type": "function" | ||
| }, | ||
| { | ||
| "inputs": [], | ||
| "name": "owner", | ||
| "outputs": [{ "internalType": "address", "name": "", "type": "address" }], | ||
| "stateMutability": "view", | ||
| "type": "function" | ||
| }, | ||
| { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, | ||
| { | ||
| "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], | ||
| "name": "transferOwnership", | ||
| "outputs": [], | ||
| "stateMutability": "nonpayable", | ||
| "type": "function" | ||
| }, | ||
| { | ||
| "inputs": [{ "internalType": "address", "name": "newImplementation", "type": "address" }], | ||
| "name": "upgradeTo", | ||
| "outputs": [], | ||
| "stateMutability": "nonpayable", | ||
| "type": "function" | ||
| } | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| import { expect } from "chai"; | ||
| import { Contract } from "ethers"; | ||
| import { ethers } from "hardhat"; | ||
| import { expectEvents } from "src/utils"; | ||
| import { forking, testForkedNetworkVipCommands } from "src/vip-framework"; | ||
|
|
||
| import { | ||
| ARBITRUMONE_CORE_COMPTROLLER, | ||
| ARBITRUMONE_CORE_VTOKENS, | ||
| ARBITRUMONE_NEW_VTOKEN_IMPLEMENTATION, | ||
| ARBITRUMONE_VTOKEN_BEACON, | ||
| } from "../../vips/vip-600/addresses/arbitrumone"; | ||
| import vip601 from "../../vips/vip-600/bscmainnet-2"; | ||
| import vip602 from "../../vips/vip-600/bscmainnet-3"; | ||
| import COMPTROLLER_ABI from "./abi/ILComptroller.json"; | ||
| import VTOKEN_ABI from "./abi/ILVToken.json"; | ||
| import VTOKEN_BEACON_ABI from "./abi/vtokenBeacon.json"; | ||
|
|
||
| const BLOCK_NUMBER = 443758428; | ||
|
|
||
| const ERC20_ABI = ["function balanceOf(address) view returns (uint256)"]; | ||
|
|
||
| forking(BLOCK_NUMBER, async () => { | ||
| const provider = ethers.provider; | ||
| const vTokenBeacon = new ethers.Contract(ARBITRUMONE_VTOKEN_BEACON, VTOKEN_BEACON_ABI, provider); | ||
|
|
||
| describe("Pre-VIP behaviour", () => { | ||
| it("CORE_VTOKENS should cover all on-chain markets", async () => { | ||
| const comptroller = new ethers.Contract(ARBITRUMONE_CORE_COMPTROLLER, COMPTROLLER_ABI, provider); | ||
| const allMarkets: string[] = await comptroller.getAllMarkets(); | ||
| expect(ARBITRUMONE_CORE_VTOKENS.length).to.equal(allMarkets.length, "CORE_VTOKENS does not cover all markets"); | ||
| }); | ||
|
|
||
| it("VToken beacon should not point to new implementation", async () => { | ||
| const currentImplementation = await vTokenBeacon.implementation(); | ||
| expect(currentImplementation).to.not.equal(ARBITRUMONE_NEW_VTOKEN_IMPLEMENTATION); | ||
| }); | ||
| }); | ||
|
|
||
| testForkedNetworkVipCommands("VIP-601 Grant syncCash permissions", await vip601()); | ||
|
|
||
| testForkedNetworkVipCommands("VIP-602 Upgrade VToken beacon and syncCash", await vip602(), { | ||
| callbackAfterExecution: async txResponse => { | ||
| await expectEvents(txResponse, [VTOKEN_BEACON_ABI], ["Upgraded"], [1]); | ||
| }, | ||
| }); | ||
|
|
||
| describe("Post-VIP behaviour", () => { | ||
| it("VToken beacon should point to new implementation", async () => { | ||
| const currentImplementation = await vTokenBeacon.implementation(); | ||
| expect(currentImplementation).to.equal(ARBITRUMONE_NEW_VTOKEN_IMPLEMENTATION); | ||
| }); | ||
|
|
||
| for (const vTokenAddress of ARBITRUMONE_CORE_VTOKENS) { | ||
| describe(`VToken ${vTokenAddress}`, () => { | ||
| let vToken: Contract; | ||
|
|
||
| before(async () => { | ||
| vToken = new ethers.Contract(vTokenAddress, VTOKEN_ABI, provider); | ||
| }); | ||
|
|
||
| it("should have internalCash equal to underlying token balance", async () => { | ||
| const internalCash = await vToken.internalCash(); | ||
| const underlyingAddress = await vToken.underlying(); | ||
| const underlyingToken = new ethers.Contract(underlyingAddress, ERC20_ABI, provider); | ||
| const underlyingBalance = await underlyingToken.balanceOf(vTokenAddress); | ||
| expect(internalCash).to.equal(underlyingBalance); | ||
| }); | ||
|
|
||
| it("should allow accrueInterest to succeed", async () => { | ||
| await expect(vToken.callStatic.accrueInterest()).to.not.be.reverted; | ||
| }); | ||
| }); | ||
| } | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| import { expect } from "chai"; | ||
| import { Contract } from "ethers"; | ||
| import { ethers } from "hardhat"; | ||
| import { expectEvents } from "src/utils"; | ||
| import { forking, testForkedNetworkVipCommands } from "src/vip-framework"; | ||
|
|
||
| import { | ||
| BASEMAINNET_CORE_COMPTROLLER, | ||
| BASEMAINNET_CORE_VTOKENS, | ||
| BASEMAINNET_NEW_VTOKEN_IMPLEMENTATION, | ||
| BASEMAINNET_VTOKEN_BEACON, | ||
| } from "../../vips/vip-600/addresses/basemainnet"; | ||
| import vip601 from "../../vips/vip-600/bscmainnet-2"; | ||
| import vip602 from "../../vips/vip-600/bscmainnet-3"; | ||
| import COMPTROLLER_ABI from "./abi/ILComptroller.json"; | ||
| import VTOKEN_ABI from "./abi/ILVToken.json"; | ||
| import VTOKEN_BEACON_ABI from "./abi/vtokenBeacon.json"; | ||
|
|
||
| const BLOCK_NUMBER = 43608484; | ||
|
|
||
| const ERC20_ABI = ["function balanceOf(address) view returns (uint256)"]; | ||
|
|
||
| forking(BLOCK_NUMBER, async () => { | ||
| const provider = ethers.provider; | ||
| const vTokenBeacon = new ethers.Contract(BASEMAINNET_VTOKEN_BEACON, VTOKEN_BEACON_ABI, provider); | ||
|
|
||
| describe("Pre-VIP behaviour", () => { | ||
| it("CORE_VTOKENS should cover all on-chain markets", async () => { | ||
| const comptroller = new ethers.Contract(BASEMAINNET_CORE_COMPTROLLER, COMPTROLLER_ABI, provider); | ||
| const allMarkets: string[] = await comptroller.getAllMarkets(); | ||
| expect(BASEMAINNET_CORE_VTOKENS.length).to.equal(allMarkets.length, "CORE_VTOKENS does not cover all markets"); | ||
| }); | ||
|
|
||
| it("VToken beacon should not point to new implementation", async () => { | ||
| const currentImplementation = await vTokenBeacon.implementation(); | ||
| expect(currentImplementation).to.not.equal(BASEMAINNET_NEW_VTOKEN_IMPLEMENTATION); | ||
| }); | ||
| }); | ||
|
|
||
| testForkedNetworkVipCommands("VIP-601 Grant syncCash permissions", await vip601()); | ||
|
|
||
| testForkedNetworkVipCommands("VIP-602 Upgrade VToken beacon and syncCash", await vip602(), { | ||
| callbackAfterExecution: async txResponse => { | ||
| await expectEvents(txResponse, [VTOKEN_BEACON_ABI], ["Upgraded"], [1]); | ||
| }, | ||
| }); | ||
|
|
||
| describe("Post-VIP behaviour", () => { | ||
| it("VToken beacon should point to new implementation", async () => { | ||
| const currentImplementation = await vTokenBeacon.implementation(); | ||
| expect(currentImplementation).to.equal(BASEMAINNET_NEW_VTOKEN_IMPLEMENTATION); | ||
| }); | ||
|
|
||
| for (const vTokenAddress of BASEMAINNET_CORE_VTOKENS) { | ||
| describe(`VToken ${vTokenAddress}`, () => { | ||
| let vToken: Contract; | ||
|
|
||
| before(async () => { | ||
| vToken = new ethers.Contract(vTokenAddress, VTOKEN_ABI, provider); | ||
| }); | ||
|
|
||
| it("should have internalCash equal to underlying token balance", async () => { | ||
| const internalCash = await vToken.internalCash(); | ||
| const underlyingAddress = await vToken.underlying(); | ||
| const underlyingToken = new ethers.Contract(underlyingAddress, ERC20_ABI, provider); | ||
| const underlyingBalance = await underlyingToken.balanceOf(vTokenAddress); | ||
| expect(internalCash).to.equal(underlyingBalance); | ||
| }); | ||
|
|
||
| it("should allow accrueInterest to succeed", async () => { | ||
| await expect(vToken.callStatic.accrueInterest()).to.not.be.reverted; | ||
| }); | ||
| }); | ||
| } | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import { forking, testVip } from "src/vip-framework"; | ||
|
|
||
| import vip601 from "../../vips/vip-600/bscmainnet-2"; | ||
|
|
||
| const BLOCK_NUMBER = 87684581; | ||
|
|
||
| forking(BLOCK_NUMBER, async () => { | ||
| testVip("VIP-601 Grant syncCash permissions (all networks)", await vip601()); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import { forking, testVip } from "src/vip-framework"; | ||
|
|
||
| import vip602 from "../../vips/vip-600/bscmainnet-3"; | ||
|
|
||
| const BLOCK_NUMBER = 87684581; | ||
|
|
||
| forking(BLOCK_NUMBER, async () => { | ||
| testVip("VIP-602 Upgrade VToken beacon and syncCash (all networks)", await vip602()); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| import { expect } from "chai"; | ||
| import { BigNumber, Contract } from "ethers"; | ||
| import { ethers } from "hardhat"; | ||
| import { forking, testVip } from "src/vip-framework"; | ||
|
|
||
| import vip600 from "../../vips/vip-600/bscmainnet"; | ||
| import VBEP20_DELEGATE_ABI from "./abi/VBep20Delegate.json"; | ||
|
|
||
| const BLOCK_NUMBER = 87684581; | ||
|
|
||
| const NEW_VBEP20_DELEGATE_IMPL = "0xb25b57599BA969c4829699F7E4Fc4076D14745E1"; | ||
|
|
||
| const ERC20_ABI = ["function balanceOf(address) view returns (uint256)"]; | ||
|
|
||
| // All 43 VBep20Delegator proxy addresses | ||
| const MARKET_ADDRESSES = [ | ||
| "0xecA88125a5ADbe82614ffC12D0DB554E2e2867C8", // vUSDC | ||
| "0xfD5840Cd36d94D7229439859C0112a4185BC0255", // vUSDT | ||
| "0x95c78222B3D6e262426483D42CfA53685A67Ab9D", // vBUSD | ||
| "0x2fF3d0F6990a40261c66E1ff2017aCBc282EB6d0", // vSXP | ||
| "0x151B1e2635A717bcDc836ECd6FbB62B674FE3E1D", // vXVS | ||
| "0x882C173bC7Ff3b7786CA16dfeD3DFFfb9Ee7847B", // vBTC | ||
| "0xf508fCD89b8bd15579dc79A6827cB4686A3592c8", // vETH | ||
| "0x57A5297F2cB2c0AaC9D554660acd6D385Ab50c6B", // vLTC | ||
| "0xB248a295732e0225acd3337607cc01068e3b9c10", // vXRP | ||
| "0x5F0388EBc2B94FA8E123F404b79cCF5f40b29176", // vBCH | ||
| "0x1610bc33319e9398de5f57B33a5b184c806aD217", // vDOT | ||
| "0x650b940a1033B8A1b1873f78730FcFC73ec11f1f", // vLINK | ||
| "0x334b3eCB4DCa3593BCCC3c7EBD1A1C1d1780FBF1", // vDAI | ||
| "0xf91d58b5aE142DAcC749f58A49FCBac340Cb0343", // vFIL | ||
| "0x972207A639CC1B374B893cc33Fa251b55CEB7c07", // vBETH | ||
| "0x9A0AF7FDb2065Ce470D72664DE73cAE409dA28Ec", // vADA | ||
| "0xec3422Ef92B2fb59e84c8B02Ba73F1fE84Ed8D71", // vDOGE | ||
| "0x5c9476FcD6a4F9a3654139721c949c2233bBbBc8", // vMATIC | ||
| "0x86aC3974e2BD0d60825230fa6F355fF11409df5c", // vCAKE | ||
| "0x26DA28954763B92139ED49283625ceCAf52C6f94", // vAAVE | ||
| "0x08CEB3F4a7ed3500cA0982bcd0FC7816688084c3", // vTUSDOLD | ||
| "0x61eDcFe8Dd6bA3c891CB9bEc2dc7657B3B422E93", // vTRXOLD | ||
| "0xC5D3466aA484B040eE977073fcF337f2c00071c1", // vTRX | ||
| "0x6CFdEc747f37DAf3b87a35a1D9c8AD3063A1A8A0", // vWBETH | ||
| "0xBf762cd5991cA1DCdDaC9ae5C638F5B5Dc3Bee6E", // vTUSD | ||
| "0x27FF564707786720C71A2e5c1490A63266683612", // vUNI | ||
| "0xC4eF4229FEc74Ccfe17B2bdeF7715fAC740BA0ba", // vFDUSD | ||
| "0x4d41a36D04D97785bcEA57b057C412b278e6Edcc", // vTWT | ||
| "0xf841cb62c19fCd4fF5CD0AaB5939f3140BaaC3Ea", // vSolvBTC | ||
| "0x86e06EAfa6A1eA631Eab51DE500E3D474933739f", // vTHE | ||
| "0xBf515bA4D1b52FFdCeaBF20d31D705Ce789F2cEC", // vSOL | ||
| "0x689E0daB47Ab16bcae87Ec18491692BF621Dc6Ab", // vlisUSD | ||
| "0x9e4E5fed5Ac5B9F732d0D850A615206330Bf1866", // vPT-sUSDE-26JUN2025 | ||
| "0x699658323d58eE25c69F1a29d476946ab011bD18", // vsUSDe | ||
| "0x74ca6930108F775CC667894EEa33843e691680d7", // vUSDe | ||
| "0x0C1DA220D301155b87318B90692Da8dc43B67340", // vUSD1 | ||
| "0xd804dE60aFD05EE6B89aab5D152258fD461B07D5", // vxSolvBTC | ||
| "0xCC1dB43a06d97f736C7B045AedD03C6707c09BDF", // vasBNB | ||
| "0x6bCa74586218dB34cdB402295796b79663d816e9", // vWBNB | ||
| "0x89c910Eb8c90df818b4649b508Ba22130Dc73Adc", // vslisBNB | ||
| "0x3d5E269787d562b74aCC55F18Bd26C5D09Fa245E", // vU | ||
| "0x6d3BD68E90B42615cb5abF4B8DE92b154ADc435e", // vPT-clisBNB-25JUN2026 | ||
| "0x92e6Ea74a1A3047DabF4186405a21c7D63a0612A", // vXAUM | ||
| ]; | ||
|
|
||
| const MARKET_NAMES = [ | ||
| "vUSDC", | ||
| "vUSDT", | ||
| "vBUSD", | ||
| "vSXP", | ||
| "vXVS", | ||
| "vBTC", | ||
| "vETH", | ||
| "vLTC", | ||
| "vXRP", | ||
| "vBCH", | ||
| "vDOT", | ||
| "vLINK", | ||
| "vDAI", | ||
| "vFIL", | ||
| "vBETH", | ||
| "vADA", | ||
| "vDOGE", | ||
| "vMATIC", | ||
| "vCAKE", | ||
| "vAAVE", | ||
| "vTUSDOLD", | ||
| "vTRXOLD", | ||
| "vTRX", | ||
| "vWBETH", | ||
| "vTUSD", | ||
| "vUNI", | ||
| "vFDUSD", | ||
| "vTWT", | ||
| "vSolvBTC", | ||
| "vTHE", | ||
| "vSOL", | ||
| "vlisUSD", | ||
| "vPT-sUSDE-26JUN2025", | ||
| "vsUSDe", | ||
| "vUSDe", | ||
| "vUSD1", | ||
| "vxSolvBTC", | ||
| "vasBNB", | ||
| "vWBNB", | ||
| "vslisBNB", | ||
| "vU", | ||
| "vPT-clisBNB-25JUN2026", | ||
| "vXAUM", | ||
| ]; | ||
|
|
||
| interface MarketSnapshot { | ||
| totalBorrows: BigNumber; | ||
| totalReserves: BigNumber; | ||
| totalSupply: BigNumber; | ||
| exchangeRate: BigNumber; | ||
| } | ||
|
|
||
| forking(BLOCK_NUMBER, async () => { | ||
| const provider = ethers.provider; | ||
| const preVipSnapshots: Map<string, MarketSnapshot> = new Map(); | ||
|
|
||
| before(async () => { | ||
| // Capture pre-VIP state for all markets | ||
| for (let i = 0; i < MARKET_ADDRESSES.length; i++) { | ||
| const vToken = new ethers.Contract(MARKET_ADDRESSES[i], VBEP20_DELEGATE_ABI, provider); | ||
| const [totalBorrows, totalReserves, totalSupply, exchangeRate] = await Promise.all([ | ||
| vToken.totalBorrows(), | ||
| vToken.totalReserves(), | ||
| vToken.totalSupply(), | ||
| vToken.exchangeRateStored(), | ||
| ]); | ||
| preVipSnapshots.set(MARKET_ADDRESSES[i], { totalBorrows, totalReserves, totalSupply, exchangeRate }); | ||
| } | ||
| }); | ||
|
|
||
| testVip("VIP-600 Upgrade VBep20Delegate for Core Pool", await vip600()); | ||
|
|
||
| describe("Post-VIP behavior", async () => { | ||
| for (let i = 0; i < MARKET_ADDRESSES.length; i++) { | ||
| const marketAddress = MARKET_ADDRESSES[i]; | ||
| const marketName = MARKET_NAMES[i]; | ||
|
|
||
| describe(`${marketName} (${marketAddress})`, () => { | ||
| let vToken: Contract; | ||
|
|
||
| before(async () => { | ||
| vToken = new ethers.Contract(marketAddress, VBEP20_DELEGATE_ABI, provider); | ||
| }); | ||
|
|
||
| it("should have the new implementation", async () => { | ||
| expect(await vToken.implementation()).to.equal(NEW_VBEP20_DELEGATE_IMPL); | ||
| }); | ||
|
|
||
| it("should have internalCash equal to underlying token balance", async () => { | ||
| const internalCash = await vToken.internalCash(); | ||
| const underlyingAddress = await vToken.underlying(); | ||
| const underlyingToken = new ethers.Contract(underlyingAddress, ERC20_ABI, provider); | ||
| const underlyingBalance = await underlyingToken.balanceOf(marketAddress); | ||
| expect(internalCash).to.equal(underlyingBalance); | ||
| }); | ||
|
|
||
| it("should preserve totalSupply", async () => { | ||
| const snapshot = preVipSnapshots.get(marketAddress)!; | ||
| expect(await vToken.totalSupply()).to.equal(snapshot.totalSupply); | ||
| }); | ||
|
|
||
| it("should allow accrueInterest to succeed", async () => { | ||
| // accrueInterest should work correctly with synced internalCash | ||
| await expect(vToken.callStatic.accrueInterest()).to.not.be.reverted; | ||
| }); | ||
| }); | ||
| } | ||
| }); | ||
| }); | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: VenusProtocol/vips
Length of output: 1421
Assert that
accrueInterest()returns 0 (success code) instead of only checking non-revert.The
accrueInterest()function returns auint256error code (0 for success, non-zero for failure). Using onlyto.not.be.revertedverifies the call didn't throw, but a failing error code will still pass this assertion. Change the assertion toexpect(await vToken.callStatic.accrueInterest()).to.equal(0).This pattern is duplicated across 8 test files in
simulations/vip-608/: bscmainnet.ts, zksyncmainnet.ts, unichainmainnet.ts, opmainnet.ts, opbnbmainnet.ts, ethereum.ts, basemainnet.ts, and arbitrumone.ts. All instances must be updated to properly validate success.🤖 Prompt for AI Agents