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

refactor: separate NST deposit/withdrawal from LST deposit/withdrawal #96

Merged
merged 13 commits into from
Sep 25, 2024
2 changes: 1 addition & 1 deletion docs/native_deposit_workflow.wsd
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ start

:Get the capsule associated with the message sender;
if (capsule == address(0)) then (yes)
:Revert with CapsuleNotExist error;
:Revert with CapsuleDoesNotExist error;
stop
endif

Expand Down
5 changes: 2 additions & 3 deletions script/11_SetPeers.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pragma solidity ^0.8.19;

import {Bootstrap} from "../src/core/Bootstrap.sol";
import {ExocoreGateway} from "../src/core/ExocoreGateway.sol";
import {GatewayStorage} from "../src/storage/GatewayStorage.sol";
import {Action, GatewayStorage} from "../src/storage/GatewayStorage.sol";

import {BaseScript} from "./BaseScript.sol";
import "forge-std/Script.sol";
Expand Down Expand Up @@ -51,8 +51,7 @@ contract SetPeersAndUpgrade is BaseScript {

vm.selectFork(exocore);
vm.startBroadcast(exocoreValidatorSet.privateKey);
uint256 nativeFee =
exocoreGateway.quote(clientChainId, abi.encodePacked(GatewayStorage.Action.REQUEST_MARK_BOOTSTRAP, ""));
uint256 nativeFee = exocoreGateway.quote(clientChainId, abi.encodePacked(Action.REQUEST_MARK_BOOTSTRAP, ""));
exocoreGateway.markBootstrap{value: nativeFee}(clientChainId);
}

Expand Down
4 changes: 2 additions & 2 deletions script/13_DepositValidator.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "../src/interfaces/IClientChainGateway.sol";
import "../src/interfaces/IExocoreGateway.sol";
import "../src/interfaces/IVault.sol";

