Skip to content

Commit

Permalink
Enable async withdrawals on superOETHb
Browse files Browse the repository at this point in the history
  • Loading branch information
shahthepro committed Oct 12, 2024
1 parent a35c437 commit cb1a80a
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 40 deletions.
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 @@ contract FixedRateDripper is Dripper {
* @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

/**
* 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 @@ contract OETHBaseVaultCore is OETHVaultCore {
// @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)
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 @@ contract VaultAdmin is VaultStorage {
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),
"Invalid claim delay period"
);
emit WithdrawalClaimDelayUpdated(withdrawalClaimDelay, _delay);
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;
}

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

0 comments on commit cb1a80a

Please sign in to comment.