Skip to content
Merged
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
46 changes: 45 additions & 1 deletion contracts/contracts/vault/OETHVaultCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -390,11 +390,55 @@ contract OETHVaultCore is VaultCore {
}
}

// @inheritdoc VaultCore
function _allocate() internal override {
// Add any unallocated WETH to the withdrawal queue first
_addWithdrawalQueueLiquidity();

super._allocate();
uint256 wethAvailableInVault = _wethAvailable();
// Nothing in vault to allocate
if (wethAvailableInVault == 0) return;
uint256 strategiesValue = _totalValueInStrategies();
// We have a method that does the same as this, gas optimisation
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this referring to _totalValue? That's different to wethAvailableInVault + strategiesValue;

uint256 calculatedTotalValue = wethAvailableInVault + strategiesValue;

// We want to maintain a buffer on the Vault so calculate a percentage
// modifier to multiply each amount being allocated by to enforce the
// vault buffer
uint256 vaultBufferModifier;
if (strategiesValue == 0) {
// Nothing in Strategies, allocate 100% minus the vault buffer to
// strategies
vaultBufferModifier = uint256(1e18) - vaultBuffer;
} else {
vaultBufferModifier =
(vaultBuffer * calculatedTotalValue) /
wethAvailableInVault;
if (1e18 > vaultBufferModifier) {
// E.g. 1e18 - (1e17 * 10e18)/5e18 = 8e17
// (5e18 * 8e17) / 1e18 = 4e18 allocated from Vault
vaultBufferModifier = uint256(1e18) - vaultBufferModifier;
} else {
// We need to let the buffer fill
return;
}
}
if (vaultBufferModifier == 0) return;

uint256 allocateAmount = wethAvailableInVault.mulTruncate(
vaultBufferModifier
);

address depositStrategyAddr = assetDefaultStrategies[weth];

if (depositStrategyAddr != address(0) && allocateAmount > 0) {
IStrategy strategy = IStrategy(depositStrategyAddr);
// Transfer asset to Strategy and call deposit method to
// mint or take required action
IERC20(weth).safeTransfer(address(strategy), allocateAmount);
strategy.deposit(weth, allocateAmount);
emit AssetAllocated(weth, depositStrategyAddr, allocateAmount);
}
}

/// @dev The total value of all assets held by the vault and all its strategies
Expand Down
44 changes: 40 additions & 4 deletions contracts/test/vault/oeth-vault.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,20 @@ describe("OETH Vault", function () {

const queueAfter = await oethVault.withdrawalQueueMetadata();
expect(queueAfter.queued).to.equal(
dataBefore.queue.queued.add(delta.queued)
dataBefore.queue.queued.add(delta.queued),
"WithdrawalQueueMetadata.queued mismatch"
);
expect(queueAfter.claimable).to.equal(
dataBefore.queue.claimable.add(delta.claimable)
dataBefore.queue.claimable.add(delta.claimable),
"WithdrawalQueueMetadata.claimable mismatch"
);
expect(queueAfter.claimed).to.equal(
dataBefore.queue.claimed.add(delta.claimed)
dataBefore.queue.claimed.add(delta.claimed),
"WithdrawalQueueMetadata.claimed mismatch"
);
expect(queueAfter.nextWithdrawalIndex).to.equal(
dataBefore.queue.nextWithdrawalIndex.add(delta.nextWithdrawalIndex)
dataBefore.queue.nextWithdrawalIndex.add(delta.nextWithdrawalIndex),
"WithdrawalQueueMetadata.queued nextWithdrawalInded"
);
};

Expand Down Expand Up @@ -912,6 +916,38 @@ describe("OETH Vault", function () {
);
await expect(tx).to.be.revertedWith("Not enough WETH available");
});
it("should not deposit allocated WETH during allocate", async () => {
const { oethVault, governor, weth } = fixture;

// Set mock strategy as default strategy
await oethVault
.connect(governor)
.setAssetDefaultStrategy(weth.address, mockStrategy.address);

// and buffer to 10%
await oethVault.connect(governor).setVaultBuffer(oethUnits("0.1"));

// WETH in strategy = 15 WETH
// WETH in the vault = 60 - 15 = 45 WETH
// Unallocated WETH in the vault = 45 - 23 = 22 WETH

await oethVault.connect(governor).allocate();

expect(await weth.balanceOf(mockStrategy.address)).to.approxEqual(
// 60 - 23 = 37 Unreserved WETH
// 90% of 37 = 33.3 WETH for allocation
oethUnits("33.3"),
"Strategy has the reserved WETH"
);

expect(await weth.balanceOf(oethVault.address)).to.approxEqual(
// 10% of 37 = 3.7 WETH for Vault buffer
// + 23 reserved WETH
oethUnits("23").add(oethUnits("3.7")),
"Vault doesn't have enough WETH"
);
});

it("Should deposit unallocated WETH to a strategy", async () => {
const { oethVault, weth, governor } = fixture;

Expand Down