Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BN Fix test #197

Draft
wants to merge 11 commits into
base: bn-slashing-upgrade
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnotes/
27 changes: 12 additions & 15 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
commit = 2f112697506eab12d433a65fdc31a639548fe365
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/openzeppelin/openzeppelin-contracts-upgradeable
commit = 22489db15621b9a42ebddb1facade6962034e9b9
[submodule "lib/safe-smart-account"]
path = lib/safe-smart-account
url = https://github.com/safe-global/safe-smart-account
branch = v1.4.1
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/openzeppelin/openzeppelin-contracts
commit = dbb6104ce834628e473d2173bbc9d47f81a9eec3
branch = v1.4.1
[submodule "lib/eigenlayer-contracts"]
path = lib/eigenlayer-contracts
url = https://github.com/layr-labs/eigenlayer-contracts
commit = bda003385c5fec59e35196dc14d01f17d1eb7001
url = https://github.com/yieldnest/eigenlayer-contracts
branch = oz-4-remapping
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"files.insertFinalNewline": false,
"files.trimFinalNewlines": false,
"files.trimTrailingWhitespace": false,
}
4 changes: 2 additions & 2 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fs_permissions = [
optimizer = true
optimizer-runs = 200
evm_version = "cancun"
solc_version = "0.8.24"
solc_version = "0.8.27"
prompt_timeout = 120

ignored_error_codes = [5159, 2018, 5574, 3860]
Expand All @@ -25,4 +25,4 @@ contract_new_lines = true
number_underscore = "thousands"

[fuzz]
seed = "420"
seed = "420"
2 changes: 1 addition & 1 deletion lib/eigenlayer-contracts
2 changes: 1 addition & 1 deletion lib/openzeppelin-contracts
2 changes: 1 addition & 1 deletion lib/openzeppelin-contracts-upgradeable
5 changes: 3 additions & 2 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@openzeppelin-upgrades/=lib/eigenlayer-contracts/lib/openzeppelin-contracts-upgradeable/
@openzeppelin-upgrades/=lib/openzeppelin-contracts-upgradeable/
@openzeppelin/=lib/openzeppelin-contracts/
@eigenlayer/=lib/eigenlayer-contracts/
@eigenlayer/=lib/eigenlayer-contracts/
forge-std/=lib/forge-std/src/
5 changes: 5 additions & 0 deletions script/ContractAddresses.sol
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ contract ContractAddresses {
return addresses[chainId];
}

function getChainIds() external view returns (ChainIds memory) {
return chainIds;
}


function isSupportedChainId(uint256 chainId) external view returns (bool) {
return chainId == chainIds.mainnet || chainId == chainIds.holeksy;
}
Expand Down
24 changes: 13 additions & 11 deletions src/StakingNode.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.24;

import {ReentrancyGuardUpgradeable} from "lib/openzeppelin-contracts-upgradeable/contracts/utils/ReentrancyGuardUpgradeable.sol";
import {BeaconChainProofs} from "lib/eigenlayer-contracts/src/contracts/libraries/BeaconChainProofs.sol";
import {IDelegationManager } from "lib/eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol";
import {IDelegationManager, IDelegationManagerTypes } from "lib/eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol";
import {IEigenPodManager } from "lib/eigenlayer-contracts/src/contracts/interfaces/IEigenPodManager.sol";
import {IEigenPod } from "lib/eigenlayer-contracts/src/contracts/interfaces/IEigenPod.sol";
import {ISignatureUtils} from "lib/eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol";
Expand All @@ -13,6 +13,8 @@ import {IEigenPodManager} from "lib/eigenlayer-contracts/src/contracts/interface
import {IStakingNodesManager} from "src/interfaces/IStakingNodesManager.sol";
import {IStakingNode} from "src/interfaces/IStakingNode.sol";
import {IERC20} from "lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol";

import {IERC20 as IERC20V4} from "lib/eigenlayer-contracts/lib/openzeppelin-contracts-v4.9.0/contracts/interfaces/IERC20.sol";
import {DEFAULT_VALIDATOR_STAKE} from "src/Constants.sol";

interface StakingNodeEvents {
Expand Down Expand Up @@ -284,7 +286,7 @@ contract StakingNode is IStakingNode, StakingNodeEvents, ReentrancyGuardUpgradea

IDelegationManager delegationManager = IDelegationManager(address(stakingNodesManager.delegationManager()));

IDelegationManager.QueuedWithdrawalParams[] memory params = new IDelegationManager.QueuedWithdrawalParams[](1);
IDelegationManagerTypes.QueuedWithdrawalParams[] memory params = new IDelegationManagerTypes.QueuedWithdrawalParams[](1);
IStrategy[] memory strategies = new IStrategy[](1);

// Assumption: 1 Share of beaconChainETHStrategy = 1 ETH.
Expand All @@ -293,10 +295,10 @@ contract StakingNode is IStakingNode, StakingNodeEvents, ReentrancyGuardUpgradea
strategies[0] = beaconChainETHStrategy;
shares[0] = sharesAmount;
// The delegationManager requires the withdrawer == msg.sender (the StakingNode in this case).
params[0] = IDelegationManager.QueuedWithdrawalParams({
params[0] = IDelegationManagerTypes.QueuedWithdrawalParams({
strategies: strategies,
shares: shares,
withdrawer: address(this)
depositShares: shares,
__deprecated_withdrawer: address(this)
});

fullWithdrawalRoots = delegationManager.queueWithdrawals(params);
Expand Down Expand Up @@ -327,7 +329,7 @@ contract StakingNode is IStakingNode, StakingNodeEvents, ReentrancyGuardUpgradea
uint256 totalWithdrawalAmount = 0;

bool[] memory receiveAsTokens = new bool[](withdrawals.length);
IERC20[][] memory tokens = new IERC20[][](withdrawals.length);
IERC20V4[][] memory tokens = new IERC20V4[][](withdrawals.length);
for (uint256 i = 0; i < withdrawals.length; i++) {

// Set receiveAsTokens to true to receive ETH when completeQueuedWithdrawals runs.
Expand All @@ -339,10 +341,10 @@ contract StakingNode is IStakingNode, StakingNodeEvents, ReentrancyGuardUpgradea

// tokens array must match length of the withdrawals[i].strategies
// but does not need actual values in the case of the beaconChainETHStrategy
tokens[i] = new IERC20[](withdrawals[i].strategies.length);
tokens[i] = new IERC20V4[](withdrawals[i].strategies.length);

for (uint256 j = 0; j < withdrawals[i].shares.length; j++) {
totalWithdrawalAmount += withdrawals[i].shares[j];
for (uint256 j = 0; j < withdrawals[i].scaledShares.length; j++) {
totalWithdrawalAmount += withdrawals[i].scaledShares[j];
}
}

Expand All @@ -356,7 +358,7 @@ contract StakingNode is IStakingNode, StakingNodeEvents, ReentrancyGuardUpgradea
// 2. For beaconChainETHStrategy, the DelegationManager calls _withdrawSharesAsTokens interacts with the EigenPodManager.withdrawSharesAsTokens
// 3. Finally, the EigenPodManager calls withdrawRestakedBeaconChainETH on the EigenPod of this StakingNode to finalize the withdrawal.
// 4. the EigenPod decrements withdrawableRestakedExecutionLayerGwei and send the ETH to address(this)
delegationManager.completeQueuedWithdrawals(withdrawals, tokens, middlewareTimesIndexes, receiveAsTokens);
delegationManager.completeQueuedWithdrawals(withdrawals, tokens, receiveAsTokens);

uint256 finalETHBalance = address(this).balance;
uint256 actualWithdrawalAmount = finalETHBalance - initialETHBalance;
Expand Down Expand Up @@ -418,7 +420,7 @@ contract StakingNode is IStakingNode, StakingNodeEvents, ReentrancyGuardUpgradea
// 4. podOwnerShares: Active shares in Eigenlayer, representing staked ETH
int256 totalETHBalance =
int256(withdrawnETH + unverifiedStakedETH + queuedSharesAmount)
+ eigenPodManager.podOwnerShares(address(this));
+ eigenPodManager.podOwnerDepositShares(address(this));

if (totalETHBalance < 0) {
return 0;
Expand Down
27 changes: 14 additions & 13 deletions src/ynEIGEN/TokenStakingNode.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import {Initializable} from "lib/openzeppelin-contracts-upgradeable/contracts/pr
import {IBeacon} from "lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol";
import {ReentrancyGuardUpgradeable} from "lib/openzeppelin-contracts-upgradeable/contracts/utils/ReentrancyGuardUpgradeable.sol";
import {IERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import {IERC20 as IERC20V4} from "lib/eigenlayer-contracts/lib/openzeppelin-contracts-v4.9.0/contracts/interfaces/IERC20.sol";
import {SafeERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
import {ISignatureUtils} from "lib/eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol";
import {IStrategyManager} from "lib/eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol";
import {IDelegationManager} from "lib/eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol";
import {IDelegationManager, IDelegationManagerTypes} from "lib/eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol";
import {IStrategy} from "lib/eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol";
import {ITokenStakingNode} from "src/interfaces/ITokenStakingNode.sol";
import {ITokenStakingNodesManager} from "src/interfaces/ITokenStakingNodesManager.sol";
Expand Down Expand Up @@ -117,7 +118,7 @@ contract TokenStakingNode is

uint256 eigenShares = strategyManager.depositIntoStrategy(
IStrategy(strategy),
asset,
IERC20V4(address(asset)),
amount
);
emit DepositToEigenlayer(asset, strategy, amount, eigenShares);
Expand Down Expand Up @@ -147,11 +148,11 @@ contract TokenStakingNode is
_strategiesArray[0] = _strategy;
uint256[] memory _sharesArray = new uint256[](1);
_sharesArray[0] = _shares;
IDelegationManager.QueuedWithdrawalParams[] memory _params = new IDelegationManager.QueuedWithdrawalParams[](1);
_params[0] = IDelegationManager.QueuedWithdrawalParams({
IDelegationManagerTypes.QueuedWithdrawalParams[] memory _params = new IDelegationManagerTypes.QueuedWithdrawalParams[](1);
_params[0] = IDelegationManagerTypes.QueuedWithdrawalParams({
strategies: _strategiesArray,
shares: _sharesArray,
withdrawer: address(this)
depositShares: _sharesArray,
__deprecated_withdrawer: address(this)
});

queuedShares[_strategy] += _shares;
Expand Down Expand Up @@ -187,31 +188,31 @@ contract TokenStakingNode is
_strategiesArray[0] = _strategy;
uint256[] memory _sharesArray = new uint256[](1);
_sharesArray[0] = _shares;
_withdrawals[0] = IDelegationManager.Withdrawal({
_withdrawals[0] = IDelegationManagerTypes.Withdrawal({
staker: address(this),
delegatedTo: _delegationManager.delegatedTo(address(this)),
withdrawer: address(this),
nonce: _nonce,
startBlock: _startBlock,
strategies: _strategiesArray,
shares: _sharesArray
scaledShares: _sharesArray
});
}

IERC20 _token = _strategy.underlyingToken();
IERC20 _token = IERC20(address(_strategy.underlyingToken()));
uint256 _balanceBefore = _token.balanceOf(address(this));

{
bool[] memory _receiveAsTokens = new bool[](1);
_receiveAsTokens[0] = true;
IERC20[][] memory _tokens = new IERC20[][](1);
_tokens[0] = new IERC20[](1);
_tokens[0][0] = _token;
IERC20V4[][] memory _tokens = new IERC20V4[][](1);
_tokens[0] = new IERC20V4[](1);
_tokens[0][0] = IERC20V4(address(_token));

_delegationManager.completeQueuedWithdrawals(
_withdrawals,
_tokens,
_middlewareTimesIndexes,
//_middlewareTimesIndexes,
_receiveAsTokens
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/ynEIGEN/WithdrawalsProcessor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ contract WithdrawalsProcessor is IWithdrawalsProcessor, Initializable, AccessCon

IStrategy[] memory _strategies = new IStrategy[](1);
_strategies[0] = IStrategy(_queuedWithdrawal.strategy);
uint256 _withdrawalDelay = delegationManager.getWithdrawalDelay(_strategies);
uint256 _withdrawalDelay = 0; //delegationManager.getWithdrawalDelay(_strategies);
if (block.number < _queuedWithdrawal.startBlock + _withdrawalDelay) return false;
}

Expand Down
7 changes: 4 additions & 3 deletions src/ynViewer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ contract ynViewer is IynViewer {
function withdrawalDelayBlocks(address _strategy) external view returns (uint256) {
IDelegationManager _delegationManager = stakingNodesManager.delegationManager();
uint256 _minDelay = _delegationManager.minWithdrawalDelayBlocks();
uint256 _strategyDelay = _delegationManager.strategyWithdrawalDelayBlocks(IStrategy(_strategy));
return _minDelay > _strategyDelay ? _minDelay : _strategyDelay;
// uint256 _strategyDelay = _delegationManager.__deprecated_strategyWithdrawalDelayBlocks(IStrategy(_strategy));
// return _minDelay > _strategyDelay ? _minDelay : _strategyDelay;
return _minDelay;
}

/// @inheritdoc IynViewer
Expand All @@ -60,7 +61,7 @@ contract ynViewer is IynViewer {
nodeId: _node.nodeId(),
ethBalance: _node.getETHBalance(),
eigenPodEthBalance: _eigenPod.balance,
podOwnerShares: _eigenPodManager.podOwnerShares(address(_node)),
podOwnerShares: _eigenPodManager.podOwnerDepositShares(address(_node)),
stakingNode: address(_node),
eigenPod: _eigenPod,
delegatedTo: stakingNodesManager.delegationManager().delegatedTo(address(_node))
Expand Down
12 changes: 10 additions & 2 deletions test/integration/M3/Base.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {ProxyAdmin} from "lib/openzeppelin-contracts/contracts/proxy/transparent

import {IStrategy} from "lib/eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol";
import {IEigenPodManager} from "lib/eigenlayer-contracts/src/contracts/interfaces/IEigenPodManager.sol";
import {IDelegationManager} from "lib/eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol";
import {IDelegationManager, IDelegationManagerTypes} from "lib/eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol";
import {BeaconChainMock, BeaconChainProofs, CheckpointProofs, CredentialProofs, EigenPodManager} from "lib/eigenlayer-contracts/src/test/integration/mocks/BeaconChainMock.t.sol";

import {Utils} from "../../../script/Utils.sol";
Expand Down Expand Up @@ -86,6 +86,14 @@ contract Base is Test, Utils {
stakingNodesManager.grantRole(stakingNodesManager.STAKING_NODES_WITHDRAWER_ROLE(), actors.ops.STAKING_NODES_WITHDRAWER);
vm.stopPrank();
}

// Upgrade StakingNode implementation with EL slashing upgrade changes
if (block.chainid == contractAddresses.getChainIds().holeksy) {
address newStakingNodeImplementation = address(new StakingNode());
vm.startPrank(actors.admin.STAKING_ADMIN);
stakingNodesManager.upgradeStakingNodeImplementation(newStakingNodeImplementation);
vm.stopPrank();
}
}

function assignContracts() internal {
Expand Down Expand Up @@ -295,7 +303,7 @@ contract Base is Test, Utils {
console.log("EigenPod shares for each StakingNode:");
for (uint256 i = 0; i < stakingNodesManager.nodesLength(); i++) {
IStakingNode stakingNode = stakingNodesManager.nodes(i);
uint256 podShares = uint256(IEigenPodManager(chainAddresses.eigenlayer.EIGENPOD_MANAGER_ADDRESS).podOwnerShares(address(stakingNode)));
uint256 podShares = uint256(IEigenPodManager(chainAddresses.eigenlayer.EIGENPOD_MANAGER_ADDRESS).podOwnerDepositShares(address(stakingNode)));
console.log("Node", i, "Shares:", podShares);
}
}
Expand Down
Loading
Loading