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(storage): common inbound nonce #40

Merged
merged 6 commits into from
Jul 1, 2024
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
2 changes: 1 addition & 1 deletion docs/architecture.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/lst-flow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 1 addition & 8 deletions src/core/BootstrapLzReceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ abstract contract BootstrapLzReceiver is PausableUpgradeable, OAppReceiverUpgrad
if (_origin.srcEid != EXOCORE_CHAIN_ID) {
revert UnexpectedSourceChain(_origin.srcEid);
}
_consumeInboundNonce(_origin.srcEid, _origin.sender, _origin.nonce);
_verifyAndUpdateNonce(_origin.srcEid, _origin.sender, _origin.nonce);
Action act = Action(uint8(payload[0]));
require(act != Action.RESPOND, "BootstrapLzReceiver: invalid action");
bytes4 selector_ = _whiteListFunctionSelectors[act];
Expand All @@ -41,11 +41,4 @@ abstract contract BootstrapLzReceiver is PausableUpgradeable, OAppReceiverUpgrad
return inboundNonce[srcEid][sender] + 1;
}

function _consumeInboundNonce(uint32 srcEid, bytes32 sender, uint64 nonce) internal {
inboundNonce[srcEid][sender] += 1;
if (nonce != inboundNonce[srcEid][sender]) {
revert UnexpectedInboundNonce(inboundNonce[srcEid][sender], nonce);
}
}

}
9 changes: 1 addition & 8 deletions src/core/ClientGatewayLzReceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ abstract contract ClientGatewayLzReceiver is PausableUpgradeable, OAppReceiverUp
revert UnexpectedSourceChain(_origin.srcEid);
}

_consumeInboundNonce(_origin.srcEid, _origin.sender, _origin.nonce);
_verifyAndUpdateNonce(_origin.srcEid, _origin.sender, _origin.nonce);

Action act = Action(uint8(payload[0]));
if (act == Action.RESPOND) {
Expand Down Expand Up @@ -75,13 +75,6 @@ abstract contract ClientGatewayLzReceiver is PausableUpgradeable, OAppReceiverUp
return inboundNonce[srcEid][sender] + 1;
}

function _consumeInboundNonce(uint32 srcEid, bytes32 sender, uint64 nonce) internal {
inboundNonce[srcEid][sender] += 1;
if (nonce != inboundNonce[srcEid][sender]) {
revert UnexpectedInboundNonce(inboundNonce[srcEid][sender], nonce);
}
}

function afterReceiveDepositResponse(bytes memory requestPayload, bytes calldata responsePayload)
public
onlyCalledFromThis
Expand Down
9 changes: 1 addition & 8 deletions src/core/ExocoreGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ contract ExocoreGateway is
}

function _lzReceive(Origin calldata _origin, bytes calldata payload) internal virtual override whenNotPaused {
_consumeInboundNonce(_origin.srcEid, _origin.sender, _origin.nonce);
_verifyAndUpdateNonce(_origin.srcEid, _origin.sender, _origin.nonce);

Action act = Action(uint8(payload[0]));
bytes4 selector_ = _whiteListFunctionSelectors[act];
Expand Down Expand Up @@ -350,11 +350,4 @@ contract ExocoreGateway is
return inboundNonce[srcEid][sender] + 1;
}

