Description:
Multi-signature wallet contract requiring multiple confirmations for transaction execution.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"@wormhole-ntt/interfaces/IManagerBase.sol": {
"content": "// SPDX-License-Identifier: Apache 2
pragma solidity >=0.8.8 <0.9.0;
import "../libraries/TransceiverStructs.sol";
interface IManagerBase {
/// @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
}
/// @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 {
bool executed;
uint64 attestedTransceivers;
}
struct _Sequence {
uint64 num;
}
struct _Threshold {
uint8 num;
}
/// @notice Emitted when a message has been attested to.
/// @dev Topic0
/// 0x35a2101eaac94b493e0dfca061f9a7f087913fde8678e7cde0aca9897edba0e5.
/// @param digest The digest of the message.
/// @param transceiver The address of the transceiver.
/// @param index The index of the transceiver in the bitmap.
event MessageAttestedTo(bytes32 digest, address transceiver, uint8 index);
/// @notice Emmitted when the threshold required transceivers is changed.
/// @dev Topic0
/// 0x2a855b929b9a53c6fb5b5ed248b27e502b709c088e036a5aa17620c8fc5085a9.
/// @param oldThreshold The old threshold.
/// @param threshold The new threshold.
event ThresholdChanged(uint8 oldThreshold, uint8 threshold);
/// @notice Emitted when an transceiver is removed from the nttManager.
/// @dev Topic0
/// 0xf05962b5774c658e85ed80c91a75af9d66d2af2253dda480f90bce78aff5eda5.
/// @param transceiver The address of the transceiver.
/// @param transceiversNum The current number of transceivers.
/// @param threshold The current threshold of transceivers.
event TransceiverAdded(address transceiver, uint256 transceiversNum, uint8 threshold);
/// @notice Emitted when an transceiver is removed from the nttManager.
/// @dev Topic0
/// 0x697a3853515b88013ad432f29f53d406debc9509ed6d9313dcfe115250fcd18f.
/// @param transceiver The address of the transceiver.
/// @param threshold The current threshold of transceivers.
event TransceiverRemoved(address transceiver, uint8 threshold);
/// @notice payment for a transfer is too low.
/// @param requiredPayment The required payment.
/// @param providedPayment The provided payment.
error DeliveryPaymentTooLow(uint256 requiredPayment, uint256 providedPayment);
/// @notice Error when the refund to the sender fails.
/// @dev Selector 0x2ca23714.
/// @param refundAmount The refund amount.
error RefundFailed(uint256 refundAmount);
/// @notice The number of thresholds should not be zero.
error ZeroThreshold();
error RetrievedIncorrectRegisteredTransceivers(uint256 retrieved, uint256 registered);
/// @notice The threshold for transceiver attestations is too high.
/// @param threshold The threshold.
/// @param transceivers The number of transceivers.
error ThresholdTooHigh(uint256 threshold, uint256 transceivers);
/// @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 Emitted when a message has already been executed to
/// notify client of against retries.
/// @dev Topic0
/// 0x4069dff8c9df7e38d2867c0910bd96fd61787695e5380281148c04932d02bef2.
/// @param sourceNttManager The address of the source nttManager.
/// @param msgHash The keccak-256 hash of the message.
event MessageAlreadyExecuted(bytes32 indexed sourceNttManager, bytes32 indexed msgHash);
/// @notice There are no transceivers enabled with the Manager
/// @dev Selector 0x69cf632a
error NoEnabledTransceivers();
/// @notice Error when the manager doesn't have a peer registered for the destination chain
/// @dev Selector 0x3af256bc.
/// @param chainId The target Wormhole chain id
error PeerNotRegistered(uint16 chainId);
/// @notice Fetch the delivery price for a given recipient chain transfer.
/// @param recipientChain The Wormhole chain ID of the transfer destination.
/// @param transceiverInstructions The transceiver specific instructions for quoting and sending
/// @return - The delivery prices associated with each enabled endpoint and the total price.
function quoteDeliveryPrice(
uint16 recipientChain,
bytes memory transceiverInstructions
) external view returns (uint256[] memory, uint256);
/// @notice Sets the threshold for the number of attestations required for a message
/// to be considered valid.
/// @param threshold The new threshold (number of attestations).
/// @dev This method can only be executed by the `owner`.
function setThreshold(
uint8 threshold
) external;
/// @notice Sets the transceiver for the given chain.
/// @param transceiver The address of the transceiver.
/// @dev This method can only be executed by the `owner`.
function setTransceiver(
address transceiver
) external;
/// @notice Removes the transceiver for the given chain.
/// @param transceiver The address of the transceiver.
/// @dev This method can only be executed by the `owner`.
function removeTransceiver(
address transceiver
) external;
/// @notice Checks if a message has been approved. The message should have at least
/// the minimum threshold of attestations from distinct endpoints.
/// @param digest The digest of the message.
/// @return - Boolean indicating if message has been approved.
function isMessageApproved(
bytes32 digest
) external view returns (bool);
/// @notice Checks if a message has been executed.
/// @param digest The digest of the message.
/// @return - Boolean indicating if message has been executed.
function isMessageExecuted(
bytes32 digest
) external view returns (bool);
/// @notice Returns the next message sequence.
function nextMessageSequence() external view returns (uint64);
/// @notice Upgrades to a new manager implementation.
/// @dev This is upgraded via a proxy, and can only be executed
/// by the `owner`.
/// @param newImplementation The address of the new implementation.
function upgrade(
address newImplementation
) external;
/// @notice Pauses the manager.
function pause() external;
/// @notice Returns the mode (locking or burning) of the NttManager.
/// @return mode A uint8 corresponding to the mode
function getMode() external view returns (uint8);
/// @notice Returns the number of Transceivers that must attest to a msgId for
/// it to be considered valid and acted upon.
function getThreshold() external view returns (uint8);
/// @notice Returns a boolean indicating if the transceiver has attested to the message.
/// @param digest The digest of the message.
/// @param index The index of the transceiver
/// @return - Boolean indicating whether the transceiver at index `index` attested to a message digest
function transceiverAttestedToMessage(
bytes32 digest,
uint8 index
) external view returns (bool);
/// @notice Returns the number of attestations for a given message.
/// @param digest The digest of the message.
/// @return count The number of attestations received for the given message digest
function messageAttestations(
bytes32 digest
) external view returns (uint8 count);
/// @notice Returns of the address of the token managed by this contract.
function token() external view returns (address);
/// @notice Returns the chain ID.
function chainId() external view returns (uint16);
}
"
},
"@wormhole-ntt/interfaces/INttManager.sol": {
"content": "// SPDX-License-Identifier: Apache 2
pragma solidity >=0.8.8 <0.9.0;
import "../libraries/TrimmedAmount.sol";
import "../libraries/TransceiverStructs.sol";
import "./IManagerBase.sol";
interface INttManager is IManagerBase {
/// @dev The peer on another chain.
struct NttManagerPeer {
bytes32 peerAddress;
uint8 tokenDecimals;
}
/// @notice Emitted when a message is sent from the nttManager.
/// @dev Topic0
/// 0xe54e51e42099622516fa3b48e9733581c9dbdcb771cafb093f745a0532a35982.
/// @param recipient The recipient of the message.
/// @param refundAddress The address on the destination chain to which the
/// refund of unused gas will be paid
/// @param amount The amount transferred.
/// @param fee The amount of ether sent along with the tx to cover the delivery fee.
/// @param recipientChain The chain ID of the recipient.
/// @param msgSequence The unique sequence ID of the message.
event TransferSent(
bytes32 indexed recipient,
bytes32 indexed refundAddress,
uint256 amount,
uint256 fee,
uint16 recipientChain,
uint64 msgSequence
);
/// @notice Emitted when a message is sent from the nttManager.
/// @dev Topic0
/// 0x3e6ae56314c6da8b461d872f41c6d0bb69317b9d0232805aaccfa45df1a16fa0.
/// @param digest The digest of the message.
event TransferSent(bytes32 indexed digest);
/// @notice Emitted when the peer contract is updated.
/// @dev Topic0
/// 0x1456404e7f41f35c3daac941bb50bad417a66275c3040061b4287d787719599d.
/// @param chainId_ The chain ID of the peer contract.
/// @param oldPeerContract The old peer contract address.
/// @param oldPeerDecimals The old peer contract decimals.
/// @param peerContract The new peer contract address.
/// @param peerDecimals The new peer contract decimals.
event PeerUpdated(
uint16 indexed chainId_,
bytes32 oldPeerContract,
uint8 oldPeerDecimals,
bytes32 peerContract,
uint8 peerDecimals
);
/// @notice Emitted when a transfer has been redeemed
/// (either minted or unlocked on the recipient chain).
/// @dev Topic0
/// 0x504e6efe18ab9eed10dc6501a417f5b12a2f7f2b1593aed9b89f9bce3cf29a91.
/// @param digest The digest of the message.
event TransferRedeemed(bytes32 indexed digest);
/// @notice Emitted when an outbound transfer has been cancelled
/// @dev Topic0
/// 0xf80e572ae1b63e2449629b6c7d783add85c36473926f216077f17ee002bcfd07.
/// @param sequence The sequence number being cancelled
/// @param recipient The canceller and recipient of the funds
/// @param amount The amount of the transfer being cancelled
event OutboundTransferCancelled(uint256 sequence, address recipient, uint256 amount);
/// @notice The transfer has some dust.
/// @dev Selector 0x71f0634a
/// @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.
/// @dev Selector 0x66001a89
/// @param mode The mode.
error InvalidMode(uint8 mode);
/// @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 recipient is invalid.
/// @dev Selector 0xe2fe2726.
error InvalidRefundAddress();
/// @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 The caller is not the deployer.
error UnexpectedDeployer(address expectedOwner, address owner);
/// @notice Peer for the chain does not match the configuration.
/// @param chainId ChainId of the source chain.
/// @param peerAddress Address of the peer nttManager contract.
error InvalidPeer(uint16 chainId, bytes32 peerAddress);
/// @notice Peer chain ID cannot be zero.
error InvalidPeerChainIdZero();
/// @notice Peer cannot be the zero address.
error InvalidPeerZeroAddress();
/// @notice Peer cannot have zero decimals.
error InvalidPeerDecimals();
/// @notice Staticcall reverted
/// @dev Selector 0x1222cd83
error StaticcallFailed();
/// @notice Error when someone other than the original sender tries to cancel a queued outbound transfer.
/// @dev Selector 0xceb40a85.
/// @param canceller The address trying to cancel the transfer.
/// @param sender The original sender that initiated the transfer that was queued.
error CancellerNotSender(address canceller, address sender);
/// @notice An unexpected msg.value was passed with the call
/// @dev Selector 0xbd28e889.
error UnexpectedMsgValue();
/// @notice Peer cannot be on the same chain
/// @dev Selector 0x20371f2a.
error InvalidPeerSameChainId();
/// @notice Feature is not implemented.
error NotImplemented();
/// @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.
/// @param amount The amount to transfer.
/// @param recipientChain The Wormhole chain ID for the destination.
/// @param recipient The recipient address.
/// @return msgId The resulting message ID of the transfer
function transfer(
uint256 amount,
uint16 recipientChain,
bytes32 recipient
) 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.
/// @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 Wormhole chain ID for the destination.
/// @param recipient The recipient address.
/// @param refundAddress The address to which a refund for unussed gas is issued on the recipient chain.
/// @param shouldQueue Whether the transfer should be queued if the outbound limit is hit.
/// @param encodedInstructions Additional instructions to be forwarded to the recipient chain.
/// @return msgId The resulting message ID of the transfer
function transfer(
uint256 amount,
uint16 recipientChain,
bytes32 recipient,
bytes32 refundAddress,
bool shouldQueue,
bytes memory encodedInstructions
) external payable returns (uint64 msgId);
/// @notice Complete an outbound transfer that's been queued.
/// @dev This method is called by the client to complete an outbound transfer that's been queued.
/// @param queueSequence The sequence of the message in the queue.
/// @return msgSequence The sequence of the message.
function completeOutboundQueuedTransfer(
uint64 queueSequence
) external payable returns (uint64 msgSequence);
/// @notice Cancels an outbound transfer that's been queued.
/// @dev This method is called by the client to cancel an outbound transfer that's been queued.
/// @param queueSequence The sequence of the message in the queue.
function cancelOutboundQueuedTransfer(
uint64 queueSequence
) external;
/// @notice Complete an inbound queued transfer.
/// @param digest The digest of the message to complete.
function completeInboundQueuedTransfer(
bytes32 digest
) external;
/// @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.
/// @param sourceChainId The Wormhole chain id of the sender.
/// @param sourceNttManagerAddress The address of the sender's NTT Manager contract.
/// @param payload The VAA payload.
function attestationReceived(
uint16 sourceChainId,
bytes32 sourceNttManagerAddress,
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.
/// @dev This function is exposed as a fallback for when an `Transceiver` is deregistered
/// when a message is in flight.
/// @param sourceChainId The Wormhole chain id of the sender.
/// @param sourceNttManagerAddress The address of the sender's nttManager contract.
/// @param message The message to execute.
function executeMsg(
uint16 sourceChainId,
bytes32 sourceNttManagerAddress,
TransceiverStructs.NttManagerMessage memory message
) external;
/// @notice Returns the number of decimals of the token managed by the NttManager.
/// @return decimals The number of decimals of the token.
function tokenDecimals() external view returns (uint8);
/// @notice Returns registered peer contract for a given chain.
/// @param chainId_ Wormhole chain ID.
function getPeer(
uint16 chainId_
) external view returns (NttManagerPeer memory);
/// @notice Sets the corresponding peer.
/// @dev The nttManager that executes the message sets the source nttManager as the peer.
/// @param peerChainId The Wormhole chain ID of the peer.
/// @param peerContract The address of the peer nttManager contract.
/// @param decimals The number of decimals of the token on the peer chain.
/// @param inboundLimit The inbound rate limit for the peer chain id. This is formatted in the normal
/// token representation. e.g. a limit of 100 for a token with 6 decimals = 100_000_000
function setPeer(
uint16 peerChainId,
bytes32 peerContract,
uint8 decimals,
uint256 inboundLimit
) external;
/// @notice Sets the outbound transfer limit for a given chain.
/// @dev This method can only be executed by the `owner`.
/// @param limit The new outbound limit. This is formatted in the normal
/// token representation. e.g. a limit of 100 for a token with 6 decimals = 100_000_000
function setOutboundLimit(
uint256 limit
) external;
/// @notice Sets the inbound transfer limit for a given chain.
/// @dev This method can only be executed by the `owner`.
/// @param limit The new limit. This is formatted in the normal
/// token representation. e.g. a limit of 100 for a token with 6 decimals = 100_000_000
/// @param chainId The Wormhole chain ID to set the limit for.
function setInboundLimit(uint256 limit, uint16 chainId) external;
}
"
},
"@wormhole-ntt/interfaces/IOwnableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: Apache 2
//
pragma solidity >=0.8.8 <0.9.0;
interface IOwnableUpgradeable {
function owner() external view returns (address);
}
"
},
"@wormhole-ntt/interfaces/ISpecialRelayer.sol": {
"content": "// SPDX-License-Identifier: Apache 2
pragma solidity >=0.8.8 <0.9.0;
interface ISpecialRelayer {
function quoteDeliveryPrice(
address sourceContract,
uint16 targetChain,
uint256 additionalValue
) external view returns (uint256 nativePriceQuote);
function requestDelivery(
address sourceContract,
uint16 targetChain,
uint256 additionalValue,
uint64 sequence
) external payable;
}
"
},
"@wormhole-ntt/interfaces/ITransceiver.sol": {
"content": "// SPDX-License-Identifier: Apache 2
pragma solidity >=0.8.8 <0.9.0;
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 Returns the owner address of the NTT Manager that this transceiver is related to.
function getNttManagerOwner() external view returns (address);
/// @notice Returns the address of the token associated with this NTT deployment.
function getNttManagerToken() external view returns (address);
/// @notice Returns the string type of the transceiver. E.g. "wormhole", "axelar", etc.
function getTransceiverType() external view returns (string memory);
/// @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.
/// @return deliveryPrice The cost of delivering a message to the recipient chain,
/// in this chain's native token.
function quoteDeliveryPrice(
uint16 recipientChain,
TransceiverStructs.TransceiverInstruction memory instruction
) external view returns (uint256);
/// @dev Send a message to another chain.
/// @param recipientChain The Wormhole chain ID of the recipient.
/// @param instruction An additional Instruction provided by the Transceiver to be
/// executed on the recipient chain.
/// @param nttManagerMessage A message to be sent to the nttManager on the recipient chain.
/// @param recipientNttManagerAddress The Wormhole formatted address of the peer NTT Manager on the recipient chain.
/// @param refundAddress The Wormhole formatted address of the refund recipient
function sendMessage(
uint16 recipientChain,
TransceiverStructs.TransceiverInstruction memory instruction,
bytes memory nttManagerMessage,
bytes32 recipientNttManagerAddress,
bytes32 refundAddress
) external payable;
/// @notice Upgrades the transceiver to a new implementation.
/// @param newImplementation The address of the new implementation contract
function upgrade(
address newImplementation
) external;
/// @notice Transfers the ownership of the transceiver to a new address.
/// @param newOwner The address of the new owner
function transferTransceiverOwnership(
address newOwner
) external;
}
"
},
"@wormhole-ntt/interfaces/IWormholeTransceiver.sol": {
"content": "// SPDX-License-Identifier: Apache 2
pragma solidity >=0.8.8 <0.9.0;
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
/// 0x79376a0dc6cbfe6f6f8f89ad24c262a8c6233f8df181d3fe5abb2e2442e8c738.
/// @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.
/// @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.
/// @param encoded The encoded instruction.
/// @return instruction The parsed `WormholeTransceiverInstruction`.
function parseWormholeTransceiverInstruction(
bytes memory encoded
) external pure returns (WormholeTransceiverInstruction memory instruction);
/// @notice Encodes the `WormholeTransceiverInstruction` into a byte array.
/// @param instruction The `WormholeTransceiverInstruction` to encode.
/// @return encoded The encoded instruction.
function encodeWormholeTransceiverInstruction(
WormholeTransceiverInstruction memory instruction
) external pure returns (bytes memory);
}
"
},
"@wormhole-ntt/interfaces/IWormholeTransceiverState.sol": {
"content": "// SPDX-License-Identifier: Apache 2
pragma solidity >=0.8.8 <0.9.0;
import "../libraries/TransceiverStructs.sol";
interface IWormholeTransceiverState {
/// @notice Emitted when a message is sent from the transceiver.
/// @dev Topic0
/// 0xc3192e083c87c556db539f071d8a298869f487e951327b5616a6f85ae3da958e.
/// @param relayingType The type of relaying.
/// @param deliveryPayment The amount of ether sent along with the tx to cover the delivery fee.
event RelayingInfo(uint8 relayingType, bytes32 refundAddress, uint256 deliveryPayment);
/// @notice Emitted when a peer transceiver is set.
/// @dev Topic0
/// 0xa559263ee060c7a2560843b3a064ff0376c9753ae3e2449b595a3b615d326466.
/// @param chainId The chain ID of the peer.
/// @param peerContract The address of the peer contract.
event SetWormholePeer(uint16 chainId, bytes32 peerContract);
/// @notice Emitted when relaying is enabled for the given chain.
/// @dev Topic0
/// 0x528b18a533e892b5401d1fb63597275df9d2bb45b13e7695c3147cd07b9746c3.
/// @param chainId The chain ID to set.
/// @param isRelayingEnabled A boolean indicating whether relaying is enabled.
event SetIsWormholeRelayingEnabled(uint16 chainId, bool isRelayingEnabled);
/// @notice Emitted when special relaying is enabled for the given chain.
/// @dev Topic0
/// 0x0fe301480713b2c2072ee91b3bcfcbf2c0014f0447c89046f020f0f80727003c.
/// @param chainId The chain ID to set.
event SetIsSpecialRelayingEnabled(uint16 chainId, bool isRelayingEnabled);
/// @notice Emitted when the chain is EVM compatible.
/// @dev Topic0
/// 0x4add57d97a7bf5035340ea1212aeeb3d4d3887eb1faf3821a8224c3a6956a10c.
/// @param chainId The chain ID to set.
/// @param isEvm A boolean indicating whether relaying is enabled.
event SetIsWormholeEvmChain(uint16 chainId, bool isEvm);
/// @notice Additonal messages are not allowed.
/// @dev Selector: 0xc504ea29.
error UnexpectedAdditionalMessages();
/// @notice Error if the VAA is invalid.
/// @dev Selector: 0x8ee2e336.
/// @param reason The reason the VAA is invalid.
error InvalidVaa(string reason);
/// @notice Error if the peer has already been set.
/// @dev Selector: 0xb55eeae9.
/// @param chainId The chain ID of the peer.
/// @param peerAddress The address of the peer.
error PeerAlreadySet(uint16 chainId, bytes32 peerAddress);
/// @notice Error the peer contract cannot be the zero address.
/// @dev Selector: 0x26e0c7de.
error InvalidWormholePeerZeroAddress();
/// @notice The chain ID cannot be zero.
/// @dev Selector: 0x3dd98b24.
error InvalidWormholeChainIdZero();
/// @notice The caller is not the relayer.
/// @dev Selector: 0x1c269589.
/// @param caller The caller.
error CallerNotRelayer(address caller);
/// @notice Get the corresponding Transceiver contract on other chains that have been registered
/// via governance. This design should be extendable to other chains, so each Transceiver would
/// be potentially concerned with Transceivers on multiple other chains.
/// @dev that peers are registered under Wormhole chain ID values.
/// @param chainId The Wormhole chain ID of the peer to get.
/// @return peerContract The address of the peer contract on the given chain.
function getWormholePeer(
uint16 chainId
) external view returns (bytes32);
/// @notice Returns a boolean indicating whether the given VAA hash has been consumed.
/// @param hash The VAA hash to check.
function isVAAConsumed(
bytes32 hash
) external view returns (bool);
/// @notice Returns a boolean indicating whether Wormhole relaying is enabled for the given chain.
/// @param chainId The Wormhole chain ID to check.
function isWormholeRelayingEnabled(
uint16 chainId
) external view returns (bool);
/// @notice Returns a boolean indicating whether special relaying is enabled for the given chain.
/// @param chainId The Wormhole chain ID to check.
function isSpecialRelayingEnabled(
uint16 chainId
) external view returns (bool);
/// @notice Returns a boolean indicating whether the given chain is EVM compatible.
/// @param chainId The Wormhole chain ID to check.
function isWormholeEvmChain(
uint16 chainId
) external view returns (bool);
/// @notice Set the Wormhole peer contract for the given chain.
/// @dev This function is only callable by the `owner`.
/// @param chainId The Wormhole chain ID of the peer to set.
/// @param peerContract The address of the peer contract on the given chain.
function setWormholePeer(uint16 chainId, bytes32 peerContract) external payable;
/// @notice Set whether the chain is EVM compatible.
/// @dev This function is only callable by the `owner`.
/// @param chainId The Wormhole chain ID to set.
/// @param isEvm A boolean indicating whether the chain is an EVM chain.
function setIsWormholeEvmChain(uint16 chainId, bool isEvm) external;
/// @notice Set whether Wormhole relaying is enabled for the given chain.
/// @dev This function is only callable by the `owner`.
/// @param chainId The Wormhole chain ID to set.
/// @param isRelayingEnabled A boolean indicating whether relaying is enabled.
function setIsWormholeRelayingEnabled(uint16 chainId, bool isRelayingEnabled) external;
/// @notice Set whether special relaying is enabled for the given chain.
/// @dev This function is only callable by the `owner`.
/// @param chainId The Wormhole chain ID to set.
/// @param isRelayingEnabled A boolean indicating whether special relaying is enabled.
function setIsSpecialRelayingEnabled(uint16 chainId, bool isRelayingEnabled) external;
}
"
},
"@wormhole-ntt/libraries/BooleanFlag.sol": {
"content": "// SPDX-License-Identifier: Apache 2
pragma solidity >=0.8.8 <0.9.0;
/// @dev A boolean flag represented as a uint256 (the native EVM word size)
/// This is more gas efficient when setting and clearing the flag
type BooleanFlag is uint256;
library BooleanFlagLib {
/// @notice Error when boolean flag is not 0 or 1
/// @dev Selector: 0x837017c0.
/// @param value The value of the boolean flag
error InvalidBoolValue(BooleanFlag value);
uint256 constant FALSE = 0;
uint256 constant TRUE = 1;
function isSet(
BooleanFlag value
) internal pure returns (bool) {
return BooleanFlag.unwrap(value) == TRUE;
}
function toBool(
BooleanFlag value
) internal pure returns (bool) {
if (BooleanFlag.unwrap(value) == 0) return false;
if (BooleanFlag.unwrap(value) == 1) return true;
revert InvalidBoolValue(value);
}
function toWord(
bool value
) internal pure returns (BooleanFlag) {
if (value) {
return BooleanFlag.wrap(TRUE);
} else {
return BooleanFlag.wrap(FALSE);
}
}
}
"
},
"@wormhole-ntt/libraries/external/ContextUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
// COPIED FROM OPENZEPPELIN v5.0.1
// COPIED TO CHANGE SOLC FROM ^0.8.20 TO ^0.8.19
pragma solidity ^0.8.19;
import {Initializable} from "./Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {}
function __Context_init_unchained() internal onlyInitializing {}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
"
},
"@wormhole-ntt/libraries/external/Initializable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
// COPIED FROM OPENZEPPELIN v5.0.1
// COPIED TO CHANGE SOLC FROM ^0.8.20 TO ^0.8.19
pragma solidity ^0.8.19;
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE =
0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reininitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._initialized = 1;
if (isTopLevelCall) {
$._initializing = true;
}
_;
if (isTopLevelCall) {
$._initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(
uint64 version
) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}
"
},
"@wormhole-ntt/libraries/external/OwnableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
// COPIED FROM OPENZEPPELIN v5.0.1
// COPIED TO CHANGE SOLC FROM ^0.8.20 TO ^0.8.19
pragma solidity ^0.8.19;
import {ContextUpgradeable} from "./ContextUpgradeable.sol";
import {Initializable} from "./Initializable.sol";
import "../../interfaces/IOwnableUpgradeable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable, IOwnableUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.Ownable
struct OwnableStorage {
address _owner;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant OwnableStorageLocation =
0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;
function _getOwnableStorage() private pure returns (OwnableStorage storage $) {
assembly {
$.slot := OwnableStorageLocation
}
}
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
function __Ownable_init(
address initialOwner
) internal onlyInitializing {
__Ownable_init_unchained(initialOwner);
}
function __Ownable_init_unchained(
address initialOwner
) internal onlyInitializing {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
OwnableStorage storage $ = _getOwnableStorage();
return $._owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(
address newOwner
) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(
address newOwner
) internal virtual {
OwnableStorage storage $ = _getOwnableStorage();
address oldOwner = $._owner;
$._owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
"
},
"@wormhole-ntt/libraries/external/ReentrancyGuardUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.19;
import {Initializable} from "./Initializable.sol";
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuardUpgradeable is Initializable {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
/// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard
struct ReentrancyGuardStorage {
uint256 _status;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant ReentrancyGuardStorageLocation =
0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;
function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {
assembly {
$.slot := ReentrancyGuardStorageLocation
}
}
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
function __ReentrancyGuard_init() internal onlyInitializing {
__ReentrancyGuard_init_unchained();
}
function __ReentrancyGuard_init_unchained() internal onlyInitializing {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
$._status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
// On the first call to nonReentrant, _status will be NOT_ENTERED
if ($._status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
$._status = ENTERED;
}
function _nonReentrantAfter() private {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
$._status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
return $._status == ENTERED;
}
}
"
},
"@wormhole-ntt/libraries/Implementation.sol": {
"content": "// SPDX-License-Identifier: Apache 2
pragma solidity >=0.8.8 <0.9.0;
import "./external/Initializable.sol";
import "openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Upgrade.sol";
/// @dev This contract should be used as a base contract for implementation contracts
/// that are used with ERC1967Proxy.
/// It ensures that the contract cannot be initialized directly, only through
/// the proxy (by disabling initializers in the constructor).
/// It also exposes a migrate function that is called during upgrades.
abstract contract Implementation is Initializable, ERC1967Upgrade {
address immutable _this;
error OnlyDelegateCall();
error NotMigrating();
constructor() {
_disableInitializers();
_this = address(this);
}
modifier onlyDelegateCall() {
_checkDelegateCall();
_;
}
struct _Migrating {
bool isMigrating;
}
struct _Bool {
bool value;
}
bytes32 private constant MIGRATING_SLOT = bytes32(uint256(keccak256("ntt.migrating")) - 1);
bytes32 private constant MIGRATES_IMMUTABLES_SLOT =
bytes32(uint256(keccak256("ntt.migratesImmutables")) - 1);
function _getMigratingStorage() private pure returns (_Migrating storage $) {
uint256 slot = uint256(MIGRATING_SLOT);
assembly ("memory-safe") {
$.slot := slot
}
}
function _getMigratesImmutablesStorage() internal pure returns (_Bool storage $) {
uint256 slot = uint256(MIGRATES_IMMUTABLES_SLOT);
assembly ("memory-safe") {
$.slot := slot
}
}
function _checkDelegateCall() internal view {
if (address(this) == _this) {
revert OnlyDelegateCall();
}
}
function initialize() external payable onlyDelegateCall initializer {
_initialize();
}
function migrate() external onlyDelegateCall reinitializer(_getInitializedVersion() + 1) {
// NOTE: we add the reinitializer() modifier so that onlyInitializing
// functions can be called inside
if (!_getMigratingStorage().isMigrating) {
revert NotMigrating();
}
_migrate();
}
function _migrate() internal virtual;
function _initialize() internal virtual;
function _checkImmutables() internal view virtual;
function _upgrade(
address newImplementation
) internal {
_checkDelegateCall();
_upgradeTo(newImplementation);
_Migrating storage _migrating = _getMigratingStorage();
assert(!_migrating.isMigrating);
_migrating.isMigrating = true;
this.migrate();
if (!this.getMigratesImmutables()) {
_checkImmutables();
}
_setMigratesImmutables(false);
_migrating.isMigrating = false;
}
function getMigratesImmutables() public view returns (bool) {
return _getMigratesImmutablesStorage().value;
}
function _setMigratesImmutables(
bool value
) internal {
_getMigratesImmutablesStorage().value = value;
}
}
"
},
"@wormhole-ntt/libraries/PausableOwnable.sol": {
"content": "// SPDX-License-Identifier: Apache 2
pragma solidity >=0.8.8 <0.9.0;
import "./PausableUpgradeable.sol";
import "./external/OwnableUpgradeable.sol";
abstract contract PausableOwnable is PausableUpgradeable, OwnableUpgradeable {
/*
* @dev Modifier to allow only the Pauser and the Owner to access pausing functionality
*/
modifier onlyOwnerOrPauser() {
_checkOwnerOrPauser(owner());
_;
}
/*
* @dev Modifier to allow only the Pauser to access some functionality
*/
function _checkOwnerOrPauser(
address owner
) internal view {
if (pauser() != msg.sender && owner != msg.sender) {
revert InvalidPauser(msg.sender);
}
}
function __PausedOwnable_init(address initialPauser, address owner) internal onlyInitializing {
__Paused_init(initialPauser);
__Ownable_init(owner);
}
/**
* @dev Transfers the ability to pause to a new account (`newPauser`).
*/
function transferPauserCapability(
address newPauser
) public virtual onlyOwnerOrPauser {
PauserStorage storage $ = _getPauserStorage();
address oldPauser = $._pauser;
$._pauser = newPauser;
emit PauserTransferred(oldPauser, newPauser);
}
}
"
},
"@wormhole-ntt/libraries/PausableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: Apache 2
pragma solidity >=0.8.8 <0.9.0;
/**
* @dev Contact Module that allows children to implement logic to pause and unpause the contract.
* This is based on the OpenZeppelin Pausable contract but makes use of deterministic storage slots
* and the EVM native word size to optimize gas costs.
*
* The `whenPaused` and `whenNotPaused` modifiers are used to
* execute code based on the current state of the contract.
*
*/
import {Initializable} from "./external/Initializable.sol";
abstract contract PausableUpgradeable is Initializable {
/*
* @custom:storage-location erc7201:openzeppelin.storage.Pausable.
* @dev Storage slot with the pauser account, this is managed by the `PauserStorage` struct
*/
struct PauserStorage {
address _pauser;
}
// @dev Storage slot with the pause flag, this is managed by the `PauseStorage` struct
struct PauseStorage {
uint256 _pauseFlag;
}
/// NOTE: use uint256 to save on gas because it is the native word size of the EVM
/// it is cheaper than using a bool because modifying a boolean value requires an extra SLOAD
uint256 private constant NOT_PAUSED = 1;
uint256 private constant PAUSED = 2;
event PauserTransferred(address indexed oldPauser, address indexed newPauser);
/**
* @dev Contract is not paused, functionality is unblocked
*/
error RequireContractIsNotPaused();
/**
* @dev Contract state is paused, blocking
*/
error RequireContractIsPaused();
/**
* @dev the pauser is not a valid pauser account (e.g. `address(0)`)
*/
error InvalidPauser(address account);
// @dev Emitted when the contract is paused
event Paused(bool paused);
event NotPaused(bool notPaused);
bytes32 private constant PAUSE_SLOT = bytes32(uint256(keccak256("Pause.pauseFlag")) - 1);
bytes32 private constant PAUSER_ROLE_SLOT = bytes32(uint256(keccak256("Pause.pauseRole")) - 1);
function _getPauserStorage() internal pure returns (PauserStorage storage $) {
uint256 slot = uint256(PAUSER_ROLE_SLOT);
assembly ("memory-safe") {
$.slot := slot
}
}
/**
* @dev Returns the current pauser account address.
*/
function pauser() public view returns (address) {
return _getPauserStorage()._pauser;
}
function _getPauseStorage() private pure returns (PauseStorage storage $) {
uint256 slot = uint256(PAUSE_SLOT);
assembly ("memory-safe") {
$.slot := slot
}
}
function _setPauseStorage(
uint256 pauseFlag
) internal {
_getPauseStorage()._pauseFlag = pauseFlag;
}
function __Paused_init(
address initialPauser
) internal onlyInitializing {
__Paused_init_unchained(initialPauser);
}
function __Paused_init_unchained(
address initialPauser
) internal onlyInitializing {
// set pause flag to false initially
PauseStorage storage $ = _getPauseStorage();
$._pauseFlag = NOT_PAUSED;
// set the initial pauser
PauserStorage storage $_role = _getPauserStorage();
$_role._pauser = initialPauser;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
* Calling a function when this flag is set to `PAUSED` will cause the transaction to revert.
*/
modifier whenNotPaused() {
if (isPaus
Submitted on: 2025-10-31 10:41:55
Comments
Log in to comment.
No comments yet.