Skip to content

Commit 3203ec4

Browse files
committed
wip slash invariants
1 parent 38f5faa commit 3203ec4

File tree

6 files changed

+370
-49
lines changed

6 files changed

+370
-49
lines changed

src/test/integration/IntegrationBase.t.sol

Lines changed: 217 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import "src/test/integration/users/User_M1.t.sol";
1818
abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
1919
using StdStyle for *;
2020
using SlashingLib for *;
21+
using Math for uint256;
2122
using Strings for *;
2223
using print for *;
2324

@@ -68,6 +69,35 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
6869
return (staker, strategies, tokenBalances);
6970
}
7071

72+
function _newBasicStaker() internal returns (User, IStrategy[] memory, uint[] memory) {
73+
string memory stakerName;
74+
75+
User staker;
76+
IStrategy[] memory strategies;
77+
uint[] memory tokenBalances;
78+
79+
if (!isUpgraded) {
80+
stakerName = string.concat("M2Staker", cheats.toString(numStakers));
81+
82+
(staker, strategies, tokenBalances) = _randUser(stakerName);
83+
84+
stakersToMigrate.push(staker);
85+
} else {
86+
stakerName = string.concat("staker", cheats.toString(numStakers));
87+
88+
(staker, strategies, tokenBalances) = _randUser(stakerName);
89+
}
90+
91+
assert_HasUnderlyingTokenBalances(staker, strategies, tokenBalances, "_newRandomStaker: failed to award token balances");
92+
93+
numStakers++;
94+
assembly { // TODO HACK
95+
mstore(strategies, 1)
96+
mstore(tokenBalances, 1)
97+
}
98+
return (staker, strategies, tokenBalances);
99+
}
100+
71101
/**
72102
* @dev Create a new operator according to configured random variants.
73103
* This user will immediately deposit their randomized assets into eigenlayer.
@@ -835,6 +865,21 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
835865
}
836866
}
837867

868+
function assert_Snap_Slashed_SlashableStake(
869+
User operator,
870+
OperatorSet memory operatorSet,
871+
SlashingParams memory params,
872+
string memory err
873+
) internal {
874+
uint[] memory curSlashableStake = _getMinSlashableStake(operator, operatorSet, params.strategies);
875+
uint[] memory prevSlashableStake = _getPrevMinSlashableStake(operator, operatorSet, params.strategies);
876+
877+
for (uint i = 0; i < params.strategies.length; i++) {
878+
uint expectedSlashed = prevSlashableStake[i].mulWadRoundUp(params.wadsToSlash[i]);
879+
assertEq(curSlashableStake[i], prevSlashableStake[i] - expectedSlashed, err);
880+
}
881+
}
882+
838883
function assert_Snap_StakeBecameAllocated(
839884
User operator,
840885
OperatorSet memory operatorSet,
@@ -877,6 +922,59 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
877922
}
878923
}
879924

925+
function assert_Snap_Slashed_AllocatedStake(
926+
User operator,
927+
OperatorSet memory operatorSet,
928+
SlashingParams memory params,
929+
string memory err
930+
) internal {
931+
uint[] memory curAllocatedStake = _getAllocatedStake(operator, operatorSet, params.strategies);
932+
uint[] memory prevAllocatedStake = _getPrevAllocatedStake(operator, operatorSet, params.strategies);
933+
934+
Magnitudes[] memory curMagnitudes = _getMagnitudes(operator, params.strategies);
935+
Magnitudes[] memory prevMagnitudes = _getPrevMagnitudes(operator, params.strategies);
936+
937+
for (uint i = 0; i < curAllocatedStake.length; i++) {
938+
// uint expectedSlashed = prevAllocatedStake[i].mulDiv(params.wadsToSlash[i], WAD, Math.Rounding.Up);
939+
uint actualSlashed = prevAllocatedStake[i] - curAllocatedStake[i];
940+
uint expectedSlashed = prevAllocatedStake[i].mulWadRoundUp(params.wadsToSlash[i]);
941+
942+
emit log_named_uint("prev enc mag ", prevMagnitudes[i].encumbered);
943+
emit log_named_uint("prev max mag ", prevMagnitudes[i].max);
944+
945+
emit log_named_uint("cur enc mag ", curMagnitudes[i].encumbered);
946+
emit log_named_uint("cur max mag ", curMagnitudes[i].max);
947+
948+
emit log("--");
949+
950+
emit log_named_uint("prevStake ", prevAllocatedStake[i]);
951+
emit log_named_uint("curStake ", curAllocatedStake[i]);
952+
emit log_named_uint("opShares ", delegationManager.operatorShares(address(operator), params.strategies[0]));
953+
emit log_named_uint("expected slash ", expectedSlashed);
954+
emit log_named_uint("actual slash ", actualSlashed);
955+
emit log_named_string("eq?", expectedSlashed == actualSlashed ? "true" : "false");
956+
957+
emit log("--");
958+
959+
emit log("eq:");
960+
961+
emit log_named_uint("prevStake ", prevAllocatedStake[i]);
962+
emit log_named_uint("expected + cur ", curAllocatedStake[i] + expectedSlashed);
963+
964+
emit log("eq:");
965+
966+
emit log_named_uint("curStake ", curAllocatedStake[i]);
967+
emit log_named_uint("prev - expected", prevAllocatedStake[i] - expectedSlashed);
968+
969+
emit log("--");
970+
971+
uint res = prevAllocatedStake[i] - expectedSlashed;
972+
emit log_named_string("result eq", res == curAllocatedStake[i] ? "true" : "false");
973+
974+
assertEq(curAllocatedStake[i], prevAllocatedStake[i] - expectedSlashed, err);
975+
}
976+
}
977+
880978
function assert_Snap_Added_EncumberedMagnitude(
881979
User operator,
882980
IStrategy[] memory strategies,
@@ -918,6 +1016,20 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
9181016
}
9191017
}
9201018

1019+
function assert_Snap_Slashed_EncumberedMagnitude(
1020+
User operator,
1021+
SlashingParams memory params,
1022+
string memory err
1023+
) internal {
1024+
Magnitudes[] memory curMagnitudes = _getMagnitudes(operator, params.strategies);
1025+
Magnitudes[] memory prevMagnitudes = _getPrevMagnitudes(operator, params.strategies);
1026+
1027+
for (uint i = 0; i < params.strategies.length; i++) {
1028+
uint expectedSlashed = prevMagnitudes[i].encumbered.mulWadRoundUp(params.wadsToSlash[i]);
1029+
assertEq(curMagnitudes[i].encumbered, prevMagnitudes[i].encumbered - expectedSlashed, err);
1030+
}
1031+
}
1032+
9211033
function assert_Snap_Added_AllocatableMagnitude(
9221034
User operator,
9231035
IStrategy[] memory strategies,
@@ -948,14 +1060,14 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
9481060
function assert_Snap_Removed_AllocatableMagnitude(
9491061
User operator,
9501062
IStrategy[] memory strategies,
951-
uint64[] memory magnitudeAllocated,
1063+
uint64[] memory magnitudeRemoved,
9521064
string memory err
9531065
) internal {
9541066
Magnitudes[] memory curMagnitudes = _getMagnitudes(operator, strategies);
9551067
Magnitudes[] memory prevMagnitudes = _getPrevMagnitudes(operator, strategies);
9561068

9571069
for (uint i = 0; i < strategies.length; i++) {
958-
assertEq(curMagnitudes[i].allocatable, prevMagnitudes[i].allocatable - magnitudeAllocated[i], err);
1070+
assertEq(curMagnitudes[i].allocatable, prevMagnitudes[i].allocatable - magnitudeRemoved[i], err);
9591071
}
9601072
}
9611073

@@ -1009,6 +1121,21 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
10091121
}
10101122
}
10111123

1124+
function assert_Snap_Slashed_Allocation(
1125+
User operator,
1126+
OperatorSet memory operatorSet,
1127+
SlashingParams memory params,
1128+
string memory err
1129+
) internal {
1130+
Allocation[] memory curAllocations = _getAllocations(operator, operatorSet, params.strategies);
1131+
Allocation[] memory prevAllocations = _getPrevAllocations(operator, operatorSet, params.strategies);
1132+
1133+
for (uint i = 0; i < params.strategies.length; i++) {
1134+
uint expectedSlashed = prevAllocations[i].currentMagnitude.mulWadRoundUp(params.wadsToSlash[i]);
1135+
assertEq(curAllocations[i].currentMagnitude, prevAllocations[i].currentMagnitude - expectedSlashed, err);
1136+
}
1137+
}
1138+
10121139
function assert_Snap_Unchanged_MaxMagnitude(
10131140
User operator,
10141141
IStrategy[] memory strategies,
@@ -1022,6 +1149,20 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
10221149
}
10231150
}
10241151

1152+
function assert_Snap_Slashed_MaxMagnitude(
1153+
User operator,
1154+
SlashingParams memory params,
1155+
string memory err
1156+
) internal {
1157+
Magnitudes[] memory curMagnitudes = _getMagnitudes(operator, params.strategies);
1158+
Magnitudes[] memory prevMagnitudes = _getPrevMagnitudes(operator, params.strategies);
1159+
1160+
for (uint i = 0; i < params.strategies.length; i++) {
1161+
uint expectedSlashed = prevMagnitudes[i].max.mulWadRoundUp(params.wadsToSlash[i]);
1162+
assertEq(curMagnitudes[i].max, prevMagnitudes[i].max - expectedSlashed, err);
1163+
}
1164+
}
1165+
10251166
function assert_Snap_Allocations_Slashed(
10261167
SlashingParams memory slashingParams,
10271168
OperatorSet memory operatorSet,
@@ -1193,7 +1334,7 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
11931334

11941335
// For each strategy, check (prev - removed == cur)
11951336
for (uint i = 0; i < strategies.length; i++) {
1196-
assertEq(prevShares[i] - removedShares[i], curShares[i], err);
1337+
assertEq(prevShares[i], curShares[i] + removedShares[i], err);
11971338
}
11981339
}
11991340

@@ -1237,6 +1378,21 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
12371378
}
12381379
}
12391380

1381+
function assert_Snap_Slashed_OperatorShares(
1382+
User operator,
1383+
SlashingParams memory params,
1384+
string memory err
1385+
) internal {
1386+
uint[] memory curShares = _getOperatorShares(operator, params.strategies);
1387+
uint[] memory prevShares = _getPrevOperatorShares(operator, params.strategies);
1388+
1389+
for (uint i = 0; i < params.strategies.length; i++) {
1390+
// uint expectedSlashed = prevShares[i].mulDiv(params.wadsToSlash[i], WAD, Math.Rounding.Down);
1391+
uint expectedSlashed = prevShares[i].mulWadRoundUp(params.wadsToSlash[i]);
1392+
assertEq(curShares[i], prevShares[i] - expectedSlashed, err);
1393+
}
1394+
}
1395+
12401396
/*******************************************************************************
12411397
SNAPSHOT ASSERTIONS: STAKER SHARES
12421398
*******************************************************************************/
@@ -1773,12 +1929,34 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
17731929
Magnitudes[] memory magnitudes = _getMagnitudes(operator, strategies);
17741930

