Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/protocol/helpers/vaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ export async function reportVaultDataWithProof(
.updateReportData(reportTimestampArg, reportRefSlotArg, reportTree.root, "");
}

return await lazyOracle.updateVaultData(
return lazyOracle.updateVaultData(
await stakingVault.getAddress(),
vaultReport.totalValue,
vaultReport.cumulativeLidoFees,
Expand Down
54 changes: 49 additions & 5 deletions test/integration/core/accounting.integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ import { setBalance } from "@nomicfoundation/hardhat-network-helpers";

import { ether, impersonate, log, ONE_GWEI, updateBalance } from "lib";
import { LIMITER_PRECISION_BASE } from "lib/constants";
import { finalizeWQViaSubmit, getProtocolContext, getReportTimeElapsed, ProtocolContext, report } from "lib/protocol";
import {
finalizeWQViaSubmit,
getProtocolContext,
getReportTimeElapsed,
OracleReportParams,
ProtocolContext,
report,
} from "lib/protocol";

import { Snapshot } from "test/suite";
import { MAX_BASIS_POINTS, ONE_DAY, SHARE_RATE_PRECISION } from "test/suite/constants";
Expand Down Expand Up @@ -97,23 +104,60 @@ describe("Integration: Accounting", () => {
}
}

// TODO: remove or fix and make it more meaningful for both scratch and mainnet limits
it.skip("Should reverts report on sanity checks", async () => {
const { oracleReportSanityChecker } = ctx.contracts;
it("reverts if the CL increase balance is incorrect", async () => {
const { oracleReportSanityChecker, withdrawalVault } = ctx.contracts;

const maxCLRebaseViaLimiter = await rebaseLimitWei();
console.debug({ maxCLRebaseViaLimiter });

// Expected annual limit to shot first
const rebaseAmount = maxCLRebaseViaLimiter - 1n;

const params = { clDiff: rebaseAmount, excludeVaultsBalances: true };
const params: Partial<OracleReportParams> = {
clDiff: rebaseAmount,
excludeVaultsBalances: true,
withdrawalVaultBalance: await ethers.provider.getBalance(withdrawalVault),
};
await expect(report(ctx, params)).to.be.revertedWithCustomError(
oracleReportSanityChecker,
"IncorrectCLBalanceIncrease(uint256)",
);
});

it("reverts if the withdrawal vault balance is greater than reported", async () => {
const { oracleReportSanityChecker, withdrawalVault } = ctx.contracts;

const balance = await ethers.provider.getBalance(withdrawalVault);

const params: Partial<OracleReportParams> = {
excludeVaultsBalances: false,
withdrawalVaultBalance: balance + 1n,
reportWithdrawalsVault: true,
};

await expect(report(ctx, params)).to.be.revertedWithCustomError(
oracleReportSanityChecker,
"IncorrectWithdrawalsVaultBalance(uint256)",
);
});

it("reverts if the withdrawal vault balance is greater than reported", async () => {
const { oracleReportSanityChecker, withdrawalVault } = ctx.contracts;

const balance = await ethers.provider.getBalance(withdrawalVault);

const params: Partial<OracleReportParams> = {
excludeVaultsBalances: false,
withdrawalVaultBalance: balance + 1n,
reportWithdrawalsVault: true,
};

await expect(report(ctx, params)).to.be.revertedWithCustomError(
oracleReportSanityChecker,
"IncorrectWithdrawalsVaultBalance(uint256)",
);
});

it("Should account correctly with no CL rebase", async () => {
const { lido, accountingOracle } = ctx.contracts;

Expand Down
80 changes: 5 additions & 75 deletions test/integration/vaults/obligations.integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -686,8 +686,7 @@ describe("Integration: Vault redemptions and fees obligations", () => {
});
});

// TODO: Need to fix the disconnect flow first
context.skip("Disconnect flow", () => {
context("Disconnect flow", () => {
it("Reverts when trying to disconnect with unsettled obligations", async () => {
await reportVaultDataWithProof(ctx, stakingVault, { cumulativeLidoFees: ether("1.1") });

Expand All @@ -699,8 +698,8 @@ describe("Integration: Vault redemptions and fees obligations", () => {

// will revert because of the unsettled obligations event trying to settle using the connection deposit
await expect(dashboard.voluntaryDisconnect())
.to.be.revertedWithCustomError(vaultHub, "UnsettledObligationsExceedsAllowance")
.withArgs(stakingVaultAddress, ether("1"), 0);
.to.be.revertedWithCustomError(vaultHub, "NoUnsettledLidoFeesShouldBeLeft")
.withArgs(stakingVaultAddress, ether("1.1"));

expect(obligations.cumulativeLidoFees).to.equal(ether("1.1"));
expect(await ethers.provider.getBalance(stakingVaultAddress)).to.equal(ether("1"));
Expand All @@ -711,8 +710,8 @@ describe("Integration: Vault redemptions and fees obligations", () => {
await dashboard.fund({ value: ether("0.1") });

await expect(dashboard.voluntaryDisconnect())
.to.emit(vaultHub, "VaultObligationsSettled")
.withArgs(stakingVaultAddress, 0n, ether("1.1"), 0n, 0n, ether("1.1"))
.to.emit(vaultHub, "LidoFeesSettled")
.withArgs(stakingVaultAddress, ether("1.1"), ether("1.1"), ether("1.1"))
.to.emit(vaultHub, "VaultDisconnectInitiated")
.withArgs(stakingVaultAddress);
});
Expand All @@ -733,74 +732,5 @@ describe("Integration: Vault redemptions and fees obligations", () => {
expect(await ethers.provider.getBalance(stakingVaultAddress)).to.equal(ether("0.1"));
expect(await vaultHub.totalValue(stakingVaultAddress)).to.equal(ether("0.1"));
});

it("Reverts disconnect process when balance is not enough to cover the exit fees", async () => {
expect(await vaultHub.totalValue(stakingVaultAddress)).to.equal(ether("1"));
await reportVaultDataWithProof(ctx, stakingVault, { cumulativeLidoFees: ether("1") });

const totalValue = await vaultHub.totalValue(stakingVaultAddress);
await dashboard.voluntaryDisconnect();

// take the last fees from the post disconnect report (1.1 ether because fees are cumulative)
await expect(reportVaultDataWithProof(ctx, stakingVault, { totalValue, cumulativeLidoFees: ether("1.1") }))
.to.be.revertedWithCustomError(vaultHub, "UnsettledObligationsExceedsAllowance")
.withArgs(stakingVaultAddress, ether("0.1"), 0);
});

it("Should take last fees from the post disconnect report with direct transfer", async () => {
// 1 ether of the connection deposit will be settled to the treasury
await reportVaultDataWithProof(ctx, stakingVault, { cumulativeLidoFees: ether("1") });

const totalValueOnRefSlot = await vaultHub.totalValue(stakingVaultAddress);

// successfully disconnect
await dashboard.voluntaryDisconnect();

// adding 1 ether to cover the exit fees
await owner.sendTransaction({ to: stakingVaultAddress, value: ether("1") });

// take the last fees from the post disconnect report (1.1 ether because fees are cumulative)
await expect(
await reportVaultDataWithProof(ctx, stakingVault, {
totalValue: totalValueOnRefSlot,
cumulativeLidoFees: ether("1.1"),
}),
)
.to.emit(vaultHub, "VaultObligationsSettled")
.withArgs(stakingVaultAddress, 0n, ether("0.1"), 0n, 0n, ether("1.1"))
.to.emit(vaultHub, "VaultDisconnectCompleted")
.withArgs(stakingVaultAddress);

// 0.9 ether should be left in the vault
expect(await ethers.provider.getBalance(stakingVaultAddress)).to.equal(ether("0.9"));
});

it("Should take last fees from the post disconnect report with fund", async () => {
// 1 ether of the connection deposit will be settled to the treasury
await reportVaultDataWithProof(ctx, stakingVault, { cumulativeLidoFees: ether("1") });

const totalValueOnRefSlot = await vaultHub.totalValue(stakingVaultAddress);

// successfully disconnect
await dashboard.voluntaryDisconnect();

// adding 1 ether to cover the exit fees
await dashboard.fund({ value: ether("1") });

// take the last fees from the post disconnect report (1.1 ether because fees are cumulative)
await expect(
await reportVaultDataWithProof(ctx, stakingVault, {
totalValue: totalValueOnRefSlot,
cumulativeLidoFees: ether("1.1"),
}),
)
.to.emit(vaultHub, "VaultObligationsSettled")
.withArgs(stakingVaultAddress, 0n, ether("0.1"), 0n, 0n, ether("1.1"))
.to.emit(vaultHub, "VaultDisconnectCompleted")
.withArgs(stakingVaultAddress);

// 0.9 ether should be left in the vault
expect(await ethers.provider.getBalance(stakingVaultAddress)).to.equal(ether("0.9"));
});
});
});
4 changes: 2 additions & 2 deletions test/integration/vaults/roles.integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe("Integration: Staking Vaults Dashboard Roles Initial Setup", () => {
}
});

describe.skip("Verify ACL for methods that require only role", () => {
describe("Verify ACL for methods that require only role", () => {
describe("Dashboard methods", () => {
it("setNodeOperatorFeeRecipient", async () => {
await testGrantingRole(
Expand All @@ -98,7 +98,7 @@ describe("Integration: Staking Vaults Dashboard Roles Initial Setup", () => {
}
});

describe.skip("Verify ACL for methods that require only role", () => {
describe("Verify ACL for methods that require only role", () => {
describe("Dashboard methods", () => {
it("setNodeOperatorFeeRecipient", async () => {
await testGrantingRole(
Expand Down
Loading
Loading