Skip to content
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

Add solvency check. #2131

Merged
merged 9 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
6 changes: 6 additions & 0 deletions contracts/contracts/vault/OETHVaultCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ contract OETHVaultCore is VaultCore {
amount: uint128(_amount),
queued: uint128(queued)
});

_postRedeem(_amount);
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit pls add a comment that this is here to do an insolvency check.

}

/**
Expand All @@ -218,6 +220,8 @@ contract OETHVaultCore is VaultCore {

// transfer WETH from the vault to the withdrawer
IERC20(weth).safeTransfer(msg.sender, amount);

_postRedeem(amount);
}

/**
Expand All @@ -243,6 +247,8 @@ contract OETHVaultCore is VaultCore {

// transfer all the claimed WETH from the vault to the withdrawer
IERC20(weth).safeTransfer(msg.sender, totalAmount);

_postRedeem(totalAmount);
}

// slither-disable-start reentrancy-no-eth
Expand Down
77 changes: 77 additions & 0 deletions contracts/test/vault/oeth-vault.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const { createFixtureLoader, oethDefaultFixture } = require("../_fixture");
const { parseUnits } = require("ethers/lib/utils");
const { deployWithConfirmation } = require("../../utils/deploy");
const { oethUnits, advanceTime } = require("../helpers");
const { impersonateAndFund } = require("../../utils/signers");
const addresses = require("../../utils/addresses");

const oethFixture = createFixtureLoader(oethDefaultFixture);
Expand Down Expand Up @@ -374,6 +375,9 @@ describe("OETH Vault", function () {
await oethVault.connect(daniel).mint(weth.address, oethUnits("10"), "0");
await oethVault.connect(josh).mint(weth.address, oethUnits("20"), "0");
await oethVault.connect(matt).mint(weth.address, oethUnits("30"), "0");
await oethVault
.connect(await impersonateAndFund(await oethVault.governor()))
.setMaxSupplyDiff(oethUnits("0.03"));
});
const firstRequestAmount = oethUnits("5");
const secondRequestAmount = oethUnits("18");
Expand Down Expand Up @@ -621,6 +625,20 @@ describe("OETH Vault", function () {
fixtureWithUser
);
});
it("Should claim single big request as a whale", async () => {
const { oethVault, matt } = fixture;

await oethVault.connect(matt).requestWithdrawal(oethUnits("30"));
naddison36 marked this conversation as resolved.
Show resolved Hide resolved

await advanceTime(delayPeriod); // Advance in time to ensure time delay between request and claim.

const tx = await oethVault.connect(matt).claimWithdrawal(0); // Claim withdrawal for 50% of the supply
naddison36 marked this conversation as resolved.
Show resolved Hide resolved

await expect(tx)
.to.emit(oethVault, "WithdrawalClaimed")
.withArgs(matt.address, 0, oethUnits("30"));
});

it("Should fail claim request because of not enough time passed", async () => {
const { oethVault, daniel } = fixture;

Expand All @@ -633,6 +651,65 @@ describe("OETH Vault", function () {

await expect(tx).to.revertedWith("Claim delay not met");
});
it("Should fail request withdrawal because of solvency check too high", async () => {
const { oethVault, daniel, weth } = fixture;

await weth.connect(daniel).transfer(oethVault.address, oethUnits("10"));

const tx = oethVault
.connect(daniel)
.requestWithdrawal(firstRequestAmount);

await expect(tx).to.revertedWith("Backing supply liquidity error");
});
it("Should fail claim request because of solvency check too high", async () => {
const { oethVault, daniel, weth } = fixture;

// Request withdrawal of 5 OETH
await oethVault.connect(daniel).requestWithdrawal(firstRequestAmount);

// Transfer 10 WETH to the vault
await weth.connect(daniel).transfer(oethVault.address, oethUnits("10"));

await advanceTime(delayPeriod); // Advance in time to ensure time delay between request and claim.

// Claim the withdrawal
const tx = oethVault.connect(daniel).claimWithdrawal(0);

await expect(tx).to.revertedWith("Backing supply liquidity error");
});
it("Should fail multiple claim requests because of solvency check too high", async () => {
const { oethVault, matt, weth } = fixture;

// Request withdrawal of 5 OETH
await oethVault.connect(matt).requestWithdrawal(firstRequestAmount);
await oethVault.connect(matt).requestWithdrawal(secondRequestAmount);

// Transfer 10 WETH to the vault
await weth.connect(matt).transfer(oethVault.address, oethUnits("10"));

await advanceTime(delayPeriod); // Advance in time to ensure time delay between request and claim.

// Claim the withdrawal
const tx = oethVault.connect(matt).claimWithdrawals([0, 1]);

await expect(tx).to.revertedWith("Backing supply liquidity error");
});

it("Should fail request withdrawal because of solvency check too low", async () => {
const { oethVault, daniel, weth } = fixture;

// Simulate a loss of funds from the vault
await weth
.connect(await impersonateAndFund(oethVault.address))
.transfer(daniel.address, oethUnits("10"));

const tx = oethVault
.connect(daniel)
.requestWithdrawal(firstRequestAmount);

await expect(tx).to.revertedWith("Backing supply liquidity error");
});

describe("when deposit some WETH to a strategy", () => {
let mockStrategy;
Expand Down
Loading