Skip to content

Commit

Permalink
fix: integration test with 32 ether deposit cap
Browse files Browse the repository at this point in the history
  • Loading branch information
call-by committed Jul 16, 2024
1 parent cc41593 commit 806c749
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 121 deletions.
2 changes: 1 addition & 1 deletion src/core/NativeRestakingController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ abstract contract NativeRestakingController is
IExoCapsule.ValidatorContainerProof calldata validatorProof,
bytes32[] calldata withdrawalContainer,
BeaconChainProofs.WithdrawalProof calldata withdrawalProof
) external payable whenNotPaused {
) external payable whenNotPaused nonReentrant nativeRestakingEnabled {
IExoCapsule capsule = _getCapsule(msg.sender);
(bool partialWithdrawal, uint256 withdrawalAmount) =
capsule.verifyWithdrawalProof(validatorContainer, validatorProof, withdrawalContainer, withdrawalProof);
Expand Down
240 changes: 120 additions & 120 deletions test/foundry/DepositWithdrawPrinciple.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import "forge-std/Test.sol";
import "@layerzero-v2/protocol/contracts/libs/AddressCast.sol";
import "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/GUID.sol";
import "@openzeppelin/contracts/utils/Create2.sol";
import "forge-std/console.sol";

contract DepositWithdrawPrincipalTest is ExocoreDeployer {

Expand Down Expand Up @@ -247,7 +246,7 @@ contract DepositWithdrawPrincipalTest is ExocoreDeployer {

_testNativeDeposit(depositor, relayer, lastlyUpdatedPrincipalBalance);
lastlyUpdatedPrincipalBalance += 32 ether;
// _testNativeWithdraw(depositor, relayer, lastlyUpdatedPrincipalBalance);
_testNativeWithdraw(depositor, relayer, lastlyUpdatedPrincipalBalance);
}

function _testNativeDeposit(Player memory depositor, Player memory relayer, uint256 lastlyUpdatedPrincipalBalance)
Expand Down Expand Up @@ -296,6 +295,11 @@ contract DepositWithdrawPrincipalTest is ExocoreDeployer {
/// client chain layerzero endpoint should emit the message packet including deposit payload.
uint64 depositRequestNonce = 1;
uint256 depositAmount = uint256(_getEffectiveBalance(validatorContainer)) * GWEI_TO_WEI;
// Cap to 32 ether
if (depositAmount >= 32 ether) {
depositAmount = 32 ether;
}

bytes memory depositRequestPayload = abi.encodePacked(
GatewayStorage.Action.REQUEST_DEPOSIT,
bytes32(bytes20(VIRTUAL_STAKED_ETH_ADDRESS)),
Expand Down Expand Up @@ -349,7 +353,6 @@ contract DepositWithdrawPrincipalTest is ExocoreDeployer {
emit MessageSent(
GatewayStorage.Action.RESPOND, depositResponseId, depositResponseNonce, depositResponseNativeFee
);
console.log("--> received");
/// relayer catches the request message packet by listening to client chain event and feed it to Exocore network
vm.startPrank(relayer.addr);
exocoreLzEndpoint.lzReceive(
Expand Down Expand Up @@ -399,122 +402,119 @@ contract DepositWithdrawPrincipalTest is ExocoreDeployer {
);
}

// function _testNativeWithdraw(Player memory withdrawer, Player memory relayer, uint256
// lastlyUpdatedPrincipalBalance)
// internal
// {
// // before native withdraw, we simulate proper block environment states to make proof valid
// _simulateBlockEnvironmentForNativeWithdraw();
// deal(address(capsule), 1 ether); // Deposit 1 ether to handle excess amount withdraw

// // 2. withdrawer will call clientGateway.processBeaconChainWithdrawal to withdraw from Exocore thru layerzero

// /// client chain layerzero endpoint should emit the message packet including deposit payload.
// uint64 withdrawRequestNonce = 3;
// uint64 withdrawalAmountGwei = _getWithdrawalAmount(withdrawalContainer);
// uint256 withdrawalAmount;
// if (withdrawalAmountGwei > MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR) {
// withdrawalAmount = MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR * GWEI_TO_WEI;
// } else {
// withdrawalAmount = withdrawalAmountGwei * GWEI_TO_WEI;
// }
// bytes memory withdrawRequestPayload = abi.encodePacked(
// GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE,
// bytes32(bytes20(VIRTUAL_STAKED_ETH_ADDRESS)),
// bytes32(bytes20(withdrawer.addr)),
// withdrawalAmount
// );
// uint256 withdrawRequestNativeFee = clientGateway.quote(withdrawRequestPayload);
// bytes32 withdrawRequestId = generateUID(withdrawRequestNonce, true);

// // client chain layerzero endpoint should emit the message packet including withdraw payload.
// vm.expectEmit(true, true, true, true, address(clientChainLzEndpoint));
// emit NewPacket(
// exocoreChainId,
// address(clientGateway),
// address(exocoreGateway).toBytes32(),
// withdrawRequestNonce,
// withdrawRequestPayload
// );
// // client chain gateway should emit MessageSent event
// vm.expectEmit(true, true, true, true, address(clientGateway));
// emit MessageSent(
// GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE,
// withdrawRequestId,
// withdrawRequestNonce,
// withdrawRequestNativeFee
// );

// vm.startPrank(withdrawer.addr);
// clientGateway.processBeaconChainWithdrawal{value: withdrawRequestNativeFee}(
// validatorContainer, validatorProof, withdrawalContainer, withdrawalProof
// );
// vm.stopPrank();

// /// exocore gateway should return response message to exocore network layerzero endpoint
// uint64 withdrawResponseNonce = 3;
// lastlyUpdatedPrincipalBalance -= withdrawalAmount;
// bytes memory withdrawResponsePayload =
// abi.encodePacked(GatewayStorage.Action.RESPOND, withdrawRequestNonce, true,
// lastlyUpdatedPrincipalBalance);
// uint256 withdrawResponseNativeFee = exocoreGateway.quote(clientChainId, withdrawResponsePayload);
// bytes32 withdrawResponseId = generateUID(withdrawResponseNonce, false);

// // exocore gateway should return response message to exocore network layerzero endpoint
// vm.expectEmit(true, true, true, true, address(exocoreLzEndpoint));
// emit NewPacket(
// clientChainId,
// address(exocoreGateway),
// address(clientGateway).toBytes32(),
// withdrawResponseNonce,
// withdrawResponsePayload
// );
// // exocore gateway should emit MessageSent event
// vm.expectEmit(true, true, true, true, address(exocoreGateway));
// emit MessageSent(
// GatewayStorage.Action.RESPOND, withdrawResponseId, withdrawResponseNonce, withdrawResponseNativeFee
// );
// exocoreLzEndpoint.lzReceive(
// Origin(clientChainId, address(clientGateway).toBytes32(), withdrawRequestNonce),
// address(exocoreGateway),
// withdrawRequestId,
// withdrawRequestPayload,
// bytes("")
// );

// // client chain gateway should execute the response hook and emit depositResult event
// vm.expectEmit(true, true, true, true, address(clientGateway));
// emit WithdrawPrincipalResult(true, address(VIRTUAL_STAKED_ETH_ADDRESS), withdrawer.addr, withdrawalAmount);
// clientChainLzEndpoint.lzReceive(
// Origin(exocoreChainId, address(exocoreGateway).toBytes32(), withdrawResponseNonce),
// address(clientGateway),
// withdrawResponseId,
// withdrawResponsePayload,
// bytes("")
// );
// }

// function _simulateBlockEnvironmentForNativeWithdraw() internal {
// // load beacon chain validator container and proof from json file
// string memory withdrawalInfo = vm.readFile("test/foundry/test-data/full_withdrawal_proof.json");
// _loadValidatorContainer(withdrawalInfo);
// // load withdrawal proof
// _loadWithdrawalContainer(withdrawalInfo);

// activationTimestamp = BEACON_CHAIN_GENESIS_TIME + _getActivationEpoch(validatorContainer) *
// SECONDS_PER_EPOCH;
// mockProofTimestamp = activationTimestamp;
// validatorProof.beaconBlockTimestamp = mockProofTimestamp;

// /// we set current block timestamp to be exactly one slot after the proof generation timestamp
// mockCurrentBlockTimestamp = mockProofTimestamp + SECONDS_PER_SLOT;
// vm.warp(mockCurrentBlockTimestamp);

// vm.mockCall(
// address(beaconOracle),
// abi.encodeWithSelector(beaconOracle.timestampToBlockRoot.selector, validatorProof.beaconBlockTimestamp),
// abi.encode(beaconBlockRoot)
// );
// }
function _testNativeWithdraw(Player memory withdrawer, Player memory relayer, uint256 lastlyUpdatedPrincipalBalance)
internal
{
// before native withdraw, we simulate proper block environment states to make proof valid
_simulateBlockEnvironmentForNativeWithdraw();
deal(address(capsule), 1 ether); // Deposit 1 ether to handle excess amount withdraw

// 2. withdrawer will call clientGateway.processBeaconChainWithdrawal to withdraw from Exocore thru layerzero

/// client chain layerzero endpoint should emit the message packet including deposit payload.
uint64 withdrawRequestNonce = 2;
uint64 withdrawalAmountGwei = _getWithdrawalAmount(withdrawalContainer);
uint256 withdrawalAmount;
if (withdrawalAmountGwei > MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR) {
withdrawalAmount = MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR * GWEI_TO_WEI;
} else {
withdrawalAmount = withdrawalAmountGwei * GWEI_TO_WEI;
}
bytes memory withdrawRequestPayload = abi.encodePacked(
GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE,
bytes32(bytes20(VIRTUAL_STAKED_ETH_ADDRESS)),
bytes32(bytes20(withdrawer.addr)),
withdrawalAmount
);
uint256 withdrawRequestNativeFee = clientGateway.quote(withdrawRequestPayload);
bytes32 withdrawRequestId = generateUID(withdrawRequestNonce, true);

// client chain layerzero endpoint should emit the message packet including withdraw payload.
vm.expectEmit(true, true, true, true, address(clientChainLzEndpoint));
emit NewPacket(
exocoreChainId,
address(clientGateway),
address(exocoreGateway).toBytes32(),
withdrawRequestNonce,
withdrawRequestPayload
);
// client chain gateway should emit MessageSent event
vm.expectEmit(true, true, true, true, address(clientGateway));
emit MessageSent(
GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE,
withdrawRequestId,
withdrawRequestNonce,
withdrawRequestNativeFee
);

vm.startPrank(withdrawer.addr);
clientGateway.processBeaconChainWithdrawal{value: withdrawRequestNativeFee}(
validatorContainer, validatorProof, withdrawalContainer, withdrawalProof
);
vm.stopPrank();

/// exocore gateway should return response message to exocore network layerzero endpoint
uint64 withdrawResponseNonce = 3;
lastlyUpdatedPrincipalBalance -= withdrawalAmount;
bytes memory withdrawResponsePayload =
abi.encodePacked(GatewayStorage.Action.RESPOND, withdrawRequestNonce, true, lastlyUpdatedPrincipalBalance);
uint256 withdrawResponseNativeFee = exocoreGateway.quote(clientChainId, withdrawResponsePayload);
bytes32 withdrawResponseId = generateUID(withdrawResponseNonce, false);

// exocore gateway should return response message to exocore network layerzero endpoint
vm.expectEmit(true, true, true, true, address(exocoreLzEndpoint));
emit NewPacket(
clientChainId,
address(exocoreGateway),
address(clientGateway).toBytes32(),
withdrawResponseNonce,
withdrawResponsePayload
);
// exocore gateway should emit MessageSent event
vm.expectEmit(true, true, true, true, address(exocoreGateway));
emit MessageSent(
GatewayStorage.Action.RESPOND, withdrawResponseId, withdrawResponseNonce, withdrawResponseNativeFee
);
exocoreLzEndpoint.lzReceive(
Origin(clientChainId, address(clientGateway).toBytes32(), withdrawRequestNonce),
address(exocoreGateway),
withdrawRequestId,
withdrawRequestPayload,
bytes("")
);

// client chain gateway should execute the response hook and emit depositResult event
vm.expectEmit(true, true, true, true, address(clientGateway));
emit WithdrawPrincipalResult(true, address(VIRTUAL_STAKED_ETH_ADDRESS), withdrawer.addr, withdrawalAmount);
clientChainLzEndpoint.lzReceive(
Origin(exocoreChainId, address(exocoreGateway).toBytes32(), withdrawResponseNonce),
address(clientGateway),
withdrawResponseId,
withdrawResponsePayload,
bytes("")
);
}

function _simulateBlockEnvironmentForNativeWithdraw() internal {
// load beacon chain validator container and proof from json file
string memory withdrawalInfo = vm.readFile("test/foundry/test-data/full_withdrawal_proof.json");
_loadValidatorContainer(withdrawalInfo);
// load withdrawal proof
_loadWithdrawalContainer(withdrawalInfo);

activationTimestamp = BEACON_CHAIN_GENESIS_TIME + _getActivationEpoch(validatorContainer) * SECONDS_PER_EPOCH;
mockProofTimestamp = activationTimestamp;
validatorProof.beaconBlockTimestamp = mockProofTimestamp;

/// we set current block timestamp to be exactly one slot after the proof generation timestamp
mockCurrentBlockTimestamp = mockProofTimestamp + SECONDS_PER_SLOT;
vm.warp(mockCurrentBlockTimestamp);

vm.mockCall(
address(beaconOracle),
abi.encodeWithSelector(beaconOracle.timestampToBlockRoot.selector, validatorProof.beaconBlockTimestamp),
abi.encode(beaconBlockRoot)
);
}

}

0 comments on commit 806c749

Please sign in to comment.