import "../src/storage/GatewayStorage.sol";
import {Action, GatewayStorage} from "../src/storage/GatewayStorage.sol";
import "@beacon-oracle/contracts/src/EigenLayerBeaconOracle.sol";
import "@layerzero-v2/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol";
import "@layerzero-v2/protocol/contracts/libs/AddressCast.sol";
Expand Down Expand Up @@ -74,7 +74,7 @@ contract DepositScript is BaseScript {

vm.startBroadcast(depositor.privateKey);
bytes memory msg_ = abi.encodePacked(
GatewayStorage.Action.REQUEST_DEPOSIT,
Action.REQUEST_DEPOSIT_LST,
abi.encodePacked(bytes32(bytes20(VIRTUAL_STAKED_ETH_ADDRESS))),
abi.encodePacked(bytes32(bytes20(depositor.addr))),
uint256(_getEffectiveBalance(validatorContainer)) * GWEI_TO_WEI
Expand Down
6 changes: 2 additions & 4 deletions script/3_Setup.s.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pragma solidity ^0.8.19;

import {GatewayStorage} from "../src/storage/GatewayStorage.sol";
import {Action, GatewayStorage} from "../src/storage/GatewayStorage.sol";

import "../src/interfaces/IClientChainGateway.sol";
import "../src/interfaces/IExocoreGateway.sol";
Expand Down Expand Up @@ -121,9 +121,7 @@ contract SetupScript is BaseScript {
for (uint256 i = 0; i < whitelistTokensBytes32.length; i++) {
nativeFee = exocoreGateway.quote(
clientChainId,
abi.encodePacked(
GatewayStorage.Action.REQUEST_ADD_WHITELIST_TOKEN, abi.encodePacked(whitelistTokensBytes32[i])
)
abi.encodePacked(Action.REQUEST_ADD_WHITELIST_TOKEN, abi.encodePacked(whitelistTokensBytes32[i]))
);
exocoreGateway.addWhitelistToken{value: nativeFee}(
clientChainId,
Expand Down
4 changes: 2 additions & 2 deletions script/4_Deposit.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "../src/interfaces/IClientChainGateway.sol";

import "../src/interfaces/IExocoreGateway.sol";
import "../src/interfaces/IVault.sol";
import "../src/storage/GatewayStorage.sol";
import {Action, GatewayStorage} from "../src/storage/GatewayStorage.sol";

import {BaseScript} from "./BaseScript.sol";
import "@layerzero-v2/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol";
Expand Down Expand Up @@ -57,7 +57,7 @@ contract DepositScript is BaseScript {

function run() public {
bytes memory msg_ = abi.encodePacked(
GatewayStorage.Action.REQUEST_DEPOSIT,
Action.REQUEST_DEPOSIT_LST,
abi.encodePacked(bytes32(bytes20(address(restakeToken)))),
abi.encodePacked(bytes32(bytes20(depositor.addr))),
uint256(DEPOSIT_AMOUNT)
Expand Down
4 changes: 2 additions & 2 deletions script/5_Withdraw.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "../src/interfaces/IClientChainGateway.sol";
import "../src/interfaces/IExocoreGateway.sol";
import "../src/interfaces/IVault.sol";

import "../src/storage/GatewayStorage.sol";
import {Action, GatewayStorage} from "../src/storage/GatewayStorage.sol";

import {BaseScript} from "./BaseScript.sol";
import "@layerzero-v2/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol";
Expand Down Expand Up @@ -57,7 +57,7 @@ contract DepositScript is BaseScript {

function run() public {
bytes memory msg_ = abi.encodePacked(
GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE,
Action.REQUEST_WITHDRAW_LST,
abi.encodePacked(bytes32(bytes20(address(restakeToken)))),
abi.encodePacked(bytes32(bytes20(depositor.addr))),
uint256(WITHDRAW_AMOUNT)
Expand Down
6 changes: 3 additions & 3 deletions script/TestPrecompileErrorFixed.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import "../src/interfaces/IVault.sol";
import "../src/interfaces/precompiles/IAssets.sol";
import "../src/interfaces/precompiles/IClaimReward.sol";
import "../src/interfaces/precompiles/IDelegation.sol";
import "../src/storage/GatewayStorage.sol";
import {Action, GatewayStorage} from "../src/storage/GatewayStorage.sol";

import {NonShortCircuitEndpointV2Mock} from "../test/mocks/NonShortCircuitEndpointV2Mock.sol";
import {BaseScript} from "./BaseScript.sol";
Expand Down Expand Up @@ -73,7 +73,7 @@ contract DepositScript is BaseScript {

function run() public {
bytes memory depositMsg = abi.encodePacked(
GatewayStorage.Action.REQUEST_DEPOSIT,
Action.REQUEST_DEPOSIT_LST,
abi.encodePacked(bytes32(bytes20(address(restakeToken)))),
abi.encodePacked(bytes32(bytes20(depositor.addr))),
uint256(TEST_DEPOSIT_AMOUNT)
Expand All @@ -94,7 +94,7 @@ contract DepositScript is BaseScript {
vm.stopBroadcast();

bytes memory withdrawMsg = abi.encodePacked(
GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE,
Action.REQUEST_WITHDRAW_LST,
abi.encodePacked(bytes32(bytes20(address(restakeToken)))),
abi.encodePacked(bytes32(bytes20(depositor.addr))),
uint256(TEST_WITHDRAWAL_AMOUNT)
Expand Down
2 changes: 1 addition & 1 deletion script/TestPrecompileErrorFixed_Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "../src/interfaces/IClientChainGateway.sol";
import "../src/interfaces/IExocoreGateway.sol";
import "../src/interfaces/IVault.sol";

import "../src/storage/GatewayStorage.sol";
import {Action, GatewayStorage} from "../src/storage/GatewayStorage.sol";

import {NonShortCircuitEndpointV2Mock} from "../test/mocks/NonShortCircuitEndpointV2Mock.sol";
import {BaseScript} from "./BaseScript.sol";
Expand Down
19 changes: 11 additions & 8 deletions src/core/BaseRestakingController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {IExoCapsule} from "../interfaces/IExoCapsule.sol";
import {IVault} from "../interfaces/IVault.sol";
import {MessagingFee, MessagingReceipt, OAppSenderUpgradeable} from "../lzApp/OAppSenderUpgradeable.sol";
import {ClientChainGatewayStorage} from "../storage/ClientChainGatewayStorage.sol";
import {Action} from "../storage/GatewayStorage.sol";

import {OptionsBuilder} from "@layerzero-v2/oapp/contracts/oapp/libs/OptionsBuilder.sol";

Expand Down Expand Up @@ -40,7 +41,7 @@ abstract contract BaseRestakingController is
nonReentrant
{
require(recipient != address(0), "BaseRestakingController: recipient address cannot be empty or zero address");
if (token == VIRTUAL_STAKED_ETH_ADDRESS) {
if (token == VIRTUAL_NST_ADDRESS) {
IExoCapsule capsule = _getCapsule(msg.sender);
capsule.withdraw(amount, payable(recipient));
} else {
Expand All @@ -63,8 +64,7 @@ abstract contract BaseRestakingController is
{
bytes memory actionArgs =
abi.encodePacked(bytes32(bytes20(token)), bytes32(bytes20(msg.sender)), bytes(operator), amount);
bytes memory encodedRequest = abi.encode(token, msg.sender, operator, amount);
_processRequest(Action.REQUEST_DELEGATE_TO, actionArgs, encodedRequest);
_processRequest(Action.REQUEST_DELEGATE_TO, actionArgs, bytes(""));
}

/// @inheritdoc IBaseRestakingController
Expand All @@ -79,18 +79,21 @@ abstract contract BaseRestakingController is
{
bytes memory actionArgs =
abi.encodePacked(bytes32(bytes20(token)), bytes32(bytes20(msg.sender)), bytes(operator), amount);
bytes memory encodedRequest = abi.encode(token, msg.sender, operator, amount);
_processRequest(Action.REQUEST_UNDELEGATE_FROM, actionArgs, encodedRequest);
_processRequest(Action.REQUEST_UNDELEGATE_FROM, actionArgs, bytes(""));
}

/// @dev Processes the request by sending it to Exocore.
/// @dev If the encodedRequest is not empty, it is regarded as a request that expects a response and the request
/// would be cached
/// @param action The action to be performed.
/// @param actionArgs The encodePacked arguments for the action.
/// @param encodedRequest The encoded request.
/// @param encodedRequest The encoded request if the request expects a response.
function _processRequest(Action action, bytes memory actionArgs, bytes memory encodedRequest) internal {
uint64 requestNonce = _sendMsgToExocore(action, actionArgs);
_registeredRequests[requestNonce] = encodedRequest;
_registeredRequestActions[requestNonce] = action;
if (encodedRequest.length > 0) {
_registeredRequests[requestNonce] = encodedRequest;
_registeredRequestActions[requestNonce] = action;
}
}

/// @dev Sends a message to Exocore.
Expand Down
12 changes: 5 additions & 7 deletions src/core/Bootstrap.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import {ITokenWhitelister} from "../interfaces/ITokenWhitelister.sol";
import {IVault} from "../interfaces/IVault.sol";

import {Errors} from "../libraries/Errors.sol";

import {BootstrapStorage} from "../storage/BootstrapStorage.sol";
import {Action} from "../storage/GatewayStorage.sol";
import {BootstrapLzReceiver} from "./BootstrapLzReceiver.sol";

/// @title Bootstrap
Expand Down Expand Up @@ -213,7 +215,7 @@ contract Bootstrap is
// whitelist, it means that it is missing a vault. we do not need to check for a
// pre-existing vault. however, we still do ensure that the vault is not deployed
// for restaking natively staked ETH.
if (token != VIRTUAL_STAKED_ETH_ADDRESS) {
if (token != VIRTUAL_NST_ADDRESS) {
// setting a tvlLimit higher than the supply is permitted.
// it allows for some margin for minting of the token, and lets us use
// a value of type(uint256).max to indicate no limit.
Expand All @@ -234,7 +236,7 @@ contract Bootstrap is
if (!isWhitelistedToken[token]) {
revert Errors.TokenNotWhitelisted(token);
}
if (token == VIRTUAL_STAKED_ETH_ADDRESS) {
if (token == VIRTUAL_NST_ADDRESS) {
revert Errors.NoTvlLimitForNativeRestaking();
}
IVault vault = _getVault(token);
Expand Down Expand Up @@ -384,9 +386,6 @@ contract Bootstrap is
withdrawableAmounts[depositor][token] += amount;
depositsByToken[token] += amount;

// afterReceiveDepositResponse stores the TotalDepositAmount in the principal.
vault.updatePrincipalBalance(depositor, totalDepositAmounts[depositor][token]);

emit DepositResult(true, token, depositor, amount);
}

Expand Down Expand Up @@ -429,7 +428,6 @@ contract Bootstrap is
depositsByToken[token] -= amount;

// afterReceiveWithdrawPrincipalResponse
vault.updatePrincipalBalance(user, totalDepositAmounts[user][token]);
vault.updateWithdrawableBalance(user, amount, 0);

emit WithdrawPrincipalResult(true, token, user, amount);
Expand All @@ -438,7 +436,7 @@ contract Bootstrap is
/// @inheritdoc ILSTRestakingController
/// @dev This is not yet supported.
function withdrawRewardFromExocore(address, uint256) external payable override beforeLocked whenNotPaused {
revert NotYetSupported();
revert Errors.NotYetSupported();
}

/// @inheritdoc IBaseRestakingController
Expand Down
8 changes: 5 additions & 3 deletions src/core/BootstrapLzReceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
pragma solidity ^0.8.19;

import {Errors} from "../libraries/Errors.sol";

import {OAppReceiverUpgradeable, Origin} from "../lzApp/OAppReceiverUpgradeable.sol";
import {BootstrapStorage} from "../storage/BootstrapStorage.sol";
import {Action} from "../storage/GatewayStorage.sol";
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";

/// @title BootstrapLzReceiver
Expand All @@ -24,7 +26,7 @@ abstract contract BootstrapLzReceiver is PausableUpgradeable, OAppReceiverUpgrad
/// @inheritdoc OAppReceiverUpgradeable
function _lzReceive(Origin calldata _origin, bytes calldata payload) internal virtual override {
if (_origin.srcEid != EXOCORE_CHAIN_ID) {
revert UnexpectedSourceChain(_origin.srcEid);
revert Errors.UnexpectedSourceChain(_origin.srcEid);
}
_verifyAndUpdateNonce(_origin.srcEid, _origin.sender, _origin.nonce);
Action act = Action(uint8(payload[0]));
Expand All @@ -33,11 +35,11 @@ abstract contract BootstrapLzReceiver is PausableUpgradeable, OAppReceiverUpgrad
}
bytes4 selector_ = _whiteListFunctionSelectors[act];
if (selector_ == bytes4(0)) {
revert UnsupportedRequest(act);
revert Errors.UnsupportedRequest(act);
}
(bool success, bytes memory reason) = address(this).call(abi.encodePacked(selector_, abi.encode(payload[1:])));
if (!success) {
revert RequestOrResponseExecuteFailed(act, _origin.nonce, reason);
revert Errors.RequestOrResponseExecuteFailed(act, _origin.nonce, reason);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/core/ClientChainGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {LSTRestakingController} from "./LSTRestakingController.sol";
import {NativeRestakingController} from "./NativeRestakingController.sol";

import {Errors} from "../libraries/Errors.sol";
import {Action} from "../storage/GatewayStorage.sol";
import {IOAppCore} from "@layerzero-v2/oapp/contracts/oapp/interfaces/IOAppCore.sol";
import {OptionsBuilder} from "@layerzero-v2/oapp/contracts/oapp/libs/OptionsBuilder.sol";
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
Expand Down Expand Up @@ -128,7 +129,7 @@ contract ClientChainGateway is
// grave error, should never happen
revert Errors.TokenNotWhitelisted(token);
}
if (token == VIRTUAL_STAKED_ETH_ADDRESS) {
if (token == VIRTUAL_NST_ADDRESS) {
// not possible to set a TVL limit for native restaking
revert Errors.NoTvlLimitForNativeRestaking();
}
Expand Down
Loading
Loading