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": {
"contracts/layer1/preconf/impl/PreconfRouter.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "src/shared/common/EssentialContract.sol";
import "../iface/IPreconfRouter.sol";
import "../iface/IPreconfWhitelist.sol";
import "src/layer1/based/ITaikoInbox.sol";
/// @title PreconfRouter
/// @custom:security-contact security@taiko.xyz
contract PreconfRouter is EssentialContract, IPreconfRouter {
IProposeBatch public immutable proposeBatchEntrypoint;
IPreconfWhitelist public immutable preconfWhitelist;
address public immutable fallbackPreconfer;
error InvalidLastBlockId(uint96 _actual, uint96 _expected);
uint256[50] private __gap;
modifier onlyFromPreconferOrFallback() {
require(
msg.sender == fallbackPreconfer
|| msg.sender == preconfWhitelist.getOperatorForCurrentEpoch(),
NotPreconferOrFallback()
);
_;
}
constructor(
address _proposeBatchEntrypoint, // TaikoInbox or TaikoWrapper
address _preconfWhitelist,
address _fallbackPreconfer
)
nonZeroAddr(_proposeBatchEntrypoint)
nonZeroAddr(_preconfWhitelist)
EssentialContract(address(0))
{
proposeBatchEntrypoint = IProposeBatch(_proposeBatchEntrypoint);
preconfWhitelist = IPreconfWhitelist(_preconfWhitelist);
fallbackPreconfer = _fallbackPreconfer;
}
function init(address _owner) external initializer {
__Essential_init(_owner);
}
function proposeBatch(
bytes calldata _params,
bytes calldata _txList
)
external
returns (ITaikoInbox.BatchMetadata memory meta_, uint64 lastBlockId_)
{
return _proposeBatch(_params, _txList);
}
function proposeBatchWithExpectedLastBlockId(
bytes calldata _params,
bytes calldata _txList,
uint96 _expectedLastBlockId
)
external
returns (ITaikoInbox.BatchMetadata memory meta_, uint64 lastBlockId_)
{
(meta_, lastBlockId_) = _proposeBatch(_params, _txList);
// Verify that the last block id is as expected
require(
lastBlockId_ == _expectedLastBlockId,
InvalidLastBlockId(uint96(lastBlockId_), _expectedLastBlockId)
);
}
/// @inheritdoc IPreconfRouter
function getConfig() external pure returns (IPreconfRouter.Config memory) {
return IPreconfRouter.Config({ handOverSlots: 8 });
}
function _proposeBatch(
bytes calldata _params,
bytes calldata _txList
)
internal
onlyFromPreconferOrFallback
returns (ITaikoInbox.BatchMetadata memory meta_, uint64 lastBlockId_)
{
// Both TaikoInbox and TaikoWrapper implement the same ABI for proposeBatch.
(meta_, lastBlockId_) = IProposeBatch(proposeBatchEntrypoint).proposeBatch(_params, _txList);
// Verify that the sender had set itself as the proposer
require(meta_.proposer == msg.sender, ProposerIsNotPreconfer());
}
}
"
},
"contracts/shared/common/EssentialContract.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import "./IResolver.sol";
/// @title EssentialContract
/// @custom:security-contact security@taiko.xyz
abstract contract EssentialContract is UUPSUpgradeable, Ownable2StepUpgradeable {
uint8 internal constant _FALSE = 1;
uint8 internal constant _TRUE = 2;
address private immutable __resolver;
uint256[50] private __gapFromOldAddressResolver;
/// @dev Slot 1.
uint8 internal __reentry;
uint8 internal __paused;
uint256[49] private __gap;
/// @notice Emitted when the contract is paused.
/// @param account The account that paused the contract.
event Paused(address account);
/// @notice Emitted when the contract is unpaused.
/// @param account The account that unpaused the contract.
event Unpaused(address account);
error INVALID_PAUSE_STATUS();
error FUNC_NOT_IMPLEMENTED();
error REENTRANT_CALL();
error ACCESS_DENIED();
error RESOLVER_NOT_FOUND();
error ZERO_ADDRESS();
error ZERO_VALUE();
/// @dev Modifier that ensures the caller is the owner or resolved address of a given name.
/// @param _name The name to check against.
modifier onlyFromOwnerOrNamed(bytes32 _name) {
require(msg.sender == owner() || msg.sender == resolve(_name, true), ACCESS_DENIED());
_;
}
/// @dev Modifier that ensures the caller is either the owner or a specified address.
/// @param _addr The address to check against.
modifier onlyFromOwnerOr(address _addr) {
require(msg.sender == owner() || msg.sender == _addr, ACCESS_DENIED());
_;
}
/// @dev Modifier that reverts the function call, indicating it is not implemented.
modifier notImplemented() {
revert FUNC_NOT_IMPLEMENTED();
_;
}
/// @dev Modifier that prevents reentrant calls to a function.
modifier nonReentrant() {
require(_loadReentryLock() != _TRUE, REENTRANT_CALL());
_storeReentryLock(_TRUE);
_;
_storeReentryLock(_FALSE);
}
/// @dev Modifier that allows function execution only when the contract is paused.
modifier whenPaused() {
require(paused(), INVALID_PAUSE_STATUS());
_;
}
/// @dev Modifier that allows function execution only when the contract is not paused.
modifier whenNotPaused() {
require(!paused(), INVALID_PAUSE_STATUS());
_;
}
/// @dev Modifier that ensures the provided address is not the zero address.
/// @param _addr The address to check.
modifier nonZeroAddr(address _addr) {
require(_addr != address(0), ZERO_ADDRESS());
_;
}
/// @dev Modifier that ensures the provided value is not zero.
/// @param _value The value to check.
modifier nonZeroValue(uint256 _value) {
require(_value != 0, ZERO_VALUE());
_;
}
/// @dev Modifier that ensures the provided bytes32 value is not zero.
/// @param _value The bytes32 value to check.
modifier nonZeroBytes32(bytes32 _value) {
require(_value != 0, ZERO_VALUE());
_;
}
/// @dev Modifier that ensures the caller is the resolved address of a given
/// name.
/// @param _name The name to check against.
modifier onlyFromNamed(bytes32 _name) {
require(msg.sender == resolve(_name, true), ACCESS_DENIED());
_;
}
/// @dev Modifier that ensures the caller is the resolved address of a given
/// name, if the name is set.
/// @param _name The name to check against.
modifier onlyFromOptionalNamed(bytes32 _name) {
address addr = resolve(_name, true);
require(addr == address(0) || msg.sender == addr, ACCESS_DENIED());
_;
}
/// @dev Modifier that ensures the caller is a resolved address to either _name1 or _name2
/// name.
/// @param _name1 The first name to check against.
/// @param _name2 The second name to check against.
modifier onlyFromNamedEither(bytes32 _name1, bytes32 _name2) {
require(
msg.sender == resolve(_name1, true) || msg.sender == resolve(_name2, true),
ACCESS_DENIED()
);
_;
}
/// @dev Modifier that ensures the caller is either of the two specified addresses.
/// @param _addr1 The first address to check against.
/// @param _addr2 The second address to check against.
modifier onlyFromEither(address _addr1, address _addr2) {
require(msg.sender == _addr1 || msg.sender == _addr2, ACCESS_DENIED());
_;
}
/// @dev Modifier that ensures the caller is the specified address.
/// @param _addr The address to check against.
modifier onlyFrom(address _addr) {
require(msg.sender == _addr, ACCESS_DENIED());
_;
}
/// @dev Modifier that ensures the caller is the specified address.
/// @param _addr The address to check against.
modifier onlyFromOptional(address _addr) {
require(_addr == address(0) || msg.sender == _addr, ACCESS_DENIED());
_;
}
constructor(address _resolver) {
__resolver = _resolver;
_disableInitializers();
}
/// @notice Pauses the contract.
function pause() public whenNotPaused {
_pause();
emit Paused(msg.sender);
// We call the authorize function here to avoid:
// Warning (5740): Unreachable code.
_authorizePause(msg.sender, true);
}
/// @notice Unpauses the contract.
function unpause() public whenPaused {
_unpause();
emit Unpaused(msg.sender);
// We call the authorize function here to avoid:
// Warning (5740): Unreachable code.
_authorizePause(msg.sender, false);
}
function impl() public view returns (address) {
return _getImplementation();
}
/// @notice Returns true if the contract is paused, and false otherwise.
/// @return true if paused, false otherwise.
function paused() public view virtual returns (bool) {
return __paused == _TRUE;
}
function inNonReentrant() public view returns (bool) {
return _loadReentryLock() == _TRUE;
}
/// @notice Returns the address of this contract.
/// @return The address of this contract.
function resolver() public view virtual returns (address) {
return __resolver;
}
/// @notice Resolves a name to an address on a specific chain
/// @param _chainId The chain ID to resolve the name on
/// @param _name The name to resolve
/// @param _allowZeroAddress Whether to allow resolving to the zero address
/// @return The resolved address
function resolve(
uint64 _chainId,
bytes32 _name,
bool _allowZeroAddress
)
internal
view
returns (address)
{
return IResolver(resolver()).resolve(_chainId, _name, _allowZeroAddress);
}
/// @notice Resolves a name to an address on the current chain
/// @param _name The name to resolve
/// @param _allowZeroAddress Whether to allow resolving to the zero address
/// @return The resolved address
function resolve(bytes32 _name, bool _allowZeroAddress) internal view returns (address) {
return IResolver(resolver()).resolve(block.chainid, _name, _allowZeroAddress);
}
/// @notice Initializes the contract.
/// @param _owner The owner of this contract. msg.sender will be used if this value is zero.
function __Essential_init(address _owner) internal virtual onlyInitializing {
__Context_init();
_transferOwnership(_owner == address(0) ? msg.sender : _owner);
__paused = _FALSE;
}
function _pause() internal virtual {
__paused = _TRUE;
}
function _unpause() internal virtual {
__paused = _FALSE;
}
function _authorizeUpgrade(address) internal virtual override onlyOwner { }
function _authorizePause(address, bool) internal virtual onlyOwner { }
// Stores the reentry lock
function _storeReentryLock(uint8 _reentry) internal virtual {
__reentry = _reentry;
}
// Loads the reentry lock
function _loadReentryLock() internal view virtual returns (uint8 reentry_) {
reentry_ = __reentry;
}
}
"
},
"contracts/layer1/preconf/iface/IPreconfRouter.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "src/layer1/based/IProposeBatch.sol";
/// @title IPreconfRouter
/// @custom:security-contact security@taiko.xyz
interface IPreconfRouter is IProposeBatch {
error ForcedInclusionNotSupported();
error NotPreconferOrFallback();
error ProposerIsNotPreconfer();
/// @notice Configuration struct for preconf-related settings
struct Config {
/// @notice The number of slots for hand over
uint256 handOverSlots;
}
/// @notice Returns the preconf configuration
/// @return The configuration struct
function getConfig() external view returns (Config memory);
}
"
},
"contracts/layer1/preconf/iface/IPreconfWhitelist.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title IPreconfWhitelist
/// @custom:security-contact security@taiko.xyz
interface IPreconfWhitelist {
/// @notice Emitted when a new operator is added to the whitelist.
/// @param proposer The proposer address of the operator that was added.
/// @param sequencer The sequencer address of the operator that was added.
/// @param activeSince The timestamp when the operator became active.
event OperatorAdded(address indexed proposer, address indexed sequencer, uint256 activeSince);
/// @notice Emitted when an operator is removed from the whitelist.
/// @param proposer The proposer address of the operator that was removed.
/// @param sequencer The sequencer address of the operator that was removed.
/// @param inactiveSince The timestamp when the operator became inactive.
event OperatorRemoved(
address indexed proposer, address indexed sequencer, uint256 inactiveSince
);
error InvalidOperatorIndex();
error InvalidOperatorCount();
error InvalidOperatorAddress();
error OperatorAlreadyExists();
error OperatorAlreadyRemoved();
error OperatorNotAvailableYet();
error NotOwnerOrEjecter();
/// @notice Adds a new operator to the whitelist.
/// @param _proposer The proposer address of the operator to be added.
/// @param _sequencer The sequencer address of the operator to be added.
/// @dev Only callable by the owner or an authorized address.
function addOperator(address _proposer, address _sequencer) external;
/// @notice Removes an operator from the whitelist.
/// @param _operatorId The ID of the operator to be removed.
/// @dev Only callable by the owner or an authorized address.
/// @dev Reverts if the operator ID does not exist.
function removeOperator(uint256 _operatorId) external;
/// @notice Retrieves the address of the operator for the current epoch.
/// @dev Uses the beacon block root of the first block in the last epoch as the source
/// of randomness.
/// @return The address of the operator.
function getOperatorForCurrentEpoch() external view returns (address);
/// @notice Retrieves the address of the operator for the next epoch.
/// @dev Uses the beacon block root of the first block in the current epoch as the source
/// of randomness.
/// @return The address of the operator.
function getOperatorForNextEpoch() external view returns (address);
}
"
},
"contracts/layer1/based/ITaikoInbox.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "src/shared/based/LibSharedData.sol";
/// @title TaikoInbox
/// @notice Acts as the inbox for the Taiko Alethia protocol, a simplified version of the
/// original Taiko-Based Contestable Rollup (BCR). The tier-based proof system and
/// contestation mechanisms have been removed.
///
/// Key assumptions of this protocol:
/// - Block proposals and proofs are asynchronous. Proofs are not available at proposal time,
/// unlike Taiko Gwyneth, which assumes synchronous composability.
/// - Proofs are presumed error-free and thoroughly validated, with proof type management
/// delegated to IVerifier contracts.
///
/// @dev Registered in the address resolver as "taiko".
/// @custom:security-contact security@taiko.xyz
interface ITaikoInbox {
struct BlockParams {
// the max number of transactions in this block. Note that if there are not enough
// transactions in calldata or blobs, the block will contains as many transactions as
// possible.
uint16 numTransactions;
// The time difference (in seconds) between the timestamp of this block and
// the timestamp of the parent block in the same batch. For the first block in a batch,
// there is not parent block in the same batch, so the time shift should be 0.
uint8 timeShift;
// Signals sent on L1 and need to sync to this L2 block.
bytes32[] signalSlots;
}
struct BlobParams {
// The hashes of the blob. Note that if this array is not empty. `firstBlobIndex` and
// `numBlobs` must be 0.
bytes32[] blobHashes;
// The index of the first blob in this batch.
uint8 firstBlobIndex;
// The number of blobs in this batch. Blobs are initially concatenated and subsequently
// decompressed via Zlib.
uint8 numBlobs;
// The byte offset of the blob in the batch.
uint32 byteOffset;
// The byte size of the blob.
uint32 byteSize;
// The block number when the blob was created. This value is only non-zero when
// `blobHashes` are non-empty.
uint64 createdIn;
}
struct BatchParams {
address proposer;
address coinbase;
bytes32 parentMetaHash;
uint64 anchorBlockId;
uint64 lastBlockTimestamp;
bool revertIfNotFirstProposal;
// Specifies the number of blocks to be generated from this batch.
BlobParams blobParams;
BlockParams[] blocks;
}
/// @dev This struct holds batch information essential for constructing blocks offchain, but it
/// does not include data necessary for batch proving.
struct BatchInfo {
bytes32 txsHash;
// Data to build L2 blocks
BlockParams[] blocks;
bytes32[] blobHashes;
bytes32 extraData;
address coinbase;
uint64 proposedIn; // Used by node/client
uint64 blobCreatedIn;
uint32 blobByteOffset;
uint32 blobByteSize;
uint32 gasLimit;
uint64 lastBlockId;
uint64 lastBlockTimestamp;
// Data for the L2 anchor transaction, shared by all blocks in the batch
uint64 anchorBlockId;
// corresponds to the `_anchorStateRoot` parameter in the anchor transaction.
// The batch's validity proof shall verify the integrity of these two values.
bytes32 anchorBlockHash;
LibSharedData.BaseFeeConfig baseFeeConfig;
}
/// @dev This struct holds batch metadata essential for proving the batch.
struct BatchMetadata {
bytes32 infoHash;
address proposer;
uint64 batchId;
uint64 proposedAt; // Used by node/client
}
/// @notice Struct representing transition to be proven.
struct Transition {
bytes32 parentHash;
bytes32 blockHash;
bytes32 stateRoot;
}
// @notice Struct representing transition storage
/// @notice 4 slots used.
struct TransitionState {
bytes32 parentHash;
bytes32 blockHash;
bytes32 stateRoot;
address prover;
bool inProvingWindow;
uint48 createdAt;
}
/// @notice 3 slots used.
struct Batch {
bytes32 metaHash; // slot 1
uint64 lastBlockId; // slot 2
uint96 reserved3;
uint96 livenessBond;
uint64 batchId; // slot 3
uint64 lastBlockTimestamp;
uint64 anchorBlockId;
uint24 nextTransitionId;
uint8 reserved4;
// The ID of the transaction that is used to verify this batch. However, if this batch is
// not verified as the last one in a transaction, verifiedTransitionId will remain zero.
uint24 verifiedTransitionId;
}
/// @notice Forge is only able to run coverage in case the contracts by default capable of
/// compiling without any optimization (neither optimizer runs, no compiling --via-ir flag).
struct Stats1 {
uint64 genesisHeight;
uint64 __reserved2;
uint64 lastSyncedBatchId;
uint64 lastSyncedAt;
}
struct Stats2 {
uint64 numBatches;
uint64 lastVerifiedBatchId;
bool paused;
uint56 lastProposedIn;
uint64 lastUnpausedAt;
}
struct ForkHeights {
uint64 ontake; // measured with block number.
uint64 pacaya; // measured with the batch Id, not block number.
uint64 shasta; // measured with the batch Id, not block number.
uint64 unzen; // measured with the batch Id, not block number.
}
/// @notice Struct holding Taiko configuration parameters. See {TaikoConfig}.
struct Config {
/// @notice The chain ID of the network where Taiko contracts are deployed.
uint64 chainId;
/// @notice The maximum number of unverified batches the protocol supports.
uint64 maxUnverifiedBatches;
/// @notice Size of the batch ring buffer, allowing extra space for proposals.
uint64 batchRingBufferSize;
/// @notice The maximum number of verifications allowed when a batch is proposed or proved.
uint64 maxBatchesToVerify;
/// @notice The maximum gas limit allowed for a block.
uint32 blockMaxGasLimit;
/// @notice The amount of Taiko token as a prover liveness bond per batch.
uint96 livenessBondBase;
/// @notice The amount of Taiko token as a prover liveness bond per block. This field is
/// deprecated and its value will be ignored.
uint96 livenessBondPerBlock;
/// @notice The number of batches between two L2-to-L1 state root sync.
uint8 stateRootSyncInternal;
/// @notice The max differences of the anchor height and the current block number.
uint64 maxAnchorHeightOffset;
/// @notice Base fee configuration
LibSharedData.BaseFeeConfig baseFeeConfig;
/// @notice The proving window in seconds.
uint16 provingWindow;
/// @notice The time required for a transition to be used for verifying a batch.
uint24 cooldownWindow;
/// @notice The maximum number of signals to be received by TaikoL2.
uint8 maxSignalsToReceive;
/// @notice The maximum number of blocks per batch.
uint16 maxBlocksPerBatch;
/// @notice Historical heights of the forks.
ForkHeights forkHeights;
}
/// @notice Struct holding the state variables for the {Taiko} contract.
struct State {
// Ring buffer for proposed batches and a some recent verified batches.
mapping(uint256 batchId_mod_batchRingBufferSize => Batch batch) batches;
// Indexing to transition ids (ring buffer not possible)
mapping(uint256 batchId => mapping(bytes32 parentHash => uint24 transitionId)) transitionIds;
// Ring buffer for transitions
mapping(
uint256 batchId_mod_batchRingBufferSize
=> mapping(uint24 transitionId => TransitionState ts)
) transitions;
bytes32 __reserve1; // slot 4 - was used as a ring buffer for Ether deposits
Stats1 stats1; // slot 5
Stats2 stats2; // slot 6
mapping(address account => uint256 bond) bondBalance;
uint256[43] __gap;
}
/// @notice Emitted when tokens are deposited into a user's bond balance.
/// @param user The address of the user who deposited the tokens.
/// @param amount The amount of tokens deposited.
event BondDeposited(address indexed user, uint256 amount);
/// @notice Emitted when tokens are withdrawn from a user's bond balance.
/// @param user The address of the user who withdrew the tokens.
/// @param amount The amount of tokens withdrawn.
event BondWithdrawn(address indexed user, uint256 amount);
/// @notice Emitted when a token is credited back to a user's bond balance.
/// @param user The address of the user whose bond balance is credited.
/// @param amount The amount of tokens credited.
event BondCredited(address indexed user, uint256 amount);
/// @notice Emitted when a token is debited from a user's bond balance.
/// @param user The address of the user whose bond balance is debited.
/// @param amount The amount of tokens debited.
event BondDebited(address indexed user, uint256 amount);
/// @notice Emitted when a batch is synced.
/// @param stats1 The Stats1 data structure.
event Stats1Updated(Stats1 stats1);
/// @notice Emitted when some state variable values changed.
/// @param stats2 The Stats2 data structure.
event Stats2Updated(Stats2 stats2);
/// @notice Emitted when a batch is proposed.
/// @param info The info of the proposed batch.
/// @param meta The metadata of the proposed batch.
/// @param txList The tx list in calldata.
event BatchProposed(BatchInfo info, BatchMetadata meta, bytes txList);
/// @notice Emitted when multiple transitions are proved.
/// @param verifier The address of the verifier.
/// @param transitions The transitions data.
event BatchesProved(address verifier, uint64[] batchIds, Transition[] transitions);
/// @notice Emitted when a transition is overwritten by a conflicting one with the same parent
/// hash but different block hash or state root.
/// @param batchId The batch ID.
/// @param oldTran The old transition overwritten.
/// @param newTran The new transition.
event ConflictingProof(uint64 batchId, TransitionState oldTran, Transition newTran);
/// @notice Emitted when a batch is verified.
/// @param batchId The ID of the verified batch.
/// @param blockHash The hash of the verified batch.
event BatchesVerified(uint64 batchId, bytes32 blockHash);
error AnchorBlockIdSmallerThanParent();
error AnchorBlockIdTooLarge();
error AnchorBlockIdTooSmall();
error ArraySizesMismatch();
error BatchNotFound();
error BatchVerified();
error BeyondCurrentFork();
error BlobNotFound();
error BlockNotFound();
error BlobNotSpecified();
error ContractPaused();
error CustomProposerMissing();
error CustomProposerNotAllowed();
error EtherNotPaidAsBond();
error FirstBlockTimeShiftNotZero();
error ForkNotActivated();
error InsufficientBond();
error InvalidBlobCreatedIn();
error InvalidBlobParams();
error InvalidGenesisBlockHash();
error InvalidParams();
error InvalidTransitionBlockHash();
error InvalidTransitionParentHash();
error InvalidTransitionStateRoot();
error MetaHashMismatch();
error MsgValueNotZero();
error NoBlocksToProve();
error NotFirstProposal();
error NotInboxWrapper();
error ParentMetaHashMismatch();
error SameTransition();
error SignalNotSent();
error TimestampSmallerThanParent();
error TimestampTooLarge();
error TimestampTooSmall();
error TooManyBatches();
error TooManyBlocks();
error TooManySignals();
error TransitionNotFound();
error ZeroAnchorBlockHash();
/// @notice Proposes a batch of blocks.
/// @param _params ABI-encoded parameters.
/// @param _txList The transaction list in calldata. If the txList is empty, blob will be used
/// for data availability.
/// @return meta_ The metadata of the proposed batch.
function proposeBatch(
bytes calldata _params,
bytes calldata _txList
)
external
returns (ITaikoInbox.BatchMetadata memory meta_, uint64 lastBlockId_);
/// @notice Proves state transitions for multiple batches with a single aggregated proof.
/// @param _params ABI-encoded parameter containing:
/// - metas: Array of metadata for each batch being proved.
/// - transitions: Array of batch transitions to be proved.
/// @param _proof The aggregated cryptographic proof proving the batches transitions.
function proveBatches(bytes calldata _params, bytes calldata _proof) external;
/// @notice Deposits TAIKO tokens into the contract to be used as liveness bond.
/// @param _amount The amount of TAIKO tokens to deposit.
function depositBond(uint256 _amount) external payable;
/// @notice Withdraws a specified amount of TAIKO tokens from the contract.
/// @param _amount The amount of TAIKO tokens to withdraw.
function withdrawBond(uint256 _amount) external;
/// @notice Returns the TAIKO token balance of a specific user.
/// @param _user The address of the user.
/// @return The TAIKO token balance of the user.
function bondBalanceOf(address _user) external view returns (uint256);
/// @notice Retrieves the Bond token address. If Ether is used as bond, this function returns
/// address(0).
/// @return The Bond token address.
function bondToken() external view returns (address);
/// @notice Retrieves the first set of protocol statistics.
/// @return Stats1 structure containing the statistics.
function getStats1() external view returns (Stats1 memory);
/// @notice Retrieves the second set of protocol statistics.
/// @return Stats2 structure containing the statistics.
function getStats2() external view returns (Stats2 memory);
/// @notice Retrieves data about a specific batch.
/// @param _batchId The ID of the batch to retrieve.
/// @return batch_ The batch data.
function getBatch(uint64 _batchId) external view returns (Batch memory batch_);
/// @notice Retrieves a specific transition by batch ID and transition ID. This function may
/// revert if the transition is not found.
/// @param _batchId The batch ID.
/// @param _tid The transition ID.
/// @return The specified transition state.
function getTransitionById(
uint64 _batchId,
uint24 _tid
)
external
view
returns (ITaikoInbox.TransitionState memory);
/// @notice Retrieves a specific transition by batch ID and parent Hash. This function may
/// revert if the transition is not found.
/// @param _batchId The batch ID.
/// @param _parentHash The parent hash.
/// @return The specified transition state.
function getTransitionByParentHash(
uint64 _batchId,
bytes32 _parentHash
)
external
view
returns (ITaikoInbox.TransitionState memory);
/// @notice Retrieves the transition used for the last verified batch.
/// @return batchId_ The batch ID of the last verified transition.
/// @return blockId_ The block ID of the last verified block.
/// @return ts_ The last verified transition.
function getLastVerifiedTransition()
external
view
returns (uint64 batchId_, uint64 blockId_, TransitionState memory ts_);
/// @notice Retrieves the transition used for the last synced batch.
/// @return batchId_ The batch ID of the last synced transition.
/// @return blockId_ The block ID of the last synced block.
/// @return ts_ The last synced transition.
function getLastSyncedTransition()
external
view
returns (uint64 batchId_, uint64 blockId_, TransitionState memory ts_);
/// @notice Retrieves the transition used for verifying a batch.
/// @param _batchId The batch ID.
/// @return The transition used for verifying the batch.
function getBatchVerifyingTransition(uint64 _batchId)
external
view
returns (TransitionState memory);
/// @notice Retrieves the current protocol configuration.
/// @return The current configuration.
function pacayaConfig() external view returns (Config memory);
}
"
},
"node_modules/@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.0;
import "../../interfaces/draft-IERC1822.sol";
import "../ERC1967/ERC1967Upgrade.sol";
/**
* @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
*
* A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
* `UUPSUpgradeable` with a custom implementation of upgrades.
*
* The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
*
* _Available since v4.1._
*/
abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
address private immutable __self = address(this);
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
require(address(this) != __self, "Function must be called through delegatecall");
require(_getImplementation() == __self, "Function must be called through active proxy");
_;
}
/**
* @dev Check that the execution is not being performed through a delegate call. This allows a function to be
* callable on the implementing contract but not through proxies.
*/
modifier notDelegated() {
require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall");
_;
}
/**
* @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate the implementation's compatibility when performing an upgrade.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
*/
function proxiableUUID() external view virtual override notDelegated returns (bytes32) {
return _IMPLEMENTATION_SLOT;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeTo(address newImplementation) public virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, new bytes(0), false);
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, data, true);
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeTo} and {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal override onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
}
"
},
"node_modules/@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.0;
import "./OwnableUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
function __Ownable2Step_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable2Step_init_unchained() internal onlyInitializing {
}
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
_transferOwnership(sender);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
"
},
"contracts/shared/common/IResolver.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title IResolver
/// @notice This contract acts as a bridge for name-to-address resolution.
/// @custom:security-contact security@taiko.xyz
interface IResolver {
error RESOLVED_TO_ZERO_ADDRESS();
/// @notice Resolves a name to its address deployed on a specified chain.
/// @param _chainId The chainId of interest.
/// @param _name Name whose address is to be resolved.
/// @param _allowZeroAddress If set to true, does not throw if the resolved
/// address is `address(0)`.
/// @return Address associated with the given name on the specified
/// chain.
function resolve(
uint256 _chainId,
bytes32 _name,
bool _allowZeroAddress
)
external
view
returns (address);
}
"
},
"contracts/layer1/based/IProposeBatch.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "./ITaikoInbox.sol";
/// @title IProposeBatch
/// @notice This interface defines the proposeBatch function that is also part of the ITaikoInbox
/// interface.
/// @custom:security-contact security@taiko.xyz
interface IProposeBatch {
/// @notice Proposes a batch of blocks.
/// @param _params ABI-encoded parameters.
/// @param _txList The transaction list in calldata. If the txList is empty, blob will be used
/// for data availability.
/// @return meta_ The metadata of the proposed batch.
function proposeBatch(
bytes calldata _params,
bytes calldata _txList
)
external
returns (ITaikoInbox.BatchMetadata memory meta_, uint64 lastBlockId_);
}
"
},
"contracts/shared/based/LibSharedData.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
library LibSharedData {
/// @dev Struct that represents L2 basefee configurations
struct BaseFeeConfig {
uint8 adjustmentQuotient;
uint8 sharingPctg;
uint32 gasIssuancePerSecond;
uint64 minGasExcess;
uint32 maxGasIssuancePerBlock;
}
}
"
},
"node_modules/@openzeppelin/contracts/interfaces/draft-IERC1822.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822Proxiable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}
"
},
"node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)
pragma solidity ^0.8.2;
import "../beacon/IBeacon.sol";
import "../../interfaces/IERC1967.sol";
import "../../interfaces/draft-IERC1822.sol";
import "../../utils/Address.sol";
import "../../utils/StorageSlot.sol";
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*
* _Available since v4.1._
*/
abstract contract ERC1967Upgrade is IERC1967 {
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Returns the current implementation address.
*/
function _getImplementation() internal view returns (address) {
return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Perform implementation upgrade
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Perform implementation upgrade with additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {
_upgradeTo(newImplementation);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(newImplementation, data);
}
}
/**
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {
// Upgrades from old implementations will perform a rollback test. This test requires the new
// implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing
// this special case will break upgrade paths from old UUPS implementation to new ones.
if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {
_setImplementation(newImplementation);
} else {
try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
} catch {
revert("ERC1967Upgrade: new implementation is not UUPS");
}
_upgradeToAndCall(newImplementation, data, forceCall);
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Returns the current admin.
*/
function _getAdmin() internal view returns (address) {
return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
require(newAdmin != address(0), "ERC1967: new admin is the zero address");
StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*/
function _changeAdmin(address newAdmin) internal {
emit AdminChanged(_getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
*/
bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Returns the current beacon.
*/
function _getBeacon() internal view returns (address) {
return StorageSlot.getAddressSlot(_BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
Address.isContract(IBeacon(newBeacon).implementation()),
"ERC1967: beacon implementation is not a contract"
);
StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;
}
/**
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
*
* Emits a {BeaconUpgraded} event.
*/
function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
}
}
}
"
},
"node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.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.
*
* By default, the owner account will be the one that deploys the contract. 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 {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @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) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @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 {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
"
},
"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @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 Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 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 functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_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 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_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() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @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 {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}
"
},
"node_modules/@openzeppelin/contracts/proxy/beacon/IBeacon.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.0;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeacon {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {BeaconProxy} will check that this address is a contract.
*/
function implementation() external view returns (address);
}
"
},
"node_modules/@openzeppelin/contracts/interfaces/IERC1967.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
*
* _Available since v4.8.3._
*/
interface IERC1967 {
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
}
"
},
"node_modules/@openzeppelin/contracts/utils/Address.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
b
Submitted on: 2025-10-08 09:36:16
Comments
Log in to comment.
No comments yet.