Skip to content
Open
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
66 changes: 66 additions & 0 deletions test/EtherFiTimelock.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,72 @@ contract TimelockTest is TestSetup {
console2.log("Role granted successfully to:", wallet);
console2.logBytes32(role);
}

function test_completeQueuedWithdrawals_realistic() public {
initializeRealisticFork(MAINNET_FORK);
(IDelegationManager.Withdrawal memory withdrawal, uint256[] memory shares) = eigenLayerDelegationManager.getQueuedWithdrawal(0xe1ae945fa8792e19a98e5108f478d585aab3ca2b58f5d9847dad3d142f2f8f4d);
IERC20[][] memory tokens = new IERC20[][](1);
tokens[0] = new IERC20[](1);
tokens[0][0] = IERC20(address(stEth));

address target = address(etherFiRestakerInstance);
IDelegationManager.Withdrawal[] memory withdrawals = new IDelegationManager.Withdrawal[](1);
withdrawals[0] = withdrawal;
bytes memory data = abi.encodeWithSelector(EtherFiRestaker.completeQueuedWithdrawals.selector, withdrawals, tokens);
//bytes memory stEthRequestWithdrawalData = abi.encodeWithSelector(EtherFiRestaker.stEthRequestWithdrawal.selector, 65000 ether);
console2.logBytes(data);
//console2.logBytes(stEthRequestWithdrawalData);
vm.startPrank(0x2aCA71020De61bb532008049e1Bd41E451aE8AdC);
etherFiRestakerInstance.completeQueuedWithdrawals(withdrawals, tokens);
etherFiRestakerInstance.stEthRequestWithdrawal(65000 ether);
vm.stopPrank();
}

function test_set_instant_wd_fee_zero() public {
initializeRealisticFork(MAINNET_FORK);

(IDelegationManager.Withdrawal memory withdrawal, uint256[] memory shares) = eigenLayerDelegationManager.getQueuedWithdrawal(0xe1ae945fa8792e19a98e5108f478d585aab3ca2b58f5d9847dad3d142f2f8f4d);
IERC20[][] memory tokens = new IERC20[][](1);
tokens[0] = new IERC20[](1);
tokens[0][0] = IERC20(address(stEth));
address[] memory addresses = new address[](3);
addresses[0] = address(etherFiRedemptionManagerInstance);
addresses[1] = address(etherFiRedemptionManagerInstance);
addresses[2] = address(etherFiRedemptionManagerInstance);

bytes[] memory data = new bytes[](addresses.length);
data[0] = abi.encodeWithSelector(EtherFiRedemptionManager.setExitFeeBasisPoints.selector, 0, address(stEth));
data[1] = abi.encodeWithSelector(EtherFiRedemptionManager.setCapacity.selector, 70000 ether, address(stEth));
data[2] = abi.encodeWithSelector(EtherFiRedemptionManager.setRefillRatePerSecond.selector, 4861111111111111111 * 4, address(stEth));

uint256[] memory values = new uint256[](addresses.length);
values[0] = 0;
values[1] = 0;
values[2] = 0;

_batch_execute_timelock(addresses, data, values, true, false, true, false);

//verify in 5hrs someone can do instant wd of 60k eeth at 0 exit fee
vm.warp(block.timestamp + 1 hours + 100);
vm.deal(0x2aCA71020De61bb532008049e1Bd41E451aE8AdC, 61000 ether);
vm.startPrank(0x2aCA71020De61bb532008049e1Bd41E451aE8AdC);
IDelegationManager.Withdrawal[] memory withdrawals = new IDelegationManager.Withdrawal[](1);
withdrawals[0] = withdrawal;
etherFiRestakerInstance.completeQueuedWithdrawals(withdrawals, tokens);

//mint eeth to 0x2aCA71020De61bb532008049e1Bd41E451aE8AdC
liquidityPoolInstance.deposit{value: 61000 ether}(0x2aCA71020De61bb532008049e1Bd41E451aE8AdC);
//approve eeth to redemption manager
eETHInstance.approve(address(etherFiRedemptionManagerInstance), 60000 ether);
//redeem eeth to steth
etherFiRedemptionManagerInstance.redeemEEth(60000 ether, 0x2aCA71020De61bb532008049e1Bd41E451aE8AdC, address(stEth));
console2.log("steth balance of 0x2aCA71020De61bb532008049e1Bd41E451aE8AdC:", stEth.balanceOf(0x2aCA71020De61bb532008049e1Bd41E451aE8AdC));
vm.stopPrank();
//verify steth balance of 0x2aCA71020De61bb532008049e1Bd41E451aE8AdC
//assertEq(stEth.balanceOf(0x2aCA71020De61bb532008049e1Bd41E451aE8AdC), 60000 ether);
}


}


