Skip to content

Commit

Permalink
fix network withdrawals, add cluster & operators tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mtabasco committed Sep 19, 2023
1 parent b8e03e7 commit 22d2859
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 9 deletions.
1 change: 1 addition & 0 deletions contracts/modules/SSVDAO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ contract SSVDAO is ISSVDAO {
}

sp.daoBalance = networkBalance - shrunkAmount;
sp.daoIndexBlockNumber = uint32(block.number);

CoreLib.transferBalance(msg.sender, amount);

Expand Down
48 changes: 39 additions & 9 deletions test/account/withdraw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import { expect } from 'chai';
import { trackGas, GasGroup } from '../helpers/gas-usage';

// Declare globals
let ssvNetworkContract: any, ssvToken: any, cluster1: any, minDepositAmount: any;
let ssvNetworkContract: any, ssvViews: any, ssvToken: any, cluster1: any, minDepositAmount: any;

describe('Withdraw Tests', () => {
beforeEach(async () => {
// Initialize contract
const metadata = (await helpers.initializeContract());
ssvNetworkContract = metadata.contract;
ssvNetworkContract = metadata.contract;
ssvViews = metadata.ssvViews;
ssvToken = metadata.ssvToken;

// Register operators
Expand Down Expand Up @@ -48,19 +50,19 @@ describe('Withdraw Tests', () => {
});

it('Withdraw from operator balance emits "OperatorWithdrawn"', async () => {
await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorEarnings(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'OperatorWithdrawn');
await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'OperatorWithdrawn');
});

it('Withdraw from operator balance gas limits', async () => {
await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorEarnings(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW_OPERATOR_BALANCE]);
await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW_OPERATOR_BALANCE]);
});

it('Withdraw the total operator balance emits "OperatorWithdrawn"', async () => {
await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawAllOperatorEarnings(uint64)'](1)).to.emit(ssvNetworkContract, 'OperatorWithdrawn');
await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawAllOperatorEarnings(1)).to.emit(ssvNetworkContract, 'OperatorWithdrawn');
});

it('Withdraw the total operator balance gas limits', async () => {
await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawAllOperatorEarnings(uint64)'](1), [GasGroup.WITHDRAW_OPERATOR_BALANCE]);
await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawAllOperatorEarnings(1), [GasGroup.WITHDRAW_OPERATOR_BALANCE]);
});

it('Withdraw from a cluster that has a removed operator emits "ClusterWithdrawn"', async () => {
Expand All @@ -72,6 +74,26 @@ describe('Withdraw Tests', () => {
await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, minDepositAmount, cluster1.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance');
});

it('Sequentially withdraw more than the cluster balance reverts "InsufficientBalance"', async () => {
cluster1 = await helpers.deposit(1,
cluster1.owner,
cluster1.operatorIds,
(minDepositAmount * 2).toString(),
cluster1.cluster);

cluster1 = await helpers.withdraw(4,
cluster1.operatorIds,
minDepositAmount,
cluster1.cluster);

cluster1 = await helpers.withdraw(4,
cluster1.operatorIds,
minDepositAmount,
cluster1.cluster);

await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, minDepositAmount, cluster1.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance');
});

it('Withdraw from a liquidatable cluster reverts "InsufficientBalance" (liquidation threshold)', async () => {
await utils.progressBlocks(20);
await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, 4000000000, cluster1.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance');
Expand All @@ -88,20 +110,28 @@ describe('Withdraw Tests', () => {
});

it('Withdraw balance from an operator I do not own reverts "CallerNotOwner"', async () => {
await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorEarnings(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner');
await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).withdrawOperatorEarnings(1, minDepositAmount)).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner');
});

it('Withdraw more than the operator balance reverts "InsufficientBalance"', async () => {
await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorEarnings(uint64,uint256)'](1, minDepositAmount
await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, minDepositAmount
)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance');
});

it('Sequentially withdraw more than the operator balance reverts "InsufficientBalance"', async () => {
await ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee * 3);
await ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee * 3);

await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee * 3
)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance');
});

it('Withdraw the total balance from an operator I do not own reverts "CallerNotOwner"', async () => {
await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawAllOperatorEarnings(uint64)'](12)).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner');
await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).withdrawAllOperatorEarnings(12)).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner');
});

it('Withdraw more than the operator total balance reverts "InsufficientBalance"', async () => {
await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawAllOperatorEarnings(uint64)'](12)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance');
await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawAllOperatorEarnings(12)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance');
});

it('Withdraw from a cluster without validators', async () => {
Expand Down
10 changes: 10 additions & 0 deletions test/dao/network-fee-withdraw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,14 @@ describe('DAO Network Fee Withdraw Tests', () => {
await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawNetworkEarnings(amount
)).to.be.revertedWith('Ownable: caller is not the owner');
});

it('Withdraw network earnings sequentially when not enough balance reverts "InsufficientBalance"', async () => {
const amount = await ssvViews.getNetworkEarnings() / 2;

await ssvNetworkContract.withdrawNetworkEarnings(amount);
await ssvNetworkContract.withdrawNetworkEarnings(amount);

await expect(ssvNetworkContract.withdrawNetworkEarnings(amount
)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance');
});
});

0 comments on commit 22d2859

Please sign in to comment.