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

evm: natspec changes and additions #249

Merged
merged 9 commits into from
Mar 6, 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
17 changes: 17 additions & 0 deletions evm/src/NttManager/NttManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ import "../interfaces/ITransceiver.sol";

import {NttManagerState} from "./NttManagerState.sol";

/// @title NttManager
/// @author Wormhole Project Contributors.
/// @notice The NttManager contract is responsible for managing the token
/// and associated transceivers.
///
/// @dev Each NttManager contract is associated with a single token but
/// can be responsible for multiple transceivers.
///
/// @dev When transferring tokens, the NttManager contract will either
/// lock the tokens or burn them, depending on the mode.
///
/// @dev To initiate a transfer, the user calls the transfer function with:
/// - the amount
/// - the recipient chain
/// - the recipient address
/// - (optional) a flag to indicate whether the transfer should be queued
/// if the rate limit is exceeded
contract NttManager is INttManager, NttManagerState {
using BytesParsing for bytes;
using SafeERC20 for IERC20;
Expand Down
31 changes: 30 additions & 1 deletion evm/src/NttManager/TransceiverRegistry.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
// SPDX-License-Identifier: Apache 2
pragma solidity >=0.8.8 <0.9.0;

/// @dev This contract is responsible for handling the registration of Transceivers.
/// @title TransceiverRegistry
/// @author Wormhole Project Contributors.
/// @notice This contract is responsible for handling the registration of Transceivers.
/// @dev This contract checks that a few critical invariants hold when transceivers are added or removed,
/// including:
/// 1. If a transceiver is not registered, it should be enabled.
/// 2. The value set in the bitmap of trannsceivers
/// should directly correspond to the whether the transceiver is enabled
abstract contract TransceiverRegistry {
constructor() {
_checkTransceiversInvariants();
Expand Down Expand Up @@ -33,11 +40,33 @@ abstract contract TransceiverRegistry {

uint8 constant MAX_TRANSCEIVERS = 64;

/// @notice Error when the caller is not the transceiver.
/// @dev Selector 0xa0ae911d.
/// @param caller The address of the caller.
error CallerNotTransceiver(address caller);

/// @notice Error when the transceiver is the zero address.
/// @dev Selector 0x2f44bd77.
error InvalidTransceiverZeroAddress();

/// @notice Error when the transceiver is disabled.
/// @dev Selector 0x1f61ba44.
error DisabledTransceiver(address transceiver);

/// @notice Error when the number of registered transceivers
/// exceeeds (MAX_TRANSCEIVERS = 64).
/// @dev Selector 0x891684c3.
error TooManyTransceivers();

/// @notice Error when attempting to remove a transceiver
/// that is not registered.
/// @dev Selector 0xd583f470.
/// @param transceiver The address of the transceiver.
error NonRegisteredTransceiver(address transceiver);

/// @notice Error when attempting to enable a transceiver that is already enabled.
/// @dev Selector 0x8d68f84d.
/// @param transceiver The address of the transceiver.
error TransceiverAlreadyEnabled(address transceiver);

modifier onlyTransceiver() {
Expand Down
9 changes: 9 additions & 0 deletions evm/src/Transceiver/Transceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ import "../libraries/Implementation.sol";
import "../interfaces/INttManager.sol";
import "../interfaces/ITransceiver.sol";

/// @title Transceiver
/// @author Wormhole Project Contributors.
/// @notice This contract is a base contract for Transceivers.
/// @dev The Transceiver provides basic functionality for transmitting / receiving NTT messages.
/// The contract supports pausing via an admin or owner and is upgradable.
///
/// @dev The interface for receiving messages is not enforced by this contract.
/// Instead, inheriting contracts should implement their own receiving logic,
/// based on the verification model and serde logic associated with message handling.
abstract contract Transceiver is
ITransceiver,
PausableOwnable,
Expand Down
12 changes: 12 additions & 0 deletions evm/src/Transceiver/WormholeTransceiver/WormholeTransceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ import "../../interfaces/INttManager.sol";

import "./WormholeTransceiverState.sol";

/// @title WormholeTransceiver
/// @author Wormhole Project Contributors.
/// @notice Transceiver implementation for Wormhole.
///
/// @dev This contract is responsible for sending and receiving NTT messages
/// that are authenticated through Wormhole Core.
///
/// @dev Messages can be delivered either via standard relaying or special relaying, or
/// manually via the core layer.
///
/// @dev Once a message is received, it is delivered to its corresponding
/// NttManager contract.
contract WormholeTransceiver is
IWormholeTransceiver,
IWormholeReceiver,
Expand Down
69 changes: 52 additions & 17 deletions evm/src/interfaces/INttManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@ import "../libraries/TransceiverStructs.sol";
import "./INttManagerState.sol";

interface INttManager is INttManagerState {
/// @notice The mode is either LOCKING or BURNING. In LOCKING mode, the NttManager locks the
/// tokens of the sender and mints an equivalent amount on the target chain. In BURNING
/// mode, the NttManager burns the tokens of the sender and mints an equivalent amount
/// on the target chain.LOCKING mode preserves the total supply of the tokens.
enum Mode {
LOCKING,
BURNING
}

// @dev Information about attestations for a given message.
/// @notice Information about attestations for a given message.
/// @dev The fields are as follows:
/// - executed: whether the message has been executed.
/// - attested: bitmap of transceivers that have attested to this message.
/// (NOTE: might contain disabled transceivers)
struct AttestationInfo {
// whether this message has been executed
bool executed;
// bitmap of transceivers that have attested to this message (NOTE: might contain disabled transceivers)
uint64 attestedTransceivers;
}

Expand All @@ -34,27 +40,56 @@ interface INttManager is INttManagerState {
error DeliveryPaymentTooLow(uint256 requiredPayment, uint256 providedPayment);

//// @notice The transfer has some dust.
//// @dev This is a security measure to prevent users from losing funds.
//// This is the result of trimming the amount and then untrimming it.
//// @dev This is a security measure to prevent users from losing funds.
//// This is the result of trimming the amount and then untrimming it.
//// @param amount The amount to transfer.
error TransferAmountHasDust(uint256 amount, uint256 dust);

/// @notice The mode is invalid. It is neither in LOCKING or BURNING mode.
/// @param mode The mode.
error InvalidMode(uint8 mode);

/// @notice Error when the refund to the sender fails.
/// @dev Selector 0x2ca23714.
/// @param refundAmount The refund amount.
error RefundFailed(uint256 refundAmount);

/// @notice Error when the tranceiver already attested to the message.
/// To ensure the client does not continue to initiate calls to the attestationReceived function.
/// @dev Selector 0x2113894.
/// @param nttManagerMessageHash The hash of the message.
error TransceiverAlreadyAttestedToMessage(bytes32 nttManagerMessageHash);

/// @notice Error when the message is not approved.
/// @dev Selector 0x451c4fb0.
/// @param msgHash The hash of the message.
error MessageNotApproved(bytes32 msgHash);

/// @notice Error when trying to execute a message on an unintended target chain.
/// @dev Selector 0x3dcb204a.
/// @param targetChain The target chain.
/// @param thisChain The current chain.
error InvalidTargetChain(uint16 targetChain, uint16 thisChain);

/// @notice Error when the transfer amount is zero.
/// @dev Selector 0x9993626a.
error ZeroAmount();

/// @notice Error when the recipient is invalid.
/// @dev Selector 0x9c8d2cd2.
error InvalidRecipient();

/// @notice Error when the amount burned is different than the balance difference,
/// since NTT does not support burn fees.
/// @dev Selector 0x02156a8f.
/// @param burnAmount The amount burned.
/// @param balanceDiff The balance after burning.
error BurnAmountDifferentThanBalanceDiff(uint256 burnAmount, uint256 balanceDiff);

/// @notice Transfer a given amount to a recipient on a given chain. This function is called
/// by the user to send the token cross-chain. This function will either lock or burn the
/// sender's tokens. Finally, this function will call into registered `Endpoint` contracts
/// to send a message with the incrementing sequence number and the token transfer payload.
/// by the user to send the token cross-chain. This function will either lock or burn the
/// sender's tokens. Finally, this function will call into registered `Endpoint` contracts
/// to send a message with the incrementing sequence number and the token transfer payload.
/// @param amount The amount to transfer.
/// @param recipientChain The chain ID for the destination.
/// @param recipient The recipient address.
Expand All @@ -65,9 +100,9 @@ interface INttManager is INttManagerState {
) external payable returns (uint64 msgId);

/// @notice Transfer a given amount to a recipient on a given chain. This function is called
/// by the user to send the token cross-chain. This function will either lock or burn the
/// sender's tokens. Finally, this function will call into registered `Endpoint` contracts
/// to send a message with the incrementing sequence number and the token transfer payload.
/// by the user to send the token cross-chain. This function will either lock or burn the
/// sender's tokens. Finally, this function will call into registered `Endpoint` contracts
/// to send a message with the incrementing sequence number and the token transfer payload.
/// @dev Transfers are queued if the outbound limit is hit and must be completed by the client.
/// @param amount The amount to transfer.
/// @param recipientChain The chain ID for the destination.
Expand Down Expand Up @@ -106,8 +141,8 @@ interface INttManager is INttManagerState {

/// @notice Called by an Endpoint contract to deliver a verified attestation.
/// @dev This function enforces attestation threshold and replay logic for messages. Once all
/// validations are complete, this function calls `executeMsg` to execute the command specified
/// by the message.
/// validations are complete, this function calls `executeMsg` to execute the command specified
/// by the message.
/// @param sourceChainId The chain id of the sender.
/// @param sourceNttManagerAddress The address of the sender's nttManager contract.
/// @param payload The VAA payload.
Expand All @@ -117,11 +152,11 @@ interface INttManager is INttManagerState {
TransceiverStructs.NttManagerMessage memory payload
) external;

/// @notice Called after a message has been sufficiently verified to execute the command in the message.
/// This function will decode the payload as an NttManagerMessage to extract the sequence, msgType,
/// and other parameters.
/// @notice Called after a message has been sufficiently verified to execute
/// the command in the message. This function will decode the payload
/// as an NttManagerMessage to extract the sequence, msgType, and other parameters.
/// @dev This function is exposed as a fallback for when an `Transceiver` is deregistered
/// when a message is in flight.
/// when a message is in flight.
/// @param sourceChainId The chain id of the sender.
/// @param sourceNttManagerAddress The address of the sender's nttManager contract.
/// @param message The message to execute.
Expand Down
28 changes: 26 additions & 2 deletions evm/src/interfaces/ITransceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,44 @@ import "../libraries/TransceiverStructs.sol";

interface ITransceiver {
/// @notice The caller is not the deployer.
/// @dev Selector: 0xc68a0e42.
/// @param deployer The address of the deployer.
/// @param caller The address of the caller.
error UnexpectedDeployer(address deployer, address caller);

/// @notice The caller is not the NttManager.
/// @dev Selector: 0xc5aa6153.
/// @param caller The address of the caller.
error CallerNotNttManager(address caller);

/// @notice Error when trying renounce transceiver ownership.
/// Ensures the owner of the transceiver is in sync with
/// the owner of the NttManager.
/// @dev Selector: 0x66791dd6.
/// @param currentOwner he current owner of the transceiver.
error CannotRenounceTransceiverOwnership(address currentOwner);

/// @notice Error when trying to transfer transceiver ownership.
/// @dev Selector: 0x306239eb.
/// @param currentOwner The current owner of the transceiver.
/// @param newOwner The new owner of the transceiver.
error CannotTransferTransceiverOwnership(address currentOwner, address newOwner);

/// @notice Error when the recipient NttManager address is not the
/// corresponding manager of the transceiver.
/// @dev Selector: 0x73bdd322.
/// @param recipientNttManagerAddress The address of the recipient NttManager.
/// @param expectedRecipientNttManagerAddress The expected address of the recipient NttManager.
error UnexpectedRecipientNttManagerAddress(
bytes32 recipientNttManagerAddress, bytes32 expectedRecipientNttManagerAddress
);

/// @notice Fetch the delivery price for a given recipient chain transfer.
/// @param recipientChain The Wormhole chain ID of the target chain.
/// @param instruction An additional Instruction provided by the Transceiver to be
/// executed on the recipient chain.
/// executed on the recipient chain.
/// @return deliveryPrice The cost of delivering a message to the recipient chain,
/// in this chain's native token.
/// in this chain's native token.
function quoteDeliveryPrice(
uint16 recipientChain,
TransceiverStructs.TransceiverInstruction memory instruction
Expand Down
43 changes: 39 additions & 4 deletions evm/src/interfaces/IWormholeTransceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,64 @@ import "../libraries/TransceiverStructs.sol";
import "./IWormholeTransceiverState.sol";

interface IWormholeTransceiver is IWormholeTransceiverState {
/// @notice The instruction for the WormholeTransceiver contract
/// to skip delivery via the relayer.
struct WormholeTransceiverInstruction {
bool shouldSkipRelayerSend;
}

/// @notice Emitted when a relayed message is received.
/// @dev Topic0
/// 0xf557dbbb087662f52c815f6c7ee350628a37a51eae9608ff840d996b65f87475
/// @param digest The digest of the message.
/// @param emitterChainId The chain ID of the emitter.
/// @param emitterAddress The address of the emitter.
event ReceivedRelayedMessage(bytes32 digest, uint16 emitterChainId, bytes32 emitterAddress);

/// @notice Emitted when a message is received.
/// @dev Topic0
/// 0xf6fc529540981400dc64edf649eb5e2e0eb5812a27f8c81bac2c1d317e71a5f0.
/// @param digest The digest of the message.
/// @param emitterChainId The chain ID of the emitter.
/// @param emitterAddress The address of the emitter.
/// @param sequence The sequence of the message.
event ReceivedMessage(
bytes32 digest, uint16 emitterChainId, bytes32 emitterAddress, uint64 sequence
);

/// @notice Emitted when a message is sent from the transceiver.
/// @dev Topic0
/// 0x53b3e029c5ead7bffc739118953883859d30b1aaa086e0dca4d0a1c99cd9c3f5.
/// @param recipientChain The chain ID of the recipient.
/// @param message The message.
event SendTransceiverMessage(
uint16 recipientChain, TransceiverStructs.TransceiverMessage message
);

/// @notice Error when the relaying configuration is invalid. (e.g. chainId is not registered)
/// @dev Selector: 0x9449a36c.
/// @param chainId The chain ID that is invalid.
error InvalidRelayingConfig(uint16 chainId);

/// @notice Error when the peer transceiver is invalid.
/// @dev Selector: 0x79b1ce56.
/// @param chainId The chain ID of the peer.
/// @param peerAddress The address of the invalid peer.
error InvalidWormholePeer(uint16 chainId, bytes32 peerAddress);

/// @notice Error when the VAA has already been consumed.
/// @dev Selector: 0x406e719e.
/// @param vaaHash The hash of the VAA.
error TransferAlreadyCompleted(bytes32 vaaHash);

/// @notice Receive an attested message from the verification layer. This function should verify
/// the `encodedVm` and then deliver the attestation to the transceiver NttManager contract.
/// @notice Receive an attested message from the verification layer.
/// This function should verify the `encodedVm` and then deliver the attestation
/// to the transceiver NttManager contract.
/// @param encodedMessage The attested message.
function receiveMessage(bytes memory encodedMessage) external;

/// @notice Parses the encoded instruction and returns the instruction struct. This instruction
/// is specific to the WormholeTransceiver contract.
/// @notice Parses the encoded instruction and returns the instruction struct.
/// This instruction is specific to the WormholeTransceiver contract.
/// @param encoded The encoded instruction.
/// @return instruction The parsed `WormholeTransceiverInstruction`.
function parseWormholeTransceiverInstruction(bytes memory encoded)
Expand Down
Loading
Loading