function _consumeInboundNonce(uint32 srcEid, bytes32 sender, uint64 nonce) internal {
inboundNonce[srcEid][sender] += 1;
if (nonce != inboundNonce[srcEid][sender]) {
revert UnexpectedInboundNonce(inboundNonce[srcEid][sender], nonce);
}
}

}
16 changes: 0 additions & 16 deletions src/storage/BootstrapStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -206,22 +206,6 @@ contract BootstrapStorage is GatewayStorage {
*/
uint32 public immutable EXOCORE_CHAIN_ID;

/**
* @dev A mapping of source chain id to source sender to the nonce of the last inbound
* message processed from that sender, over LayerZero.
* @notice This mapping is used to track the last message processed from each sender on
* each source chain to prevent replay attacks.
*/
mapping(uint32 eid => mapping(bytes32 sender => uint64 nonce)) public inboundNonce;

// TSS information.
/**
* @dev The message nonce from the last TSS message processed by the contract.
* @notice This nonce is used to track the last message processed by the contract to
* prevent replay attacks.
*/
uint256 public lastMessageNonce;
adu-web3 marked this conversation as resolved.
Show resolved Hide resolved

// the beacon that stores the Vault implementation contract address for proxy
/**
* @notice this stores the Vault implementation contract address for proxy, and it is
Expand Down
3 changes: 1 addition & 2 deletions src/storage/ClientChainGatewayStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ pragma solidity ^0.8.19;
import {IETHPOSDeposit} from "../interfaces/IETHPOSDeposit.sol";
import {IExoCapsule} from "../interfaces/IExoCapsule.sol";
import {BootstrapStorage} from "../storage/BootstrapStorage.sol";
import {BootstrapStorage} from "./BootstrapStorage.sol";

import {IBeacon} from "@openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol";

Expand All @@ -13,7 +12,7 @@ contract ClientChainGatewayStorage is BootstrapStorage {
/* state variables exclusively owned by ClientChainGateway */
/* -------------------------------------------------------------------------- */

uint64 public outboundNonce;
uint64 public outboundNonce; // the only contract that has outgoing messages
MaxMustermann2 marked this conversation as resolved.
Show resolved Hide resolved
mapping(address => IExoCapsule) public ownerToCapsule;
mapping(uint64 => bytes) internal _registeredRequests;
mapping(uint64 => Action) internal _registeredRequestActions;
Expand Down
1 change: 0 additions & 1 deletion src/storage/ExocoreGatewayStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ contract ExocoreGatewayStorage is GatewayStorage {
uint128 internal constant DESTINATION_GAS_LIMIT = 500_000;
uint128 internal constant DESTINATION_MSG_VALUE = 0;

mapping(uint32 eid => mapping(bytes32 sender => uint64 nonce)) public inboundNonce;
mapping(uint32 id => bool) public chainToBootstrapped;

event ExocorePrecompileError(address indexed precompile, uint64 nonce);
Expand Down
10 changes: 10 additions & 0 deletions src/storage/GatewayStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ contract GatewayStorage {
mapping(Action => bytes4) internal _whiteListFunctionSelectors;
address payable public exocoreValidatorSetAddress;

mapping(uint32 eid => mapping(bytes32 sender => uint64 nonce)) public inboundNonce;

event MessageSent(Action indexed act, bytes32 packetId, uint64 nonce, uint256 nativeFee);

error UnsupportedRequest(Action act);
Expand All @@ -25,4 +27,12 @@ contract GatewayStorage {

uint256[40] private __gap;

function _verifyAndUpdateNonce(uint32 srcChainId, bytes32 srcAddress, uint64 nonce) internal {
uint64 expectedNonce = inboundNonce[srcChainId][srcAddress] + 1;
if (nonce != expectedNonce) {
revert UnexpectedInboundNonce(expectedNonce, nonce);
}
inboundNonce[srcChainId][srcAddress] = nonce;
}

}
9 changes: 1 addition & 8 deletions test/mocks/ExocoreGatewayMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ contract ExocoreGatewayMock is
}

function _lzReceive(Origin calldata _origin, bytes calldata payload) internal virtual override whenNotPaused {
_consumeInboundNonce(_origin.srcEid, _origin.sender, _origin.nonce);
_verifyAndUpdateNonce(_origin.srcEid, _origin.sender, _origin.nonce);

Action act = Action(uint8(payload[0]));
bytes4 selector_ = _whiteListFunctionSelectors[act];
Expand Down Expand Up @@ -341,11 +341,4 @@ contract ExocoreGatewayMock is
return inboundNonce[srcEid][sender] + 1;
}

function _consumeInboundNonce(uint32 srcEid, bytes32 sender, uint64 nonce) internal {
inboundNonce[srcEid][sender] += 1;
if (nonce != inboundNonce[srcEid][sender]) {
revert UnexpectedInboundNonce(inboundNonce[srcEid][sender], nonce);
}
}

}
Loading