Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 72 additions & 10 deletions src/test/integration/IntegrationBase.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ abstract contract IntegrationBase is IntegrationDeployer {
uint numStakers = 0;
uint numOperators = 0;

// Lists of stakers/operators created before the m2 upgrade
//
// When we call _upgradeEigenLayerContracts, we iterate over
// these lists and migrate perform the standard migration actions
// for each user
User[] stakersToMigrate;
User[] operatorsToMigrate;

/**
* Gen/Init methods:
*/
Expand All @@ -27,13 +35,27 @@ abstract contract IntegrationBase is IntegrationDeployer {
* This user is ready to deposit into some strategies and has some underlying token balances
*/
function _newRandomStaker() internal returns (User, IStrategy[] memory, uint[] memory) {
string memory stakerName = string.concat("- Staker", numStakers.toString());
numStakers++;
string memory stakerName;

User staker;
IStrategy[] memory strategies;
uint[] memory tokenBalances;

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

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

(User staker, IStrategy[] memory strategies, uint[] memory tokenBalances) = _randUser(stakerName);
stakersToMigrate.push(staker);
} else {
stakerName = string.concat("- Staker", numStakers.toString());

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

assert_HasUnderlyingTokenBalances(staker, strategies, tokenBalances, "_newRandomStaker: failed to award token balances");

numStakers++;
return (staker, strategies, tokenBalances);
}

Expand All @@ -44,25 +66,28 @@ abstract contract IntegrationBase is IntegrationDeployer {
* as ETH podowner shares are not available yet.
*/
function _newRandomOperator() internal returns (User, IStrategy[] memory, uint[] memory) {
string memory operatorName = string.concat("- Operator", numOperators.toString());
numOperators++;

User operator;
IStrategy[] memory strategies;
uint[] memory tokenBalances;

if (forkType == MAINNET && !isUpgraded) {
// Create an operator for M1
(operator, , ) = _randUser(operatorName);
// deal with random assets of only LSTS
(strategies, tokenBalances) = _dealRandAssets_M1(operator);
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
(operator, strategies, tokenBalances) = _randUser_NoETH(operatorName);

User_M1(payable(address(operator))).depositIntoEigenlayer_M1(strategies, tokenBalances);
uint[] memory addedShares = _calculateExpectedShares(strategies, tokenBalances);

assert_Snap_Added_StakerShares(operator, strategies, addedShares, "_newRandomOperator: failed to add delegatable shares");

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

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

uint[] memory addedShares = _calculateExpectedShares(strategies, tokenBalances);

operator.registerAsOperator();
Expand All @@ -73,9 +98,45 @@ abstract contract IntegrationBase is IntegrationDeployer {
assertTrue(delegationManager.isOperator(address(operator)), "_newRandomOperator: operator should be registered");
}

numOperators++;
return (operator, strategies, tokenBalances);
}

/// @dev If we're on mainnet, upgrade contracts to M2 and migrate stakers/operators
function _upgradeEigenLayerContracts() internal {
if (forkType == MAINNET) {
require(!isUpgraded, "_upgradeEigenLayerContracts: already performed m2 upgrade");

emit log("_upgradeEigenLayerContracts: upgrading mainnet to m2");
_upgradeMainnetContracts();

emit log("===Migrating Stakers/Operators===");

// Enable restaking for stakers' pods
for (uint i = 0; i < stakersToMigrate.length; i++) {
stakersToMigrate[i].activateRestaking();
}

// Register operators with DelegationManager
for (uint i = 0; i < operatorsToMigrate.length; i++) {
operatorsToMigrate[i].registerAsOperator();
}

emit log("======");

isUpgraded = true;
emit log("_upgradeEigenLayerContracts: m2 upgrade complete");
} else if (forkType == HOLESKY) {
require(!isUpgraded, "_upgradeEigenLayerContracts: already performed m2 upgrade");

emit log("_upgradeEigenLayerContracts: upgrading holesky to m2");
_upgradeHoleskyContracts();

isUpgraded = true;
emit log("_upgradeEigenLayerContracts: m2 upgrade complete");
}
}

/**
* Common assertions:
*/
Expand Down Expand Up @@ -106,6 +167,7 @@ abstract contract IntegrationBase is IntegrationDeployer {
}

assertApproxEqAbs(expectedBalance, tokenBalance, 1, err);
// assertEq(expectedBalance, tokenBalance, err);
}
}

Expand Down
137 changes: 56 additions & 81 deletions src/test/integration/IntegrationDeployer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -446,10 +446,10 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
strategyManager.unpause(0);

eigenPodManager.updateBeaconChainOracle(beaconChainOracle);
timeMachine.setProofGenStartTime(2 hours);
timeMachine.setProofGenStartTime(0);
beaconChain.setNextTimestamp(timeMachine.proofGenStartTime());

if (eigenPodManager.denebForkTimestamp() == 0) {
if (eigenPodManager.denebForkTimestamp() == type(uint64).max) {
//set deneb fork timestamp if not set
eigenPodManager.setDenebForkTimestamp(DENEB_FORK_TIMESTAMP);
}
Expand Down Expand Up @@ -556,10 +556,10 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
strategyManager.unpause(0);

eigenPodManager.updateBeaconChainOracle(beaconChainOracle);
timeMachine.setProofGenStartTime(2 hours);
timeMachine.setProofGenStartTime(0);
beaconChain.setNextTimestamp(timeMachine.proofGenStartTime());

if (eigenPodManager.denebForkTimestamp() == 0) {
if (eigenPodManager.denebForkTimestamp() == type(uint64).max) {
//set deneb fork timestamp if not set
eigenPodManager.setDenebForkTimestamp(DENEB_FORK_TIMESTAMP);
}
Expand Down Expand Up @@ -653,6 +653,8 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
function _deployOrFetchContracts() internal {
forkType = _randForkType();

emit log_named_string("_deployOrFetchContracts selected fork for test", forkTypeToStr[forkType]);

if (forkType == LOCAL) {
_setUpLocal();
// Set Upgraded as local setup deploys most up to date contracts
Expand Down Expand Up @@ -729,72 +731,6 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
}
}

/**
* For non LOCAL forkTypes, upgrade contracts to current implementations as well as
* unpausing all contracts.
*/
function _upgradeEigenLayerContracts() internal {
if (forkType == MAINNET) {
require(!isUpgraded, "_upgradeEigenLayerContracts: already upgraded");
_upgradeMainnetContracts();
isUpgraded = true;
} else if (forkType == HOLESKY) {
require(!isUpgraded, "_upgradeEigenLayerContracts: already upgraded");
_upgradeHoleskyContracts();
isUpgraded = true;
}
}

/**
* For non LOCAL forkTypes, upgrade contracts to current implementations as well as
* unpausing all contracts.
*/
function _upgradeEigenLayerContracts(User staker, User operator) internal {
if (forkType == MAINNET) {
require(!isUpgraded, "_upgradeEigenLayerContracts: already upgraded");
_upgradeMainnetContracts();

// Enable restaking for stakers' pods
staker.activateRestaking();
// Now register users that are supposed to be Operators
operator.registerAsOperator();
isUpgraded = true;
} else if (forkType == HOLESKY) {
require(!isUpgraded, "_upgradeEigenLayerContracts: already upgraded");
_upgradeHoleskyContracts();

isUpgraded = true;
}
}

/**
* For non LOCAL forkTypes, upgrade contracts to current implementations as well as
* unpausing all contracts.
* @param stakers - array of stakers to activate restaking for that were setup before upgrade
* @param operators - array of operators to register that were setup before upgrade
*/
function _upgradeEigenLayerContracts(User[] memory stakers, User[] memory operators) internal {
if (forkType == MAINNET) {
require(!isUpgraded, "_upgradeEigenLayerContracts: already upgraded");
_upgradeMainnetContracts();

// Enable restaking for stakers' pods
for (uint i; i < stakers.length; i++) {
stakers[i].activateRestaking();
}
// Now register users that are supposed to be Operators
for (uint i; i < operators.length; i++) {
operators[i].registerAsOperator();
}
isUpgraded = true;
} else if (forkType == HOLESKY) {
require(!isUpgraded, "_upgradeEigenLayerContracts: already upgraded");
_upgradeHoleskyContracts();

isUpgraded = true;
}
}

/**
* @dev Create a new User with a random config using the range defined in `_configRand`
*
Expand All @@ -808,7 +744,47 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
uint assetType = _randAssetType();
uint userType = _randUserType();

// Create User contract based on deposit type:
// Deploy new User contract
User user = _genRandUser(name, userType);

// For the specific asset selection we made, get a random assortment of
// strategies and deal the user some corresponding underlying token balances
(IStrategy[] memory strategies, uint[] memory tokenBalances) = _dealRandAssets(user, assetType);

_printUserInfo(name, assetType, userType, strategies, tokenBalances);
return (user, strategies, tokenBalances);
}

/// @dev Create a new user without native ETH. See _randUser above for standard usage
function _randUser_NoETH(string memory name) internal returns (User, IStrategy[] memory, uint[] memory) {
// For the new user, select what type of assets they'll have and whether
// they'll use `xWithSignature` methods.
//
// The values selected here are in the ranges configured via `_configRand`
uint userType = _randUserType();

// Pick the user's asset distribution, removing "native ETH" as an option
// I'm sorry if this eventually leads to a bug that's really hard to track down
uint assetType = _randAssetType();
if (assetType == HOLDS_ETH) {
assetType = NO_ASSETS;
} else if (assetType == HOLDS_ALL) {
assetType = HOLDS_LST;
}

// Deploy new User contract
User user = _genRandUser(name, userType);

// For the specific asset selection we made, get a random assortment of
// strategies and deal the user some corresponding underlying token balances
(IStrategy[] memory strategies, uint[] memory tokenBalances) = _dealRandAssets(user, assetType);

_printUserInfo(name, assetType, userType, strategies, tokenBalances);
return (user, strategies, tokenBalances);
}

function _genRandUser(string memory name, uint userType) internal returns (User) {
// Create User contract based on userType:
User user;
if (forkType == LOCAL) {
user = new User(name);
Expand Down Expand Up @@ -852,12 +828,7 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
revert("_randUser: unimplemented forkType");
}

// For the specific asset selection we made, get a random assortment of
// strategies and deal the user some corresponding underlying token balances
(IStrategy[] memory strategies, uint[] memory tokenBalances) = _dealRandAssets(user, assetType);
_printUserInfo(assetType, userType, strategies, tokenBalances);

return (user, strategies, tokenBalances);
return user;
}

/// @dev For a given `assetType`, select a random assortment of strategies and assets
Expand Down Expand Up @@ -1026,16 +997,18 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
}

function _printUserInfo(
string memory name,
uint assetType,
uint userType,
IStrategy[] memory strategies,
uint[] memory tokenBalances
) internal {

emit log("Creating user:");
emit log_named_string("assetType: ", assetTypeToStr[assetType]);
emit log_named_string("userType: ", userTypeToStr[userType]);
emit log_named_string("forkType: ", forkTypeToStr[forkType]);
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);

Expand All @@ -1052,5 +1025,7 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
emit log_named_uint("token balance: ", tokenBalances[i]);
}
}

emit log("==================");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ contract Integration_Delegate_Deposit_Queue_Complete is IntegrationCheckUtils {
_randomSeed: _random,
_assetTypes: HOLDS_LST | HOLDS_ETH | HOLDS_ALL,
_userTypes: DEFAULT | ALT_METHODS,
_forkTypes: LOCAL | MAINNET | HOLESKY
_forkTypes: LOCAL | MAINNET
});
// 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(staker, operator);
_upgradeEigenLayerContracts();

// 1. Delegate to operator
staker.delegateTo(operator);
Expand Down Expand Up @@ -51,14 +51,14 @@ contract Integration_Delegate_Deposit_Queue_Complete is IntegrationCheckUtils {
_randomSeed: _random,
_assetTypes: HOLDS_LST | HOLDS_ETH | HOLDS_ALL,
_userTypes: DEFAULT | ALT_METHODS,
_forkTypes: LOCAL | MAINNET | HOLESKY
_forkTypes: LOCAL | MAINNET
});

// 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(staker, operator);
_upgradeEigenLayerContracts();

// 1. Delegate to operator
staker.delegateTo(operator);
Expand Down
Loading