Expand Down
11 changes: 7 additions & 4 deletions test/TestSetup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ contract TestSetup is Test, ContractCodeChecker, DepositDataGeneration {
earlyAdopterPoolInstance = EarlyAdopterPool(payable(addressProviderInstance.getContractAddress("EarlyAdopterPool")));
withdrawRequestNFTInstance = WithdrawRequestNFT(addressProviderInstance.getContractAddress("WithdrawRequestNFT"));
liquifierInstance = Liquifier(payable(addressProviderInstance.getContractAddress("Liquifier")));
etherFiTimelockInstance = EtherFiTimelock(payable(addressProviderInstance.getContractAddress("EtherFiTimelock")));
etherFiTimelockInstance = EtherFiTimelock(payable(0xcD425f44758a08BaAB3C4908f3e3dE5776e45d7a));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restore timelock lookup from AddressProvider

initializeRealisticFork now hardcodes etherFiTimelockInstance to the operating timelock instead of reading "EtherFiTimelock" from AddressProvider, which changes the authority model for every fork test that uses this setup. This makes _execute_timelock/_batch_execute_timelock impersonate the wrong proposer for contracts still governed by the main timelock (for example, mainnet role owners are pinned to 0x9f26... in test/behaviour-tests/ELExitsForkTestingDeployment.t.sol lines 54-56), and it also makes the TESTNET_FORK path point to a mainnet-only address.

Useful? React with 👍 / 👎.

etherFiAdminInstance = EtherFiAdmin(payable(addressProviderInstance.getContractAddress("EtherFiAdmin")));
etherFiOracleInstance = EtherFiOracle(payable(addressProviderInstance.getContractAddress("EtherFiOracle")));
etherFiRedemptionManagerInstance = EtherFiRedemptionManager(payable(address(0xDadEf1fFBFeaAB4f68A9fD181395F68b4e4E7Ae0)));
Expand Down Expand Up @@ -1705,9 +1705,12 @@ contract TestSetup is Test, ContractCodeChecker, DepositDataGeneration {
vm.stopPrank();
}

function _batch_execute_timelock(address[] memory targets, bytes[] memory data, uint256[] memory values, bool _schedule, bool _log_schedule, bool _execute, bool _log_execute) internal {
vm.startPrank(0xcdd57D11476c22d265722F68390b036f3DA48c21);

function _batch_execute_timelock(address[] memory targets, bytes[] memory data, uint256[] memory values, bool _schedule, bool _log_schedule, bool _execute, bool _log_execute) internal {
if(address(0x9f26d4C958fD811A1F59B01B86Be7dFFc9d20761) == address(etherFiTimelockInstance)) { // 3 Day Timelock
vm.startPrank(0xcdd57D11476c22d265722F68390b036f3DA48c21);
} else { // 8hr Timelock
vm.startPrank(0x2aCA71020De61bb532008049e1Bd41E451aE8AdC);
}
bytes32 salt = keccak256(abi.encode(targets, data, block.number));
if (_schedule) etherFiTimelockInstance.scheduleBatch(targets, values, data, bytes32(0), salt, etherFiTimelockInstance.getMinDelay());
if (_log_schedule) _batch_output_schedule_txn(targets, data, values, bytes32(0), salt, etherFiTimelockInstance.getMinDelay());
Expand Down
Loading