17751931
for (uint i = 0; i < params.strategies.length; i++) {
1776-
IStrategy strategy = params.strategies[i];
17771932
uint64 halfAvailable = uint64(magnitudes[i].allocatable) / 2;
17781933
params.newMagnitudes[i] = allocations[i].currentMagnitude + halfAvailable;
17791934
}
17801935
}
17811936

1937+
/// @dev Generate params to allocate a random portion of available magnitude to each strategy
1938+
/// in the operator set. All strategies will have a nonzero allocation, and the minimum allocation
1939+
/// will be 10% of available magnitude
1940+
function _genAllocation_Rand(
1941+
User operator,
1942+
OperatorSet memory operatorSet
1943+
) internal returns (AllocateParams memory params) {
1944+
params.operatorSet = operatorSet;
1945+
params.strategies = allocationManager.getStrategiesInOperatorSet(operatorSet);
1946+
params.newMagnitudes = new uint64[](params.strategies.length);
1947+
1948+
Allocation[] memory allocations = _getAllocations(operator, operatorSet, params.strategies);
1949+
Magnitudes[] memory magnitudes = _getMagnitudes(operator, params.strategies);
1950+
1951+
for (uint i = 0; i < params.strategies.length; i++) {
1952+
// minimum of 10%, maximum of 100%. increments of 10%.
1953+
uint r = _randUint({min: 1, max: 10});
1954+
uint64 allocation = uint64(magnitudes[i].allocatable) / uint64(r);
1955+
1956+
params.newMagnitudes[i] = allocations[i].currentMagnitude + allocation;
1957+
}
1958+
}
1959+
17821960
/// @dev Generates params for a half deallocation from all strategies the operator is allocated to in the operator set
17831961
function _genDeallocation_HalfRemaining(
17841962
User operator,
@@ -1824,12 +2002,46 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
18242002
User operator,
18252003
OperatorSet memory operatorSet,
18262004
IStrategy[] memory strategies
1827-
) internal view returns (AllocateParams memory params) {
2005+
) internal pure returns (AllocateParams memory params) {
18282006
params.operatorSet = operatorSet;
18292007
params.strategies = strategies;
18302008
params.newMagnitudes = new uint64[](params.strategies.length);
18312009
}
18322010

