From 1f4bc571a907d1897325ebe7ae269b4a508c0189 Mon Sep 17 00:00:00 2001 From: Samuil Borisov Date: Tue, 17 Dec 2024 15:02:26 +0200 Subject: [PATCH 1/5] add testing --- test/HydraDelegation/VestedDelegation.test.ts | 173 +++++++++++++++++- test/constants.ts | 1 + 2 files changed, 172 insertions(+), 2 deletions(-) diff --git a/test/HydraDelegation/VestedDelegation.test.ts b/test/HydraDelegation/VestedDelegation.test.ts index c2bb831c..94eabf2f 100644 --- a/test/HydraDelegation/VestedDelegation.test.ts +++ b/test/HydraDelegation/VestedDelegation.test.ts @@ -942,7 +942,7 @@ export function RunVestedDelegationTests(): void { ) ) .to.be.revertedWithCustomError(hydraDelegation, "DelegateRequirement") - .withArgs("DelegPoolLib", ERRORS.DelegPoolLib.lateBalanceChange); + .withArgs("_verifyRewardsMatured", ERRORS.vesting.previousRPS); }); it("should revert when get reward with early balance", async function () { @@ -1480,7 +1480,36 @@ export function RunVestedDelegationTests(): void { ) ) .to.be.revertedWithCustomError(hydraDelegation, "DelegateRequirement") - .withArgs("DelegPoolLib", ERRORS.DelegPoolLib.invalidParamsIndex); + .withArgs("_verifyRewardsMatured", ERRORS.vesting.previousRPS); + }); + + it("should revert when the position have future valid RPS and a person is trying to get an old reward", async function () { + const { systemHydraChain, hydraStaking, hydraDelegation, delegatedValidator, vestManager } = await loadFixture( + this.fixtures.vestedDelegationFixture + ); + + await commitEpochs(systemHydraChain, hydraStaking, [delegatedValidator], 5, this.epochSize, WEEK * 2); + + // prepare params for call + const { epochNum, balanceChangeIndex } = await getClaimableRewardRPSData( + systemHydraChain, + hydraDelegation, + delegatedValidator.address, + vestManager.address + ); + + await commitEpochs(systemHydraChain, hydraStaking, [delegatedValidator], 1, this.epochSize); + + await expect( + hydraDelegation.calculatePositionTotalReward( + delegatedValidator.address, + vestManager.address, + epochNum, + balanceChangeIndex + ) + ) + .to.be.revertedWithCustomError(hydraDelegation, "DelegateRequirement") + .withArgs("_verifyRewardsMatured", ERRORS.vesting.previousRPS); }); it("should revert when calculate the total reward with earlier balance change index", async function () { @@ -1570,6 +1599,62 @@ export function RunVestedDelegationTests(): void { expect(positionClaimableReward).to.lt(positionTotalReward); }); + it("should not claim if position is matured but we pass old RPS data", async function () { + const { systemHydraChain, hydraStaking, hydraDelegation, delegatedValidator, vestManager, vestManagerOwner } = + await loadFixture(this.fixtures.weeklyVestedDelegationFixture); + + // prepare params for call + let { epochNum, balanceChangeIndex } = await getClaimableRewardRPSData( + systemHydraChain, + hydraDelegation, + delegatedValidator.address, + vestManager.address + ); + + const positionClaimableReward = await hydraDelegation.calculatePositionClaimableReward( + delegatedValidator.address, + vestManager.address, + epochNum, + balanceChangeIndex + ); + + // prepare the total reward params + ({ epochNum, balanceChangeIndex } = await getTotalRewardRPSData( + systemHydraChain, + hydraDelegation, + delegatedValidator.address, + vestManager.address + )); + + const positionTotalReward = await hydraDelegation.calculatePositionTotalReward( + delegatedValidator.address, + vestManager.address, + epochNum, + balanceChangeIndex + ); + + await commitEpochs(systemHydraChain, hydraStaking, [delegatedValidator], 1, this.epochSize); + + expect(positionTotalReward).to.not.be.equal(positionClaimableReward); + + const position = await hydraDelegation.vestedDelegationPositions( + delegatedValidator.address, + vestManager.address + ); + + // increase so the position is fully + await time.increaseTo(position.end.add(position.duration).add(DAY)); + await commitEpochs(systemHydraChain, hydraStaking, [delegatedValidator], 1, this.epochSize); + + await expect( + vestManager + .connect(vestManagerOwner) + .claimVestedPositionReward(delegatedValidator.address, epochNum, balanceChangeIndex) + ) + .to.be.revertedWithCustomError(hydraDelegation, "DelegateRequirement") + .withArgs("_verifyRewardsMatured", ERRORS.vesting.previousRPS); + }); + it("should successfully calculate the total reward (must be equal to claimable) for matured position, and claim", async function () { const { systemHydraChain, hydraStaking, hydraDelegation, delegatedValidator, vestManager } = await loadFixture( this.fixtures.vestedDelegationFixture @@ -1715,6 +1800,90 @@ export function RunVestedDelegationTests(): void { }); }); + describe("Liquid Debt", async function () { + it("should give negative liquid debt when vesting", async function () { + const { hydraDelegation, vestManager } = await loadFixture(this.fixtures.vestedDelegationFixture); + + const liquidDebt = await hydraDelegation.liquidityDebts(vestManager.address); + + expect(liquidDebt).to.be.lt(0); + }); + + it("Should clear all debt and take all Lydras on cutting the whole position", async function () { + const { systemHydraChain, hydraStaking, hydraDelegation, vestManager, delegatedValidator, vestManagerOwner } = + await loadFixture(this.fixtures.vestedDelegationFixture); + + // commit epochs to distribute rewards + await commitEpochs(systemHydraChain, hydraStaking, [delegatedValidator], 5, this.epochSize, WEEK); + + const liquidDebtBefore = await hydraDelegation.liquidityDebts(vestManager.address); + + await vestManager.connect(vestManagerOwner).cutVestedDelegatePosition(delegatedValidator.address, 100); + + const liquidDebtAfter = await hydraDelegation.liquidityDebts(vestManager.address); + + expect(liquidDebtAfter).to.be.eq(liquidDebtBefore.add(100)); + expect(liquidDebtAfter).to.be.gt(liquidDebtBefore); + expect(liquidDebtAfter).to.be.lt(0); + }); + + it("When cutting a position, the liquid debt should be changed properly (above), and we provide 0 Lydra", async function () { + const { + systemHydraChain, + hydraStaking, + hydraDelegation, + vestManager, + delegatedValidator, + vestManagerOwner, + liquidToken, + } = await loadFixture(this.fixtures.vestedDelegationFixture); + + // commit epochs to distribute rewards + await commitEpochs(systemHydraChain, hydraStaking, [delegatedValidator], 5, this.epochSize, WEEK); + + const liquidDebtBefore = await hydraDelegation.liquidityDebts(vestManager.address); + + await liquidToken.connect(vestManagerOwner).approve(vestManager.address, this.minDelegation.mul(100)); + // cut the entire position without providing any Lydra, because the liquid debt is more than the position for the manager + await vestManager + .connect(vestManagerOwner) + .cutVestedDelegatePosition(delegatedValidator.address, this.minDelegation.mul(2)); + + const liquidDebtAfter = await hydraDelegation.liquidityDebts(vestManager.address); + + expect(await liquidToken.balanceOf(vestManagerOwner.address)).to.be.eq(0); + expect(liquidDebtAfter).to.be.gt(liquidDebtBefore); + expect(liquidDebtAfter).to.be.eq(0); + }); + + it("When opening a big position (more than the liquid debt), another position with same manager will handle liquid debt properly", async function () { + const { systemHydraChain, hydraStaking, hydraDelegation, vestManager, delegatedValidator, vestManagerOwner } = + await loadFixture(this.fixtures.vestedDelegationFixture); + + const liquidDebtBeforeNewPosition = await hydraDelegation.liquidityDebts(vestManager.address); + + await vestManager + .connect(vestManagerOwner) + .openVestedDelegatePosition(this.signers.validators[1].address, 52, { value: this.minDelegation.mul(100) }); + // commit epochs to distribute rewards + await commitEpochs(systemHydraChain, hydraStaking, [delegatedValidator], 5, this.epochSize, WEEK); + + const liquidDebtBeforeCut = await hydraDelegation.liquidityDebts(vestManager.address); + expect(liquidDebtBeforeNewPosition).to.be.gt(liquidDebtBeforeCut); + + // cut the entire position without providing any Lydra, because the liquid debt is more than the position for the manager + await vestManager + .connect(vestManagerOwner) + .cutVestedDelegatePosition(delegatedValidator.address, this.minDelegation.mul(2)); + + const liquidDebtAfter = await hydraDelegation.liquidityDebts(vestManager.address); + + expect(liquidDebtAfter).to.be.eq(liquidDebtBeforeCut.add(this.minDelegation.mul(2))); + expect(liquidDebtAfter).to.be.gt(liquidDebtBeforeCut); + expect(liquidDebtAfter).to.be.lt(0); + }); + }); + describe("penaltyDecreasePerWeek()", async function () { it("should revert setting penalty decrease per week if not governance", async function () { const { hydraDelegation, delegatedValidator } = await loadFixture(this.fixtures.vestedDelegationFixture); diff --git a/test/constants.ts b/test/constants.ts index 26aa52f1..f144e5f4 100644 --- a/test/constants.ts +++ b/test/constants.ts @@ -66,6 +66,7 @@ export const ERRORS = { vesting: { invalidEpoch: "INVALID_EPOCH", wrongRPS: "WRONG_RPS", + previousRPS: "PREVIOUS_RPS", }, DelegPoolLib: { invalidParamsIndex: "INVALID_PARAMS_INDEX", From 16b0e5d635441e49eecd540d37d64ccd6748f586 Mon Sep 17 00:00:00 2001 From: Samuil Borisov Date: Fri, 20 Dec 2024 12:19:49 +0200 Subject: [PATCH 2/5] update comment --- .../modules/VestedDelegation/VestedDelegation.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/HydraDelegation/modules/VestedDelegation/VestedDelegation.sol b/contracts/HydraDelegation/modules/VestedDelegation/VestedDelegation.sol index e45fcdd0..18093efd 100644 --- a/contracts/HydraDelegation/modules/VestedDelegation/VestedDelegation.sol +++ b/contracts/HydraDelegation/modules/VestedDelegation/VestedDelegation.sol @@ -223,7 +223,7 @@ abstract contract VestedDelegation is IVestedDelegation, Vesting, Delegation, Ve // update the old delegation position DelegationPool storage oldDelegation = delegationPools[oldStaker]; uint256 amount = oldDelegation.balanceOf(msg.sender); - // we delete the previous position historical data to avoid any possible issues + // we delete the previous position historical data (for the new validator) to avoid any possible issues delegationPools[newStaker].cleanDelegatorHistoricalData(msg.sender); // undelegate (withdraw & emit event) the old amount from the old position From 64c1ac9d1e534f7089a0f805d56d7b50476a63a8 Mon Sep 17 00:00:00 2001 From: Samuil Borisov Date: Fri, 20 Dec 2024 12:50:58 +0200 Subject: [PATCH 3/5] update modifier --- contracts/common/Vesting/Vesting.sol | 2 +- docs/common/Vesting/Vesting.md | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/contracts/common/Vesting/Vesting.sol b/contracts/common/Vesting/Vesting.sol index dd1da154..9ef2a275 100644 --- a/contracts/common/Vesting/Vesting.sol +++ b/contracts/common/Vesting/Vesting.sol @@ -46,7 +46,7 @@ abstract contract Vesting is IVesting, Governed, APRCalculatorConnector { /** * @inheritdoc IVesting */ - function setPenaltyDecreasePerWeek(uint256 newRate) external onlyRole(DEFAULT_ADMIN_ROLE) { + function setPenaltyDecreasePerWeek(uint256 newRate) external onlyGovernance { if (newRate < 10 || newRate > 150) revert PenaltyRateOutOfRange(); penaltyDecreasePerWeek = newRate; } diff --git a/docs/common/Vesting/Vesting.md b/docs/common/Vesting/Vesting.md index 32a1c456..bd7dd0cc 100644 --- a/docs/common/Vesting/Vesting.md +++ b/docs/common/Vesting/Vesting.md @@ -329,4 +329,20 @@ error PenaltyRateOutOfRange() +### Unauthorized + +```solidity +error Unauthorized(string only) +``` + + + + + +#### Parameters + +| Name | Type | Description | +|---|---|---| +| only | string | undefined | + From 19b651067e6b89425cdf02a0df3cd8d6fdf032c9 Mon Sep 17 00:00:00 2001 From: Samuil Borisov Date: Fri, 20 Dec 2024 15:23:06 +0200 Subject: [PATCH 4/5] fix tests --- test/HydraDelegation/VestedDelegation.test.ts | 8 ++---- test/HydraStaking/VestedStaking.test.ts | 28 +++++++++---------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/test/HydraDelegation/VestedDelegation.test.ts b/test/HydraDelegation/VestedDelegation.test.ts index 94eabf2f..dc7398c0 100644 --- a/test/HydraDelegation/VestedDelegation.test.ts +++ b/test/HydraDelegation/VestedDelegation.test.ts @@ -1888,11 +1888,9 @@ export function RunVestedDelegationTests(): void { it("should revert setting penalty decrease per week if not governance", async function () { const { hydraDelegation, delegatedValidator } = await loadFixture(this.fixtures.vestedDelegationFixture); - const admin = await hydraDelegation.DEFAULT_ADMIN_ROLE(); - - await expect(hydraDelegation.connect(delegatedValidator).setPenaltyDecreasePerWeek(100)).to.be.revertedWith( - ERRORS.accessControl(delegatedValidator.address.toLocaleLowerCase(), admin) - ); + await expect(hydraDelegation.connect(delegatedValidator).setPenaltyDecreasePerWeek(100)) + .to.be.revertedWithCustomError(hydraDelegation, "Unauthorized") + .withArgs(ERRORS.unauthorized.governanceArg); }); it("should revert setting penalty decrease per week if amount of of range", async function () { diff --git a/test/HydraStaking/VestedStaking.test.ts b/test/HydraStaking/VestedStaking.test.ts index 658d8594..dc96b09d 100644 --- a/test/HydraStaking/VestedStaking.test.ts +++ b/test/HydraStaking/VestedStaking.test.ts @@ -521,33 +521,31 @@ export function RunVestedStakingTests(): void { }); describe("penaltyDecreasePerWeek()", async function () { - it("should revert setting penalty decrease per week if not admin", async function () { - const { hydraDelegation, delegatedValidator } = await loadFixture(this.fixtures.vestedDelegationFixture); + it("should revert setting penalty decrease per week if not Governance", async function () { + const { hydraStaking, delegatedValidator } = await loadFixture(this.fixtures.vestedDelegationFixture); - const admin = await hydraDelegation.DEFAULT_ADMIN_ROLE(); - - await expect(hydraDelegation.connect(delegatedValidator).setPenaltyDecreasePerWeek(100)).to.be.revertedWith( - ERRORS.accessControl(delegatedValidator.address.toLocaleLowerCase(), admin) - ); + await expect(hydraStaking.connect(delegatedValidator).setPenaltyDecreasePerWeek(100)) + .to.be.revertedWithCustomError(hydraStaking, "Unauthorized") + .withArgs(ERRORS.unauthorized.governanceArg); }); it("should revert setting penalty decrease per week if amount of of range", async function () { - const { hydraDelegation } = await loadFixture(this.fixtures.vestedDelegationFixture); + const { hydraStaking } = await loadFixture(this.fixtures.vestedDelegationFixture); await expect( - hydraDelegation.connect(this.signers.governance).setPenaltyDecreasePerWeek(9) - ).to.be.revertedWithCustomError(hydraDelegation, "PenaltyRateOutOfRange"); + hydraStaking.connect(this.signers.governance).setPenaltyDecreasePerWeek(9) + ).to.be.revertedWithCustomError(hydraStaking, "PenaltyRateOutOfRange"); await expect( - hydraDelegation.connect(this.signers.governance).setPenaltyDecreasePerWeek(151) - ).to.be.revertedWithCustomError(hydraDelegation, "PenaltyRateOutOfRange"); + hydraStaking.connect(this.signers.governance).setPenaltyDecreasePerWeek(151) + ).to.be.revertedWithCustomError(hydraStaking, "PenaltyRateOutOfRange"); }); it("should set penalty decrease per week", async function () { - const { hydraDelegation } = await loadFixture(this.fixtures.vestedDelegationFixture); + const { hydraStaking } = await loadFixture(this.fixtures.vestedDelegationFixture); - await hydraDelegation.connect(this.signers.governance).setPenaltyDecreasePerWeek(100); - expect(await hydraDelegation.penaltyDecreasePerWeek()).to.be.eq(100); + await hydraStaking.connect(this.signers.governance).setPenaltyDecreasePerWeek(100); + expect(await hydraStaking.penaltyDecreasePerWeek()).to.be.eq(100); }); }); }); From 264044283cd5e165232b7a23097477adce01e903 Mon Sep 17 00:00:00 2001 From: Samuil Borisov Date: Mon, 23 Dec 2024 11:57:25 +0200 Subject: [PATCH 5/5] Polish PR --- contracts/common/Vesting/Vesting.sol | 2 +- docs/common/Vesting/Vesting.md | 16 ------- test/HydraDelegation/VestedDelegation.test.ts | 21 ++++---- test/HydraStaking/VestedStaking.test.ts | 48 +++++++++++++++++-- 4 files changed, 57 insertions(+), 30 deletions(-) diff --git a/contracts/common/Vesting/Vesting.sol b/contracts/common/Vesting/Vesting.sol index 9ef2a275..dd1da154 100644 --- a/contracts/common/Vesting/Vesting.sol +++ b/contracts/common/Vesting/Vesting.sol @@ -46,7 +46,7 @@ abstract contract Vesting is IVesting, Governed, APRCalculatorConnector { /** * @inheritdoc IVesting */ - function setPenaltyDecreasePerWeek(uint256 newRate) external onlyGovernance { + function setPenaltyDecreasePerWeek(uint256 newRate) external onlyRole(DEFAULT_ADMIN_ROLE) { if (newRate < 10 || newRate > 150) revert PenaltyRateOutOfRange(); penaltyDecreasePerWeek = newRate; } diff --git a/docs/common/Vesting/Vesting.md b/docs/common/Vesting/Vesting.md index bd7dd0cc..32a1c456 100644 --- a/docs/common/Vesting/Vesting.md +++ b/docs/common/Vesting/Vesting.md @@ -329,20 +329,4 @@ error PenaltyRateOutOfRange() -### Unauthorized - -```solidity -error Unauthorized(string only) -``` - - - - - -#### Parameters - -| Name | Type | Description | -|---|---|---| -| only | string | undefined | - diff --git a/test/HydraDelegation/VestedDelegation.test.ts b/test/HydraDelegation/VestedDelegation.test.ts index dc7398c0..bedcf399 100644 --- a/test/HydraDelegation/VestedDelegation.test.ts +++ b/test/HydraDelegation/VestedDelegation.test.ts @@ -1642,7 +1642,7 @@ export function RunVestedDelegationTests(): void { vestManager.address ); - // increase so the position is fully + // increase so the position is fully matured await time.increaseTo(position.end.add(position.duration).add(DAY)); await commitEpochs(systemHydraChain, hydraStaking, [delegatedValidator], 1, this.epochSize); @@ -1667,7 +1667,7 @@ export function RunVestedDelegationTests(): void { vestManager.address ); - // increase so the position is fully + // increase so the position is fully matured await time.increaseTo(position.end.add(position.duration).add(DAY)); await commitEpochs(systemHydraChain, hydraStaking, [delegatedValidator], 3, this.epochSize); @@ -1867,9 +1867,11 @@ export function RunVestedDelegationTests(): void { .openVestedDelegatePosition(this.signers.validators[1].address, 52, { value: this.minDelegation.mul(100) }); // commit epochs to distribute rewards await commitEpochs(systemHydraChain, hydraStaking, [delegatedValidator], 5, this.epochSize, WEEK); + const expectedLiquidTokensFromPosition = calcLiquidTokensToDistributeOnVesting(52, this.minDelegation.mul(100)); + const liquidDebtForPosition = this.minDelegation.mul(100).sub(expectedLiquidTokensFromPosition); const liquidDebtBeforeCut = await hydraDelegation.liquidityDebts(vestManager.address); - expect(liquidDebtBeforeNewPosition).to.be.gt(liquidDebtBeforeCut); + expect(liquidDebtBeforeNewPosition).to.be.eq(liquidDebtBeforeCut.add(liquidDebtForPosition)); // cut the entire position without providing any Lydra, because the liquid debt is more than the position for the manager await vestManager @@ -1879,21 +1881,22 @@ export function RunVestedDelegationTests(): void { const liquidDebtAfter = await hydraDelegation.liquidityDebts(vestManager.address); expect(liquidDebtAfter).to.be.eq(liquidDebtBeforeCut.add(this.minDelegation.mul(2))); - expect(liquidDebtAfter).to.be.gt(liquidDebtBeforeCut); expect(liquidDebtAfter).to.be.lt(0); }); }); describe("penaltyDecreasePerWeek()", async function () { - it("should revert setting penalty decrease per week if not governance", async function () { + it("should revert setting penalty decrease per week if not Governance", async function () { const { hydraDelegation, delegatedValidator } = await loadFixture(this.fixtures.vestedDelegationFixture); - await expect(hydraDelegation.connect(delegatedValidator).setPenaltyDecreasePerWeek(100)) - .to.be.revertedWithCustomError(hydraDelegation, "Unauthorized") - .withArgs(ERRORS.unauthorized.governanceArg); + const admin = await hydraDelegation.DEFAULT_ADMIN_ROLE(); + + await expect(hydraDelegation.connect(delegatedValidator).setPenaltyDecreasePerWeek(100)).to.be.revertedWith( + ERRORS.accessControl(delegatedValidator.address.toLocaleLowerCase(), admin) + ); }); - it("should revert setting penalty decrease per week if amount of of range", async function () { + it("should revert setting penalty decrease per week if amount out of range", async function () { const { hydraDelegation } = await loadFixture(this.fixtures.vestedDelegationFixture); await expect( diff --git a/test/HydraStaking/VestedStaking.test.ts b/test/HydraStaking/VestedStaking.test.ts index dc96b09d..eff1c7e3 100644 --- a/test/HydraStaking/VestedStaking.test.ts +++ b/test/HydraStaking/VestedStaking.test.ts @@ -220,6 +220,44 @@ export function RunVestedStakingTests(): void { ); }); + it("Should manage debt and collect tokens properly for vested staking positions", async function () { + const { systemHydraChain, hydraStaking } = await loadFixture(this.fixtures.stakedValidatorsStateFixture); + + const validator = this.signers.validators[0]; + const stakedAmount = await hydraStaking.stakeOf(validator.address); + + const liquidDebtBeforeNewPosition = await hydraStaking.liquidityDebts(validator.address); + expect(liquidDebtBeforeNewPosition).to.be.equal(0); + + await hydraStaking.connect(validator).stakeWithVesting(1, { value: this.minDelegation }); + const expectedLiquidTokensFromPosition = calcLiquidTokensToDistributeOnVesting( + 1, + stakedAmount.add(this.minDelegation) + ); + const liquidDebtForPosition = stakedAmount.add(this.minDelegation).sub(expectedLiquidTokensFromPosition); + expect(await hydraStaking.liquidityDebts(validator.address)).to.be.equal(liquidDebtForPosition.mul(-1)); + + // commit epochs and increase time to mature the position + await commitEpochs(systemHydraChain, hydraStaking, [validator], 3, this.epochSize, WEEK); + + await hydraStaking.connect(validator).stakeWithVesting(52, { value: this.minDelegation.mul(5) }); + const expectedLiquidTokensFromNewPosition = calcLiquidTokensToDistributeOnVesting( + 52, + this.minDelegation.mul(6).add(stakedAmount) + ); + const liquidDebtForNewPosition = this.minDelegation + .mul(6) + .add(stakedAmount) + .sub(expectedLiquidTokensFromNewPosition); + expect(await hydraStaking.liquidityDebts(validator.address)).to.be.equal(liquidDebtForNewPosition.mul(-1)); + + await hydraStaking.connect(validator).unstake(this.minDelegation); + + expect(await hydraStaking.liquidityDebts(validator.address)).to.be.equal( + liquidDebtForNewPosition.sub(this.minDelegation).mul(-1) + ); + }); + it("should get staker penalty and rewards must return 0 (burned), if closing from active position", async function () { const { stakerHydraStaking, systemHydraChain, hydraStaking } = await loadFixture( this.fixtures.newVestingValidatorFixture @@ -524,12 +562,14 @@ export function RunVestedStakingTests(): void { it("should revert setting penalty decrease per week if not Governance", async function () { const { hydraStaking, delegatedValidator } = await loadFixture(this.fixtures.vestedDelegationFixture); - await expect(hydraStaking.connect(delegatedValidator).setPenaltyDecreasePerWeek(100)) - .to.be.revertedWithCustomError(hydraStaking, "Unauthorized") - .withArgs(ERRORS.unauthorized.governanceArg); + const admin = await hydraStaking.DEFAULT_ADMIN_ROLE(); + + await expect(hydraStaking.connect(delegatedValidator).setPenaltyDecreasePerWeek(100)).to.be.revertedWith( + ERRORS.accessControl(delegatedValidator.address.toLocaleLowerCase(), admin) + ); }); - it("should revert setting penalty decrease per week if amount of of range", async function () { + it("should revert setting penalty decrease per week if amount out of range", async function () { const { hydraStaking } = await loadFixture(this.fixtures.vestedDelegationFixture); await expect(