Skip to content

Commit

Permalink
refactor: merge Sent/Receive events
Browse files Browse the repository at this point in the history
  • Loading branch information
0xIryna committed Jan 21, 2025
1 parent bd66230 commit ba0e968
Show file tree
Hide file tree
Showing 6 changed files with 409 additions and 134 deletions.
52 changes: 38 additions & 14 deletions src/Portal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ abstract contract Portal is NttManagerNoRateLimiting, IPortal {
mapping(uint16 destinationChainId => mapping(bytes32 destinationToken => bool supported))
public supportedDestinationToken;

/// @inheritdoc IPortal
mapping(uint16 destinationChainId => bytes32 mToken) public destinationMToken;

/* ============ Constructor ============ */

/**
Expand Down Expand Up @@ -71,6 +74,15 @@ abstract contract Portal is NttManagerNoRateLimiting, IPortal {

/* ============ External Interactive Functions ============ */

/// @inheritdoc IPortal
function setDestinationMToken(uint16 destinationChainId_, bytes32 mToken_) external onlyOwner {
if (destinationChainId_ == chainId) revert InvalidDestinationChain(destinationChainId_);
if (mToken_ == bytes32(0)) revert ZeroMToken();

destinationMToken[destinationChainId_] = mToken_;
emit DestinationMTokenSet(destinationChainId_, mToken_);
}

/// @inheritdoc IPortal
function setSupportedDestinationToken(
uint16 destinationChainId_,
Expand Down Expand Up @@ -112,6 +124,8 @@ abstract contract Portal is NttManagerNoRateLimiting, IPortal {
// NOTE: the following code has been adapted from NTT manager `transfer` or `_transferEntryPoint` functions.
// We cannot call those functions directly here as they attempt to transfer M Token from the msg.sender.

_burnOrLock(amount_);

uint64 sequence_ = _useMessageSequence();
uint128 index_ = _currentIndex();

Expand All @@ -128,10 +142,10 @@ abstract contract Portal is NttManagerNoRateLimiting, IPortal {

uint256 totalPriceQuote_ = _sendMessage(destinationChainId_, refundAddress_, message_);

// Stack too deep
// Prevent stack too deep
uint256 transferAmount_ = amount_;

emit WrappedMTokenSent(
emit MTokenSent(
destinationChainId_,
sourceToken_,
destinationToken_,
Expand Down Expand Up @@ -166,18 +180,29 @@ abstract contract Portal is NttManagerNoRateLimiting, IPortal {
bytes32 // refundAddress
) internal override returns (TransceiverStructs.NativeTokenTransfer memory nativeTokenTransfer_) {
uint128 index_ = _currentIndex();
bytes32 destinationMToken_ = destinationMToken[destinationChainId_];
bytes32 messageId_;
(nativeTokenTransfer_, , messageId_) = _encodeTokenTransfer(
amount_,
index_,
recipient_,
token.toBytes32(),
destinationMToken_,
destinationChainId_,
sequence_,
sender_
);

emit MTokenSent(destinationChainId_, messageId_, sender_, recipient_, amount_.untrim(tokenDecimals()), index_);
uint256 untrimmedAmount_ = amount_.untrim(tokenDecimals());
emit MTokenSent(
destinationChainId_,
token,
destinationMToken_,
messageId_,
sender_,
recipient_,
untrimmedAmount_,
index_
);
}

function _encodeTokenTransfer(
Expand Down Expand Up @@ -277,23 +302,15 @@ abstract contract Portal is NttManagerNoRateLimiting, IPortal {
// NOTE: Assumes that token.decimals() are the same on all chains.
uint256 amount_ = trimmedAmount_.untrim(tokenDecimals());

emit MTokenReceived(sourceChainId_, destinationToken_, messageId_, sender_, recipient_, amount_, index_);

// Emitting `INttManager.TransferRedeemed` to comply with Wormhole NTT specification.
emit TransferRedeemed(messageId_);

if (destinationToken_ == token) {
emit MTokenReceived(sourceChainId_, messageId_, sender_, recipient_, amount_, index_);
// mints or unlocks M Token to the recipient
_mintOrUnlock(recipient_, amount_, index_);
} else {
emit WrappedMTokenReceived(
sourceChainId_,
destinationToken_,
messageId_,
sender_,
recipient_,
amount_,
index_
);
// mints or unlocks M Token to the Portal
_mintOrUnlock(address(this), amount_, index_);

Expand Down Expand Up @@ -341,6 +358,13 @@ abstract contract Portal is NttManagerNoRateLimiting, IPortal {
*/
function _mintOrUnlock(address recipient_, uint256 amount_, uint128 index_) internal virtual {}

/**
* @dev HubPortal: locks amount_` M tokens.
* SpokePortal: burns `amount_` M tokens.
* @param amount_ The amount of M tokens to lock/burn.
*/
function _burnOrLock(uint256 amount_) internal virtual {}

/// @dev Returns the current M token index used by the Portal.
function _currentIndex() internal view virtual returns (uint128) {}
}
8 changes: 8 additions & 0 deletions src/SpokePortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ contract SpokePortal is ISpokePortal, Portal {
}
}

/**
* @dev Burns M Token.
* @param amount_ The amount of M Token to mint to the recipient.
*/
function _burnOrLock(uint256 amount_) internal override {
ISpokeMTokenLike(token).burn(amount_);
}

/// @dev Returns the current M token index used by the Spoke Portal.
function _currentIndex() internal view override returns (uint128) {
return ISpokeMTokenLike(mToken()).currentIndex();
Expand Down
63 changes: 24 additions & 39 deletions src/interfaces/IPortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,6 @@ interface IPortal {
/**
* @notice Emitted when M token is sent to a destination chain.
* @param destinationChainId The Wormhole destination chain ID.
* @param messageId The unique identifier for the sent message.
* @param sender The address that bridged the M tokens via the Portal.
* @param recipient The account receiving tokens on destination chain.
* @param amount The amount of tokens.
* @param index The M token index.
*/
event MTokenSent(
uint16 indexed destinationChainId,
bytes32 messageId,
address indexed sender,
bytes32 indexed recipient,
uint256 amount,
uint128 index
);

/**
* @notice Emitted when Wrapped M token is sent to a destination chain.
* @param destinationChainId The Wormhole destination chain ID.
* @param sourceToken The address of the token on the source chain.
* @param destinationToken The address of the token on the destination chain.
* @param messageId The unique identifier for the sent message.
Expand All @@ -38,7 +20,7 @@ interface IPortal {
* @param amount The amount of tokens.
* @param index The M token index.
*/
event WrappedMTokenSent(
event MTokenSent(
uint16 destinationChainId,
address indexed sourceToken,
bytes32 destinationToken,
Expand All @@ -51,24 +33,6 @@ interface IPortal {

/**
* @notice Emitted when M token is received from a source chain.
* @param sourceChainId The Wormhole source chain ID.
* @param messageId The unique identifier for the received message.
* @param sender The account sending tokens.
* @param recipient The account receiving tokens.
* @param amount The amount of tokens.
* @param index The M token index.
*/
event MTokenReceived(
uint16 indexed sourceChainId,
bytes32 messageId,
bytes32 indexed sender,
address indexed recipient,
uint256 amount,
uint128 index
);

/**
* @notice Emitted when Wrapped M token is received from a source chain.
* @param sourceChainId The Wormhole source chain ID.
* @param destinationToken The address of the token on the destination chain.
* @param messageId The unique identifier for the received message.
Expand All @@ -77,7 +41,7 @@ interface IPortal {
* @param amount The amount of tokens.
* @param index The M token index.
*/
event WrappedMTokenReceived(
event MTokenReceived(
uint16 sourceChainId,
address indexed destinationToken,
bytes32 messageId,
Expand All @@ -95,6 +59,13 @@ interface IPortal {
*/
event WrapFailed(address indexed destinationWrappedToken, address indexed recipient, uint256 amount);

/**
* @notice Emitted when M token is set for the remote chain.
* @param destinationChainId The Wormhole destination chain ID.
* @param mToken The address of M token on the destination chain.
*/
event DestinationMTokenSet(uint16 indexed destinationChainId, bytes32 mToken);

/**
* @notice Emitted when a supported token is set for the remote chain.
* @param destinationChainId The Wormhole destination chain ID.
Expand Down Expand Up @@ -143,6 +114,13 @@ interface IPortal {
/// @notice The address of the Registrar contract.
function registrar() external view returns (address);

/**
* @notice Returns the address of M token the destination chain.
* @param destinationChainId The Wormhole destination chain ID.
* @return mToken The address of M token the destination chain.
*/
function destinationMToken(uint16 destinationChainId) external view returns (bytes32 mToken);

/**
* @notice Indicates whether the provided token is supported on the destination chain.
* @param destinationChainId The Wormhole destination chain ID.
Expand All @@ -156,6 +134,13 @@ interface IPortal {

/* ============ Interactive Functions ============ */

/**
* @notice Sets M token address on the remote chain.
* @param destinationChainId The Wormhole destination chain ID.
* @param mToken The address of M token on the destination chain.
*/
function setDestinationMToken(uint16 destinationChainId, bytes32 mToken) external;

/**
* @notice Sets whether the token is supported on the remote chain.
* @param destinationChainId The Wormhole destination chain ID.
Expand All @@ -165,7 +150,7 @@ interface IPortal {
function setSupportedDestinationToken(uint16 destinationChainId, bytes32 destinationToken, bool supported) external;

/**
* @notice Transfers Wrapped M Token to the destination chain.
* @notice Transfers M or Wrapped M Token to the destination chain.
* @param amount The amount of tokens to transfer.
* @param sourceToken The address of the token (M or Wrapped M) on the source chain.
* @param destinationToken The address of the token (M or Wrapped M) on the destination chain.
Expand Down
Loading

0 comments on commit ba0e968

Please sign in to comment.