Skip to content

Commit

Permalink
test(wip): slashing integration
Browse files Browse the repository at this point in the history
  • Loading branch information
0xClandestine committed Nov 15, 2024
1 parent 0e763c3 commit 2f5b4b6
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 101 deletions.
19 changes: 13 additions & 6 deletions src/test/integration/IntegrationBase.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ abstract contract IntegrationBase is IntegrationDeployer {
uint[] memory tokenBalances;

if (forkType == MAINNET && !isUpgraded) {
stakerName = string.concat("M1_Staker", numStakers.toString());
stakerName = string.concat("M1_Staker_", numStakers.toString());

(staker, strategies, tokenBalances) = _randUser(stakerName);

stakersToMigrate.push(staker);
} else {
stakerName = string.concat("Staker", numStakers.toString());
stakerName = string.concat("Staker_", numStakers.toString());

(staker, strategies, tokenBalances) = _randUser(stakerName);
}
Expand All @@ -75,7 +75,7 @@ abstract contract IntegrationBase is IntegrationDeployer {
uint[] memory tokenBalances;

if (forkType == MAINNET && !isUpgraded) {
string memory operatorName = string.concat("M1_Operator", numOperators.toString());
string memory operatorName = string.concat("M1_Operator_", numOperators.toString());

// Create an operator for M1. We omit native ETH because we want to
// check staker/operator shares, and we don't award native ETH shares in M1
Expand All @@ -88,7 +88,7 @@ abstract contract IntegrationBase is IntegrationDeployer {

operatorsToMigrate.push(operator);
} else {
string memory operatorName = string.concat("Operator", numOperators.toString());
string memory operatorName = string.concat("Operator_", numOperators.toString());

(operator, strategies, tokenBalances) = _randUser_NoETH(operatorName);

Expand All @@ -107,12 +107,16 @@ abstract contract IntegrationBase is IntegrationDeployer {
}

function _newRandomAVS(IStrategy[] memory strategies) internal returns (AVS avs, uint32 operatorSetId) {
string memory avsName = string.concat("M1_Operator", numOperators.toString());
string memory avsName = string.concat("M1_Operator_", numOperators.toString());
avs = _genRandAVS(avsName);
operatorSetId = avs.createOperatorSet(allStrats);
operatorSetId = avs.createOperatorSet(strategies);
++numAVSs;
}

function _newRandomAVS() internal returns (AVS avs, uint32 operatorSetId) {
return _newRandomAVS(allStrats);
}

/// @dev Send a random amount of ETH (up to 10 gwei) to the destination via `call`,
/// triggering its fallback function. Sends a gwei-divisible amount as well as a
/// non-gwei-divisible amount.
Expand Down Expand Up @@ -1065,6 +1069,7 @@ abstract contract IntegrationBase is IntegrationDeployer {
timeMachine.warpToPresent(curState);
}

// TODO:
/// @dev Given a list of strategies, roll the block number forward to the
/// a valid blocknumber to completeWithdrawals
function _rollBlocksForCompleteWithdrawals(IStrategy[] memory strategies) internal {
Expand All @@ -1076,6 +1081,8 @@ abstract contract IntegrationBase is IntegrationDeployer {
// }
// }
// cheats.roll(block.number + delegationManager.getWithdrawalDelay(strategies));

cheats.roll(block.number + delegationManager.MIN_WITHDRAWAL_DELAY_BLOCKS());
}

/// @dev Uses timewarp modifier to get operator shares at the last snapshot
Expand Down
51 changes: 23 additions & 28 deletions src/test/integration/IntegrationDeployer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,14 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
_hash(cheats.envOr(string("FOUNDRY_PROFILE"), string("default")));

if (forkMainnet) {
emit log("setUp: running tests against mainnet fork");
emit log_named_string("- using RPC url", cheats.rpcUrl("mainnet"));
emit log_named_uint("- forking at block", mainnetForkBlock);
console.log("setUp: running tests against mainnet fork");
console.log("- using RPC url", cheats.rpcUrl("mainnet"));
console.log("- forking at block", mainnetForkBlock);

cheats.createSelectFork(cheats.rpcUrl("mainnet"), mainnetForkBlock);
forkType = MAINNET;
} else {
emit log("setUp: running tests locally");
console.log("setUp: running tests locally");

forkType = LOCAL;
}
Expand Down Expand Up @@ -594,21 +594,21 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
) internal {
// Using uint24 for the seed type so that if a test fails, it's easier
// to manually use the seed to replay the same test.
emit log_named_uint("_configRand: set random seed to: ", _randomSeed);
console.log("_configRand: set random seed to: ", _randomSeed);
random = keccak256(abi.encodePacked(_randomSeed));

// Convert flag bitmaps to bytes of set bits for easy use with _randUint
assetTypes = _bitmapToBytes(_assetTypes);
userTypes = _bitmapToBytes(_userTypes);

emit log("_configRand: Users will be initialized with these asset types:");
console.log("_configRand: Users will be initialized with these asset types:");
for (uint i = 0; i < assetTypes.length; i++) {
emit log(assetTypeToStr[uint(uint8(assetTypes[i]))]);
console.log(assetTypeToStr[uint(uint8(assetTypes[i]))]);
}

emit log("_configRand: these User contracts will be initialized:");
console.log("_configRand: these User contracts will be initialized:");
for (uint i = 0; i < userTypes.length; i++) {
emit log(userTypeToStr[uint(uint8(userTypes[i]))]);
console.log(userTypeToStr[uint(uint8(userTypes[i]))]);
}

assertTrue(assetTypes.length != 0, "_configRand: no asset types selected");
Expand All @@ -622,7 +622,7 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
* Note: for non-LOCAL forktypes, upgrade of contracts will be peformed after user initialization.
*/
function _deployOrFetchContracts() internal {
emit log_named_string("_deployOrFetchContracts using fork for test", forkTypeToStr[forkType]);
console.log("_deployOrFetchContracts using fork for test", forkTypeToStr[forkType]);

if (forkType == LOCAL) {
_setUpLocal();
Expand Down Expand Up @@ -749,7 +749,7 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
_printUserInfo(name, assetType, userType, strategies, tokenBalances);
return (user, strategies, tokenBalances);
}

function _genRandUser(string memory name, uint userType) internal returns (User user) {
// Create User contract based on userType:
if (forkType == LOCAL) {
Expand Down Expand Up @@ -954,7 +954,7 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
// Mask for i-th bit
uint mask = uint(1 << i);

// emit log_named_uint("mask: ", mask);
// console.log("mask: ", mask);

// If the i-th bit is flipped, add a byte to the return array
if (bitmap & mask != 0) {
Expand All @@ -971,30 +971,25 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
IStrategy[] memory strategies,
uint[] memory tokenBalances
) internal {

emit log("===Created User===");
emit log_named_string("Name", name);
emit log_named_string("assetType", assetTypeToStr[assetType]);
emit log_named_string("userType", userTypeToStr[userType]);
emit log_named_string("forkType", forkTypeToStr[forkType]);

emit log_named_uint("num assets: ", strategies.length);

console.log("====== Created User %s ======", StdStyle.bold(StdStyle.yellow(name)));
console.log("Asset Type:", assetTypeToStr[assetType]);
console.log("User Type:", userTypeToStr[userType]);
console.log("Fork Type:", forkTypeToStr[forkType]);
console.log("Total Assets:", strategies.length);

for (uint i = 0; i < strategies.length; i++) {
IStrategy strat = strategies[i];

if (strat == BEACONCHAIN_ETH_STRAT) {
emit log_named_string("token name: ", "Native ETH");
emit log_named_uint("token balance: ", tokenBalances[i]);
console.log("Asset:", "Native ETH");
console.log("Balance:", tokenBalances[i]);
} else {
IERC20 underlyingToken = strat.underlyingToken();

emit log_named_string("token name: ", IERC20Metadata(address(underlyingToken)).name());
emit log_named_uint("token balance: ", tokenBalances[i]);
console.log("Asset:", IERC20Metadata(address(underlyingToken)).name());
console.log("Balance: ", tokenBalances[i]);
}
}

emit log("==================");
console.log("=====================================\n");
}

/// @dev Helper because solidity syntax is exhausting
Expand Down
132 changes: 65 additions & 67 deletions src/test/integration/tests/Delegate_Deposit_Queue_Complete.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,84 +5,82 @@ import "src/test/integration/IntegrationChecks.t.sol";
import "src/test/integration/users/User.t.sol";

contract Integration_Delegate_Deposit_Queue_Complete is IntegrationCheckUtils {
function testFuzz_delegate_deposit_queue_completeAsShares(uint24 _random) public {
// Configure the random parameters for the test
_configRand({
_randomSeed: _random,
_assetTypes: HOLDS_LST | HOLDS_ETH | HOLDS_ALL,
_userTypes: DEFAULT | ALT_METHODS
});
// Create a staker and an operator with a nonzero balance and corresponding strategies
(User staker, IStrategy[] memory strategies, uint[] memory tokenBalances) = _newRandomStaker();
(User operator, ,) = _newRandomOperator();
// Upgrade contracts if forkType is not local
_upgradeEigenLayerContracts();

// TODO: fix test
// function testFuzz_delegate_deposit_queue_completeAsShares(uint24 _random) public {
// // Configure the random parameters for the test
// _configRand({
// _randomSeed: _random,
// _assetTypes: HOLDS_LST | HOLDS_ETH | HOLDS_ALL,
// _userTypes: DEFAULT | ALT_METHODS
// });
// // Create a staker and an operator with a nonzero balance and corresponding strategies
// (User staker, IStrategy[] memory strategies, uint[] memory tokenBalances) = _newRandomStaker();
// (User operator, ,) = _newRandomOperator();
// // Upgrade contracts if forkType is not local
// _upgradeEigenLayerContracts();

// // 1. Delegate to operator
// staker.delegateTo(operator);
// check_Delegation_State(staker, operator, strategies, new uint256[](strategies.length)); // Initial shares are zero
// 1. Delegate to operator
staker.delegateTo(operator);
check_Delegation_State(staker, operator, strategies, new uint256[](strategies.length)); // Initial shares are zero

// // 2. Deposit into strategy
// staker.depositIntoEigenlayer(strategies, tokenBalances);
// uint[] memory shares = _calculateExpectedShares(strategies, tokenBalances);
// 2. Deposit into strategy
staker.depositIntoEigenlayer(strategies, tokenBalances);
uint[] memory shares = _calculateExpectedShares(strategies, tokenBalances);

// // Check that the deposit increased operator shares the staker is delegated to
// check_Deposit_State(staker, strategies, shares);
// assert_Snap_Added_OperatorShares(operator, strategies, shares, "operator should have received shares");
// Check that the deposit increased operator shares the staker is delegated to
check_Deposit_State(staker, strategies, shares);
assert_Snap_Added_OperatorShares(operator, strategies, shares, "operator should have received shares");

// // 3. Queue Withdrawal
// IDelegationManagerTypes.Withdrawal[] memory withdrawals = staker.queueWithdrawals(strategies, shares);
// bytes32[] memory withdrawalRoots = _getWithdrawalHashes(withdrawals);
// check_QueuedWithdrawal_State(staker, operator, strategies, shares, withdrawals, withdrawalRoots);
// 3. Queue Withdrawal
IDelegationManagerTypes.Withdrawal[] memory withdrawals = staker.queueWithdrawals(strategies, shares);
bytes32[] memory withdrawalRoots = _getWithdrawalHashes(withdrawals);
check_QueuedWithdrawal_State(staker, operator, strategies, shares, withdrawals, withdrawalRoots);

// // 4. Complete Queued Withdrawal
// _rollBlocksForCompleteWithdrawals(strategies);
// for (uint i = 0; i < withdrawals.length; i++) {
// staker.completeWithdrawalAsShares(withdrawals[i]);
// check_Withdrawal_AsShares_State(staker, operator, withdrawals[i], strategies, shares);
// }
// }
// 4. Complete Queued Withdrawal
_rollBlocksForCompleteWithdrawals(strategies);
for (uint i = 0; i < withdrawals.length; i++) {
staker.completeWithdrawalAsShares(withdrawals[i]);
check_Withdrawal_AsShares_State(staker, operator, withdrawals[i], strategies, shares);
}
}

// TODO: fix test
// function testFuzz_delegate_deposit_queue_completeAsTokens(uint24 _random) public {
// // Configure the random parameters for the test
// _configRand({
// _randomSeed: _random,
// _assetTypes: HOLDS_LST | HOLDS_ETH | HOLDS_ALL,
// _userTypes: DEFAULT | ALT_METHODS
// });
function testFuzz_delegate_deposit_queue_completeAsTokens(uint24 _random) public {
// Configure the random parameters for the test
_configRand({
_randomSeed: _random,
_assetTypes: HOLDS_LST | HOLDS_ETH | HOLDS_ALL,
_userTypes: DEFAULT | ALT_METHODS
});

// // Create a staker and an operator with a nonzero balance and corresponding strategies
// (User staker, IStrategy[] memory strategies, uint[] memory tokenBalances) = _newRandomStaker();
// (User operator, ,) = _newRandomOperator();
// // Upgrade contracts if forkType is not local
// _upgradeEigenLayerContracts();
// Create a staker and an operator with a nonzero balance and corresponding strategies
(User staker, IStrategy[] memory strategies, uint[] memory tokenBalances) = _newRandomStaker();
(User operator, ,) = _newRandomOperator();
// Upgrade contracts if forkType is not local
_upgradeEigenLayerContracts();

// // 1. Delegate to operator
// staker.delegateTo(operator);
// check_Delegation_State(staker, operator, strategies, new uint256[](strategies.length)); // Initial shares are zero
// 1. Delegate to operator
staker.delegateTo(operator);
check_Delegation_State(staker, operator, strategies, new uint256[](strategies.length)); // Initial shares are zero

// // 2. Deposit into strategy
// staker.depositIntoEigenlayer(strategies, tokenBalances);
// uint[] memory shares = _calculateExpectedShares(strategies, tokenBalances);
// 2. Deposit into strategy
staker.depositIntoEigenlayer(strategies, tokenBalances);
uint[] memory shares = _calculateExpectedShares(strategies, tokenBalances);

// // Check that the deposit increased operator shares the staker is delegated to
// check_Deposit_State(staker, strategies, shares);
// assert_Snap_Added_OperatorShares(operator, strategies, shares, "operator should have received shares");
// Check that the deposit increased operator shares the staker is delegated to
check_Deposit_State(staker, strategies, shares);
assert_Snap_Added_OperatorShares(operator, strategies, shares, "operator should have received shares");

// // 3. Queue Withdrawal
// IDelegationManagerTypes.Withdrawal[] memory withdrawals = staker.queueWithdrawals(strategies, shares);
// bytes32[] memory withdrawalRoots = _getWithdrawalHashes(withdrawals);
// check_QueuedWithdrawal_State(staker, operator, strategies, shares, withdrawals, withdrawalRoots);
// 3. Queue Withdrawal
IDelegationManagerTypes.Withdrawal[] memory withdrawals = staker.queueWithdrawals(strategies, shares);
bytes32[] memory withdrawalRoots = _getWithdrawalHashes(withdrawals);
check_QueuedWithdrawal_State(staker, operator, strategies, shares, withdrawals, withdrawalRoots);

// // 4. Complete Queued Withdrawal
// _rollBlocksForCompleteWithdrawals(strategies);
// for (uint i = 0; i < withdrawals.length; i++) {
// uint[] memory expectedTokens = _calculateExpectedTokens(strategies, shares);
// IERC20[] memory tokens = staker.completeWithdrawalAsTokens(withdrawals[i]);
// check_Withdrawal_AsTokens_State(staker, operator, withdrawals[i], strategies, shares, tokens, expectedTokens);
// }
// }
// 4. Complete Queued Withdrawal
_rollBlocksForCompleteWithdrawals(strategies);
for (uint i = 0; i < withdrawals.length; i++) {
uint[] memory expectedTokens = _calculateExpectedTokens(strategies, shares);
IERC20[] memory tokens = staker.completeWithdrawalAsTokens(withdrawals[i]);
check_Withdrawal_AsTokens_State(staker, operator, withdrawals[i], strategies, shares, tokens, expectedTokens);
}
}
}
10 changes: 10 additions & 0 deletions src/test/integration/users/User.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -618,4 +618,14 @@ contract User_AltMethods is User {
}
}
}

bytes4 internal constant MAGIC_VALUE = 0x1626ba7e;

function isValidSignature(bytes32 hash, bytes memory) external view returns (bytes4) {
if (signedHashes[hash]) {
return MAGIC_VALUE;
} else {
return 0xffffffff;
}
}
}

0 comments on commit 2f5b4b6

Please sign in to comment.