From 83840a276120b9116dd0a3edf70a0d3be7997515 Mon Sep 17 00:00:00 2001 From: Yash Patil Date: Tue, 15 Oct 2024 13:28:31 -0700 Subject: [PATCH 1/5] test: base regression --- src/test/unit/AllocationManagerUnit.t.sol | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/unit/AllocationManagerUnit.t.sol b/src/test/unit/AllocationManagerUnit.t.sol index 473a02a3c..b757810d4 100644 --- a/src/test/unit/AllocationManagerUnit.t.sol +++ b/src/test/unit/AllocationManagerUnit.t.sol @@ -1759,6 +1759,13 @@ contract AllocationManagerUnitTests_ModifyAllocations is AllocationManagerUnitTe "encumberedMagnitude should be updated" ); } + + /** + * Allocate + */ + function test_regression_allocate_deallocate_allocate() public { + + } } contract AllocationManagerUnitTests_ClearModificationQueue is AllocationManagerUnitTests { From 8ce77e3e625866e151e014c0c8bc37b0fb372ab5 Mon Sep 17 00:00:00 2001 From: Yash Patil Date: Tue, 15 Oct 2024 14:08:53 -0700 Subject: [PATCH 2/5] test: regression --- src/contracts/core/AllocationManager.sol | 1 + src/test/unit/AllocationManagerUnit.t.sol | 49 ++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/contracts/core/AllocationManager.sol b/src/contracts/core/AllocationManager.sol index 311f4fe9b..72fc00be1 100644 --- a/src/contracts/core/AllocationManager.sol +++ b/src/contracts/core/AllocationManager.sol @@ -8,6 +8,7 @@ import "@openzeppelin-upgrades/contracts/security/ReentrancyGuardUpgradeable.sol import "../permissions/Pausable.sol"; import "../libraries/SlashingLib.sol"; import "./AllocationManagerStorage.sol"; +import "forge-std/console.sol"; contract AllocationManager is Initializable, diff --git a/src/test/unit/AllocationManagerUnit.t.sol b/src/test/unit/AllocationManagerUnit.t.sol index b757810d4..b65ba37e0 100644 --- a/src/test/unit/AllocationManagerUnit.t.sol +++ b/src/test/unit/AllocationManagerUnit.t.sol @@ -1761,10 +1761,57 @@ contract AllocationManagerUnitTests_ModifyAllocations is AllocationManagerUnitTe } /** - * Allocate + * Allocates, deallocates, and then allocates again */ function test_regression_allocate_deallocate_allocate() public { + uint32 allocationDelay = 15 days; + // Set allocation delay to be 15 days + cheats.prank(defaultOperator); + allocationManager.setAllocationDelay(allocationDelay); + cheats.warp(block.timestamp + ALLOCATION_CONFIGURATION_DELAY); + (,uint32 storedDelay) = allocationManager.getAllocationDelay(defaultOperator); + assertEq(allocationDelay, storedDelay, "allocation delay not valid"); + + // Allocate half of mag to opset1 + IAllocationManagerTypes.MagnitudeAllocation[] memory firstAllocation = + _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 1, 5e17, 1e18); + cheats.prank(defaultOperator); + allocationManager.modifyAllocations(firstAllocation); + cheats.warp(block.timestamp + 15 days); + + // Deallocate half from opset1. + uint32 t = uint32(block.timestamp); + uint32 deallocationEffectTimestamp = uint32(block.timestamp + DEALLOCATION_DELAY); + IAllocationManagerTypes.MagnitudeAllocation[] memory firstDeallocation = + _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 1, 25e16, 1e18); + cheats.prank(defaultOperator); + allocationManager.modifyAllocations(firstDeallocation); + MagnitudeInfo[] memory mInfos = allocationManager.getAllocationInfo(defaultOperator, strategyMock, firstDeallocation[0].operatorSets); + assertEq(deallocationEffectTimestamp, mInfos[0].effectTimestamp, "effect timestamp not correct"); + // Allocate 33e16 mag to opset2 + uint32 allocationEffectTimestamp = uint32(block.timestamp + allocationDelay); + IAllocationManagerTypes.MagnitudeAllocation[] memory secondAllocation = + _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 2, 33e16, 1e18); + cheats.prank(defaultOperator); + allocationManager.modifyAllocations(secondAllocation); + mInfos = allocationManager.getAllocationInfo(defaultOperator, strategyMock, secondAllocation[0].operatorSets); + assertEq(allocationEffectTimestamp, mInfos[0].effectTimestamp, "effect timestamp not correct"); + assertLt(allocationEffectTimestamp, deallocationEffectTimestamp, "invalid test setup"); + + // Warp to allocation effect timestamp & clear the queue + cheats.warp(allocationEffectTimestamp); + allocationManager.clearModificationQueue(defaultOperator, _strategyMockArray(), _maxNumToClear()); + + // Validate `getAllocatableMagnitude`. Allocatable magnitude should be the difference between the total magnitude and the encumbered magnitude + uint64 allocatableMagnitude = allocationManager.getAllocatableMagnitude(defaultOperator, strategyMock); + assertEq(WAD - 33e16 - 5e17, allocatableMagnitude, "allocatableMagnitude not correct"); + + // Validate that we can allocate again for opset2 + IAllocationManagerTypes.MagnitudeAllocation[] memory thirdAllocation = + _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 2, 10e16, 1e18); + cheats.prank(defaultOperator); + allocationManager.modifyAllocations(thirdAllocation); } } From 04e46baad735523d724877c8922af174858a7221 Mon Sep 17 00:00:00 2001 From: Yash Patil Date: Tue, 15 Oct 2024 14:10:05 -0700 Subject: [PATCH 3/5] fix: remove console --- src/contracts/core/AllocationManager.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/src/contracts/core/AllocationManager.sol b/src/contracts/core/AllocationManager.sol index 72fc00be1..311f4fe9b 100644 --- a/src/contracts/core/AllocationManager.sol +++ b/src/contracts/core/AllocationManager.sol @@ -8,7 +8,6 @@ import "@openzeppelin-upgrades/contracts/security/ReentrancyGuardUpgradeable.sol import "../permissions/Pausable.sol"; import "../libraries/SlashingLib.sol"; import "./AllocationManagerStorage.sol"; -import "forge-std/console.sol"; contract AllocationManager is Initializable, From d2d969a4484a468cbd612575d41838242daa56fd Mon Sep 17 00:00:00 2001 From: Yash Patil Date: Tue, 15 Oct 2024 15:30:49 -0700 Subject: [PATCH 4/5] test: logs --- src/test/unit/AllocationManagerUnit.t.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/unit/AllocationManagerUnit.t.sol b/src/test/unit/AllocationManagerUnit.t.sol index b65ba37e0..37c71cb2a 100644 --- a/src/test/unit/AllocationManagerUnit.t.sol +++ b/src/test/unit/AllocationManagerUnit.t.sol @@ -1796,6 +1796,8 @@ contract AllocationManagerUnitTests_ModifyAllocations is AllocationManagerUnitTe cheats.prank(defaultOperator); allocationManager.modifyAllocations(secondAllocation); mInfos = allocationManager.getAllocationInfo(defaultOperator, strategyMock, secondAllocation[0].operatorSets); + console.log("deallocation effect timestamp: ", deallocationEffectTimestamp); + console.log("allocation effect timestamp: ", allocationEffectTimestamp); assertEq(allocationEffectTimestamp, mInfos[0].effectTimestamp, "effect timestamp not correct"); assertLt(allocationEffectTimestamp, deallocationEffectTimestamp, "invalid test setup"); @@ -1807,7 +1809,7 @@ contract AllocationManagerUnitTests_ModifyAllocations is AllocationManagerUnitTe uint64 allocatableMagnitude = allocationManager.getAllocatableMagnitude(defaultOperator, strategyMock); assertEq(WAD - 33e16 - 5e17, allocatableMagnitude, "allocatableMagnitude not correct"); - // Validate that we can allocate again for opset2 + // Validate that we can allocate again for opset2. This should revert? IAllocationManagerTypes.MagnitudeAllocation[] memory thirdAllocation = _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 2, 10e16, 1e18); cheats.prank(defaultOperator); From c8b74b4b0154fac59ae7f545599569b61b1263e3 Mon Sep 17 00:00:00 2001 From: Yash Patil Date: Tue, 15 Oct 2024 16:23:36 -0700 Subject: [PATCH 5/5] test: add actual regression --- src/test/unit/AllocationManagerUnit.t.sol | 171 ++++++++++++++-------- 1 file changed, 114 insertions(+), 57 deletions(-) diff --git a/src/test/unit/AllocationManagerUnit.t.sol b/src/test/unit/AllocationManagerUnit.t.sol index 37c71cb2a..9fb74a17c 100644 --- a/src/test/unit/AllocationManagerUnit.t.sol +++ b/src/test/unit/AllocationManagerUnit.t.sol @@ -1569,7 +1569,7 @@ contract AllocationManagerUnitTests_ModifyAllocations is AllocationManagerUnitTe * Allocates to `firstMod` magnitude and then deallocate to `secondMod` magnitude * Validates the storage * - 1. After deallocation is alled - * - 2. After the deallocationd elay is hit + * - 2. After the deallocationd delay is hit * - 3. After the modification queue is cleared */ function testFuzz_allocate_deallocate(uint256 r) public { @@ -1759,62 +1759,6 @@ contract AllocationManagerUnitTests_ModifyAllocations is AllocationManagerUnitTe "encumberedMagnitude should be updated" ); } - - /** - * Allocates, deallocates, and then allocates again - */ - function test_regression_allocate_deallocate_allocate() public { - uint32 allocationDelay = 15 days; - // Set allocation delay to be 15 days - cheats.prank(defaultOperator); - allocationManager.setAllocationDelay(allocationDelay); - cheats.warp(block.timestamp + ALLOCATION_CONFIGURATION_DELAY); - (,uint32 storedDelay) = allocationManager.getAllocationDelay(defaultOperator); - assertEq(allocationDelay, storedDelay, "allocation delay not valid"); - - // Allocate half of mag to opset1 - IAllocationManagerTypes.MagnitudeAllocation[] memory firstAllocation = - _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 1, 5e17, 1e18); - cheats.prank(defaultOperator); - allocationManager.modifyAllocations(firstAllocation); - cheats.warp(block.timestamp + 15 days); - - // Deallocate half from opset1. - uint32 t = uint32(block.timestamp); - uint32 deallocationEffectTimestamp = uint32(block.timestamp + DEALLOCATION_DELAY); - IAllocationManagerTypes.MagnitudeAllocation[] memory firstDeallocation = - _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 1, 25e16, 1e18); - cheats.prank(defaultOperator); - allocationManager.modifyAllocations(firstDeallocation); - MagnitudeInfo[] memory mInfos = allocationManager.getAllocationInfo(defaultOperator, strategyMock, firstDeallocation[0].operatorSets); - assertEq(deallocationEffectTimestamp, mInfos[0].effectTimestamp, "effect timestamp not correct"); - - // Allocate 33e16 mag to opset2 - uint32 allocationEffectTimestamp = uint32(block.timestamp + allocationDelay); - IAllocationManagerTypes.MagnitudeAllocation[] memory secondAllocation = - _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 2, 33e16, 1e18); - cheats.prank(defaultOperator); - allocationManager.modifyAllocations(secondAllocation); - mInfos = allocationManager.getAllocationInfo(defaultOperator, strategyMock, secondAllocation[0].operatorSets); - console.log("deallocation effect timestamp: ", deallocationEffectTimestamp); - console.log("allocation effect timestamp: ", allocationEffectTimestamp); - assertEq(allocationEffectTimestamp, mInfos[0].effectTimestamp, "effect timestamp not correct"); - assertLt(allocationEffectTimestamp, deallocationEffectTimestamp, "invalid test setup"); - - // Warp to allocation effect timestamp & clear the queue - cheats.warp(allocationEffectTimestamp); - allocationManager.clearModificationQueue(defaultOperator, _strategyMockArray(), _maxNumToClear()); - - // Validate `getAllocatableMagnitude`. Allocatable magnitude should be the difference between the total magnitude and the encumbered magnitude - uint64 allocatableMagnitude = allocationManager.getAllocatableMagnitude(defaultOperator, strategyMock); - assertEq(WAD - 33e16 - 5e17, allocatableMagnitude, "allocatableMagnitude not correct"); - - // Validate that we can allocate again for opset2. This should revert? - IAllocationManagerTypes.MagnitudeAllocation[] memory thirdAllocation = - _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 2, 10e16, 1e18); - cheats.prank(defaultOperator); - allocationManager.modifyAllocations(thirdAllocation); - } } contract AllocationManagerUnitTests_ClearModificationQueue is AllocationManagerUnitTests { @@ -1931,6 +1875,119 @@ contract AllocationManagerUnitTests_ClearModificationQueue is AllocationManagerU assertEq(0, mInfos[0].pendingDiff, "pendingMagnitude should be 0"); assertEq(0, mInfos[0].effectTimestamp, "effectTimestamp should be 0"); } + + /** + * Allocates, deallocates, and then allocates again. Asserts that + * - The deallocation does not block state updates from the second allocation, even though the allocation has an earlier + * effect timestamp, but is on the queue before + */ + function test_allocate_deallocate_allocate() public { + uint32 allocationDelay = 15 days; + // Set allocation delay to be 15 days + cheats.prank(defaultOperator); + allocationManager.setAllocationDelay(allocationDelay); + cheats.warp(block.timestamp + ALLOCATION_CONFIGURATION_DELAY); + (,uint32 storedDelay) = allocationManager.getAllocationDelay(defaultOperator); + assertEq(allocationDelay, storedDelay, "allocation delay not valid"); + + // Allocate half of mag to opset1 + IAllocationManagerTypes.MagnitudeAllocation[] memory firstAllocation = + _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 1, 5e17, 1e18); + cheats.prank(defaultOperator); + allocationManager.modifyAllocations(firstAllocation); + cheats.warp(block.timestamp + 15 days); + + // Deallocate half from opset1. + uint32 t = uint32(block.timestamp); + uint32 deallocationEffectTimestamp = uint32(block.timestamp + DEALLOCATION_DELAY); + IAllocationManagerTypes.MagnitudeAllocation[] memory firstDeallocation = + _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 1, 25e16, 1e18); + cheats.prank(defaultOperator); + allocationManager.modifyAllocations(firstDeallocation); + MagnitudeInfo[] memory mInfos = allocationManager.getAllocationInfo(defaultOperator, strategyMock, firstDeallocation[0].operatorSets); + assertEq(deallocationEffectTimestamp, mInfos[0].effectTimestamp, "effect timestamp not correct"); + + // Allocate 33e16 mag to opset2 + uint32 allocationEffectTimestamp = uint32(block.timestamp + allocationDelay); + IAllocationManagerTypes.MagnitudeAllocation[] memory secondAllocation = + _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 2, 33e16, 1e18); + cheats.prank(defaultOperator); + allocationManager.modifyAllocations(secondAllocation); + mInfos = allocationManager.getAllocationInfo(defaultOperator, strategyMock, secondAllocation[0].operatorSets); + console.log("deallocation effect timestamp: ", deallocationEffectTimestamp); + console.log("allocation effect timestamp: ", allocationEffectTimestamp); + assertEq(allocationEffectTimestamp, mInfos[0].effectTimestamp, "effect timestamp not correct"); + assertLt(allocationEffectTimestamp, deallocationEffectTimestamp, "invalid test setup"); + + // Warp to allocation effect timestamp & clear the queue + cheats.warp(allocationEffectTimestamp); + allocationManager.clearModificationQueue(defaultOperator, _strategyMockArray(), _maxNumToClear()); + + // Validate `getAllocatableMagnitude`. Allocatable magnitude should be the difference between the total magnitude and the encumbered magnitude + uint64 allocatableMagnitude = allocationManager.getAllocatableMagnitude(defaultOperator, strategyMock); + assertEq(WAD - 33e16 - 5e17, allocatableMagnitude, "allocatableMagnitude not correct"); + + // Validate that we can allocate again for opset2. This should not revert + IAllocationManagerTypes.MagnitudeAllocation[] memory thirdAllocation = + _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 2, 10e16, 1e18); + cheats.prank(defaultOperator); + allocationManager.modifyAllocations(thirdAllocation); + } + + /** + * Allocates to opset1, allocates to opset2, deallocates from opset1. Asserts that the allocation, which has a higher + * effect timestamp is not blocking the deallocation. + * The queue looks like (note that the first allocation has been completed): + * 1. (allocation, opSet2, mag: 5e17, effectTimestamp: 50th day) + * 2. (deallocation, opSet1, mag: 0, effectTimestamp: 42.5 day) + */ + function test_regression_allocationBlocksDeallocation() public { + uint32 allocationDelay = 25 days; + // Set allocation delay to be 25 days, greater than the deallocation timestamp + cheats.prank(defaultOperator); + allocationManager.setAllocationDelay(allocationDelay); + cheats.warp(block.timestamp + ALLOCATION_CONFIGURATION_DELAY); + (,uint32 storedDelay) = allocationManager.getAllocationDelay(defaultOperator); + assertEq(allocationDelay, storedDelay, "allocation delay not valid"); + + // Allocate half of mag to opset1 + IAllocationManagerTypes.MagnitudeAllocation[] memory firstAllocation = + _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 1, 5e17, 1e18); + cheats.prank(defaultOperator); + allocationManager.modifyAllocations(firstAllocation); + cheats.warp(block.timestamp + 25 days); + + // Allocate half of mag to opset2 + IAllocationManagerTypes.MagnitudeAllocation[] memory secondAllocation = + _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 2, 5e17, 1e18); + cheats.prank(defaultOperator); + allocationManager.modifyAllocations(secondAllocation); + + uint32 allocationEffectTimestamp = uint32(block.timestamp + allocationDelay); + MagnitudeInfo[] memory mInfos = allocationManager.getAllocationInfo(defaultOperator, strategyMock, secondAllocation[0].operatorSets); + assertEq(allocationEffectTimestamp, mInfos[0].effectTimestamp, "effect timestamp not correct"); + + // Deallocate all from opSet1 + uint32 deallocationEffectTimestamp = uint32(block.timestamp + DEALLOCATION_DELAY); + IAllocationManagerTypes.MagnitudeAllocation[] memory firstDeallocation = + _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 1, 0, 1e18); + cheats.prank(defaultOperator); + allocationManager.modifyAllocations(firstDeallocation); + mInfos = allocationManager.getAllocationInfo(defaultOperator, strategyMock, firstDeallocation[0].operatorSets); + assertEq(deallocationEffectTimestamp, mInfos[0].effectTimestamp, "effect timestamp not correct"); + assertLt(deallocationEffectTimestamp, allocationEffectTimestamp, "invalid test setup"); + + // Warp to deallocation effect timestamp & clear the queue + cheats.warp(deallocationEffectTimestamp); + allocationManager.clearModificationQueue(defaultOperator, _strategyMockArray(), _maxNumToClear()); + + // At this point, we should be able to allocate again to opSet1 AND have only 5e17 encumbered magnitude + assertEq(5e17, allocationManager.encumberedMagnitude(defaultOperator, strategyMock), "encumbered magnitude not correct"); + IAllocationManagerTypes.MagnitudeAllocation[] memory thirdAllocation = + _generateMagnitudeAllocationCalldataForOpSet(defaultAVS, 1, 5e17, 1e18); + cheats.prank(defaultOperator); + allocationManager.modifyAllocations(thirdAllocation); + } } contract AllocationManagerUnitTests_SetAllocationDelay is AllocationManagerUnitTests {