// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity ^0.8.13; import {IWormhole} from "../interfaces/IWormhole.sol"; /// @title UsesCore /// @author The Warp Team /// @notice This contract manages a eip1967 stored Wormhole core contract /// address. /// @dev This contract is intended to be inherited by any contract that needs /// to access the Wormhole core system. abstract contract UsesCore { /// @notice Contract is already init, and cannot be initialized again. /// @dev Selector 0xef34ca5c. error AlreadyInit(); /// @notice Attempting to set Core address to zero. /// @dev Selector 0xf71b2b01. error NullCore(); /// @notice The slot at which the core contract address is stored. /// @dev 0xc6a342a8a7e6992aa2a41ce922cb4520fcb72f46fb4f9e41cdd65930adc9ca4c. bytes32 public constant CORE_SLOT = bytes32(uint256(keccak256("eip1967.proxy.accumulate.core")) - 1); /// @notice Read the core contract address. /// @return _core The Wormhole core contract. function core() public view returns (IWormhole _core) { uint256 slot = uint256(CORE_SLOT); assembly ("memory-safe") { _core := sload(slot) } } /// @notice Set the core contract address. /// @dev This function can only be called once. /// @param _core The new core contract. /// @custom:reverts AlreadyInit() when core has already been initialized. /// @custom:reverts NullCore() when core is address(0). /// @custom:reverts if core doesn't implement chainId() function. function setCore(address _core) internal { if (address(core()) != address(0)) revert AlreadyInit(); // assert _core is not zero if (_core == address(0)) revert NullCore(); // call chainId() to check that _core implements IWormhole IWormhole(_core).chainId(); // store _core in CORE_SLOT uint256 slot = uint256(CORE_SLOT); assembly ("memory-safe") { sstore(slot, _core) } } }