2011+
/// Generate random slashing between 1 and 99%
2012+
function _genSlashing_Rand(
2013+
User operator,
2014+
OperatorSet memory operatorSet
2015+
) internal returns (SlashingParams memory params) {
2016+
params.operator = address(operator);
2017+
params.operatorSetId = operatorSet.id;
2018+
params.description = "genSlashing_Half";
2019+
params.strategies = allocationManager.getStrategiesInOperatorSet(operatorSet).sort();
2020+
params.wadsToSlash = new uint[](params.strategies.length);
2021+
2022+
/// 1% * rand(1, 99)
2023+
uint slashWad = 1e16 * _randUint({min: 1, max: 99});
2024+
2025+
for (uint i = 0; i < params.wadsToSlash.length; i++) {
2026+
params.wadsToSlash[i] = slashWad;
2027+
}
2028+
}
2029+
2030+
function _genSlashing_Half(
2031+
User operator,
2032+
OperatorSet memory operatorSet
2033+
) internal view returns (SlashingParams memory params) {
2034+
params.operator = address(operator);
2035+
params.operatorSetId = operatorSet.id;
2036+
params.description = "genSlashing_Half";
2037+
params.strategies = allocationManager.getStrategiesInOperatorSet(operatorSet).sort();
2038+
params.wadsToSlash = new uint[](params.strategies.length);
2039+
2040+
for (uint i = 0; i < params.wadsToSlash.length; i++) {
2041+
params.wadsToSlash[i] = 1e17;
2042+
}
2043+
}
2044+
18332045
function _randWadToSlash() internal returns (uint) {
18342046
return _randUint({ min: 0.01 ether, max: 1 ether });
18352047
}

0 commit comments

Comments
 (0)