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

Enable async withdrawals on superOETHb #2275

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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 contracts/contracts/harvest/FixedRateDripper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
* @param _perSecond Rate of WETH to drip per second
*/
function setDripRate(uint192 _perSecond) external onlyGovernorOrStrategist {
emit DripRateUpdated(_perSecond, drip.perSecond);
emit DripRateUpdated(drip.perSecond, _perSecond);

Check warning on line 61 in contracts/contracts/harvest/FixedRateDripper.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/harvest/FixedRateDripper.sol#L61

Added line #L61 was not covered by tests
shahthepro marked this conversation as resolved.
Show resolved Hide resolved
shahthepro marked this conversation as resolved.
Show resolved Hide resolved

/**
* Note: It's important to call `_collect` before updating
Expand Down
4 changes: 4 additions & 0 deletions contracts/contracts/interfaces/IVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -264,4 +264,8 @@ interface IVault {
external
view
returns (bool);

function withdrawalClaimDelay() external view returns (uint256);

function setWithdrawalClaimDelay(uint256 newDelay) external;
}
29 changes: 9 additions & 20 deletions contracts/contracts/vault/OETHBaseVaultCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,33 +81,22 @@
// @inheritdoc OETHVaultCore
// solhint-disable-next-line no-unused-vars
function requestWithdrawal(uint256 _amount)
external
public
virtual
override
returns (uint256, uint256)
returns (uint256 requestId, uint256 queued)
{
revert("Async withdrawals disabled");
require(withdrawalClaimDelay > 0, "Async withdrawals not enabled");
return super.requestWithdrawal(_amount);

Check warning on line 90 in contracts/contracts/vault/OETHBaseVaultCore.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/vault/OETHBaseVaultCore.sol#L90

Added line #L90 was not covered by tests
}

// @inheritdoc OETHVaultCore
// solhint-disable-next-line no-unused-vars
function claimWithdrawal(uint256 _requestId)
external
virtual
override
returns (uint256)
{
revert("Async withdrawals disabled");
}

// @inheritdoc OETHVaultCore
// solhint-disable-next-line no-unused-vars
function claimWithdrawals(uint256[] memory _requestIds)
external
function _claimWithdrawal(uint256 requestId)

Check warning on line 93 in contracts/contracts/vault/OETHBaseVaultCore.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/vault/OETHBaseVaultCore.sol#L93

Added line #L93 was not covered by tests
internal
virtual
override
returns (uint256[] memory, uint256)
returns (uint256 amount)
{
revert("Async withdrawals disabled");
require(withdrawalClaimDelay > 0, "Async withdrawals not enabled");
return _claimWithdrawal(requestId, withdrawalClaimDelay);

Check warning on line 100 in contracts/contracts/vault/OETHBaseVaultCore.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/vault/OETHBaseVaultCore.sol#L100

Added line #L100 was not covered by tests
}
}
12 changes: 10 additions & 2 deletions contracts/contracts/vault/OETHVaultCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ contract OETHVaultCore is VaultCore {
* @param queued Cumulative total of all WETH queued including already claimed requests.
*/
function requestWithdrawal(uint256 _amount)
external
public
virtual
whenNotCapitalPaused
nonReentrant
Expand Down Expand Up @@ -284,6 +284,14 @@ contract OETHVaultCore is VaultCore {
}

function _claimWithdrawal(uint256 requestId)
internal
virtual
returns (uint256 amount)
{
return _claimWithdrawal(requestId, CLAIM_DELAY);
}

function _claimWithdrawal(uint256 requestId, uint256 claimDelay)
shahthepro marked this conversation as resolved.
Show resolved Hide resolved
internal
returns (uint256 amount)
{
Expand All @@ -292,7 +300,7 @@ contract OETHVaultCore is VaultCore {
WithdrawalQueueMetadata memory queue = withdrawalQueueMetadata;

require(
request.timestamp + CLAIM_DELAY <= block.timestamp,
request.timestamp + claimDelay <= block.timestamp,
"Claim delay not met"
);
// If there isn't enough reserved liquidity in the queue to claim
Expand Down
14 changes: 14 additions & 0 deletions contracts/contracts/vault/VaultAdmin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,20 @@
emit DripperChanged(_dripper);
}

/**
* @notice Changes the async withdrawal claim period for superOETHb
* @param _delay Delay period (should be between 30mins to 7 days).
* Set to 0 to disable async withdrawals
*/
function setWithdrawalClaimDelay(uint256 _delay) external onlyGovernor {
require(
_delay == 0 || (_delay >= 30 minutes && _delay <= 7 days),
shahthepro marked this conversation as resolved.
Show resolved Hide resolved
"Invalid claim delay period"
);
emit WithdrawalClaimDelayUpdated(withdrawalClaimDelay, _delay);
shahthepro marked this conversation as resolved.
Show resolved Hide resolved
withdrawalClaimDelay = _delay;

Check warning on line 177 in contracts/contracts/vault/VaultAdmin.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/vault/VaultAdmin.sol#L176-L177

Added lines #L176 - L177 were not covered by tests
}

/***************************************
Swaps
****************************************/
Expand Down
6 changes: 5 additions & 1 deletion contracts/contracts/vault/VaultStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ contract VaultStorage is Initializable, Governable {
uint256 _amount
);
event WithdrawalClaimable(uint256 _claimable, uint256 _newClaimable);
event WithdrawalClaimDelayUpdated(uint256 _oldDelay, uint256 _newDelay);

// Assets supported by the Vault, i.e. Stablecoins
enum UnitConversion {
Expand Down Expand Up @@ -236,8 +237,11 @@ contract VaultStorage is Initializable, Governable {
/// @notice Mapping of withdrawal request indices to the user withdrawal request data
mapping(uint256 => WithdrawalRequest) public withdrawalRequests;

/// @notice Used for superOETHb async withdrawal
uint256 public withdrawalClaimDelay;

// For future use
uint256[45] private __gap;
uint256[44] private __gap;

/**
* @notice set the implementation for the admin, this needs to be in a base class else we cannot set it
Expand Down
45 changes: 45 additions & 0 deletions contracts/deploy/base/018_async_withdrawals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const { deployOnBaseWithGuardian } = require("../../utils/deploy-l2");
const { deployWithConfirmation } = require("../../utils/deploy");
const addresses = require("../../utils/addresses");

module.exports = deployOnBaseWithGuardian(
{
deployName: "018_async_withdrawals",
},
async ({ ethers }) => {
const cOETHbVaultProxy = await ethers.getContract("OETHBaseVaultProxy");
const cOETHbVault = await ethers.getContractAt(
"IVault",
cOETHbVaultProxy.address
);

// Deploy new implementation
const dOETHbVaultCore = await deployWithConfirmation("OETHBaseVaultCore", [
addresses.base.WETH,
]);
const dOETHbVaultAdmin = await deployWithConfirmation("OETHBaseVaultAdmin");

return {
actions: [
{
// 1. Upgrade VaultCore
contract: cOETHbVaultProxy,
signature: "upgradeTo(address)",
args: [dOETHbVaultCore.address],
},
{
// 2. Upgrade VaultAdmin
contract: cOETHbVault,
signature: "setAdminImpl(address)",
args: [dOETHbVaultAdmin.address],
},
{
// 3. Set async claim delay to 1 day
contract: cOETHbVault,
signature: "setWithdrawalClaimDelay(uint256)",
args: [24 * 60 * 60], // 1d
},
],
};
}
);
40 changes: 24 additions & 16 deletions contracts/test/vault/oethb-vault.base.fork-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { defaultBaseFixture } = require("../_fixture-base");
const { expect } = require("chai");
const addresses = require("../../utils/addresses");
const { impersonateAndFund } = require("../../utils/signers");
const { oethUnits } = require("../helpers");
const { oethUnits, advanceTime } = require("../helpers");
const { deployWithConfirmation } = require("../../utils/deploy");

const baseFixture = createFixtureLoader(defaultBaseFixture);
Expand All @@ -14,14 +14,14 @@ describe("ForkTest: OETHb Vault", function () {
fixture = await baseFixture();
});

describe("Mint & Permissioned redeems", function () {
async function _mint(signer) {
const { weth, oethbVault } = fixture;
await weth.connect(signer).deposit({ value: oethUnits("1") });
await weth.connect(signer).approve(oethbVault.address, oethUnits("1"));
await oethbVault.connect(signer).mint(weth.address, oethUnits("1"), "0");
}
async function _mint(signer) {
const { weth, oethbVault } = fixture;
await weth.connect(signer).deposit({ value: oethUnits("1") });
await weth.connect(signer).approve(oethbVault.address, oethUnits("1"));
await oethbVault.connect(signer).mint(weth.address, oethUnits("1"), "0");
}

describe("Mint & Permissioned redeems", function () {
it("Should allow anyone to mint", async () => {
const { nick, weth, oethb, oethbVault } = fixture;

Expand Down Expand Up @@ -113,20 +113,28 @@ describe("ForkTest: OETHb Vault", function () {
});

describe("Async withdrawals", function () {
it("Should be disabled", async () => {
const { oethbVault, nick } = fixture;
it("Should allow 1:1 async withdrawals", async function () {
const { rafael, oethbVault } = fixture;

let tx = oethbVault.connect(nick).requestWithdrawal(oethUnits("1"));
const delayPeriod = await oethbVault.withdrawalClaimDelay();

await expect(tx).to.be.revertedWith("Async withdrawals disabled");
if (delayPeriod == 0) {
// Skip when disabled
return;
shahthepro marked this conversation as resolved.
Show resolved Hide resolved
}

tx = oethbVault.connect(nick).claimWithdrawal(oethUnits("1"));
const { nextWithdrawalIndex: requestId } =
await oethbVault.withdrawalQueueMetadata();

await expect(tx).to.be.revertedWith("Async withdrawals disabled");
// Rafael mints 1 superOETHb
await _mint(rafael);

tx = oethbVault.connect(nick).claimWithdrawals([oethUnits("1")]);
// Rafael places an async withdrawal request
await oethbVault.connect(rafael).requestWithdrawal(oethUnits("1"));

await expect(tx).to.be.revertedWith("Async withdrawals disabled");
// ... and tries to claim it after 1d
await advanceTime(delayPeriod);
await oethbVault.connect(rafael).claimWithdrawal(requestId);
});
});

Expand Down
Loading