// SPDX-License-Identifier: MITpragmasolidity ^0.6.12;pragmaexperimentalABIEncoderV2;import { IBridgehub, L2TransactionRequestDirect } from'./system/IBridgehub.sol';
import { Ownable } from'@openzeppelin/contracts/access/Ownable.sol';
import { ReentrancyGuard } from'@openzeppelin/contracts/utils/ReentrancyGuard.sol';
import { Pausable } from'@openzeppelin/contracts/utils/Pausable.sol';
/// @title Abstract Bridge contract/// @author Pudgy Labs/// @notice This contract handles bridging of ETH to Layer 2contractAbstractBridgeisOwnable, ReentrancyGuard, Pausable{
uint256constant FEE_DECIMALS =1e4;
/// @notice Address of the bridge hub contract
IBridgehub public bridgehub;
/// @notice Fee percentage for the operatoruint256public operatorFee;
/// @notice Address where the operator fee is sentaddresspublic feeTo;
/// @notice Configuration for the ZkBridgeHubstructZkBridgeHubConfig {
uint256 chainId; // Chain ID of the target Layer 2bytes l2Calldata; // Calldata for the Layer 2 transactionuint256 l2GasLimit; // Gas limit for the Layer 2 transactionuint256 l2GasPrice; // Gas price for the Layer 2 transactionuint256 l2GasPerPubdataByteLimit; // Gas per pubdata byte limit for the Layer 2 transactionbytes[] factoryDeps; // Factory dependencies for the Layer 2 transaction
}
/// @notice Current bridge configuration
ZkBridgeHubConfig public bridgeConfig;
/// @param _bridgehub Address of the bridge hub contractconstructor(address _bridgehub) publicOwnable() {
bridgehub = IBridgehub(_bridgehub);
}
/// @notice Sets the operator fee/// @param _fee New operator feefunctionsetOperatorFee(uint256 _fee) publiconlyOwner{
operatorFee = _fee;
}
/// @notice Sets the address where the operator fee is sent/// @param _feeTo New fee recipient addressfunctionsetFeeTo(address _feeTo) publiconlyOwner{
feeTo = _feeTo;
}
/// @notice Sets the bridge hub contract address/// @param _bridgehub New bridge hub contract addressfunctionsetBridgehub(address _bridgehub) publiconlyOwner{
bridgehub = IBridgehub(_bridgehub);
}
/// @notice Sets the bridge configuration/// @param _bridgeConfig New bridge configurationfunctionsetBridgeConfig(ZkBridgeHubConfig memory _bridgeConfig) publiconlyOwner{
bridgeConfig = _bridgeConfig;
}
/// @notice Handles the deposit of ETH to the bridge/// @param _to Address of the recipient on Layer 2function_handleDepositEth(address _to) internalwhenNotPaused{
require(address(bridgehub) !=address(0), 'Bridge address unset');
uint256 operatorShare = (msg.value* operatorFee) / FEE_DECIMALS;
uint256 l1Value =msg.value- operatorShare;
uint256 gasFee = bridgehub.l2TransactionBaseCost(
bridgeConfig.chainId,
bridgeConfig.l2GasPrice,
bridgeConfig.l2GasLimit,
bridgeConfig.l2GasPerPubdataByteLimit
);
uint256 l2Value = l1Value - ((gasFee *11000) / FEE_DECIMALS);
bridgehub.requestL2TransactionDirect{ value: l1Value }(
L2TransactionRequestDirect(
bridgeConfig.chainId,
l1Value,
_to,
l2Value,
bridgeConfig.l2Calldata,
bridgeConfig.l2GasLimit,
bridgeConfig.l2GasPerPubdataByteLimit,
bridgeConfig.factoryDeps,
_to
)
);
if (operatorShare >0) {
payable(feeTo).transfer(operatorShare);
}
}
/// @notice Bridges ETH to Layer 2/// @param _to Address of the recipient on Layer 2functionbridgeEth(address _to) externalpayablenonReentrant{
_handleDepositEth(_to);
}
/// @notice Fallback function to handle direct ETH depositsreceive() externalpayablenonReentrant{
_handleDepositEth(msg.sender);
}
}
Contract Source Code
File 2 of 9: Context.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/*
* @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 GSN 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.
*/abstractcontractContext{
function_msgSender() internalviewvirtualreturns (addresspayable) {
returnmsg.sender;
}
function_msgData() internalviewvirtualreturns (bytesmemory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691returnmsg.data;
}
}
Contract Source Code
File 3 of 9: IBridgehub.sol
// SPDX-License-Identifier: MIT// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.pragmasolidity ^0.6.12;pragmaexperimentalABIEncoderV2;import {IL1SharedBridge} from"./IL1SharedBridge.sol";
import {L2Message, L2Log, TxStatus} from"./Messaging.sol";
structL2TransactionRequestDirect {
uint256 chainId;
uint256 mintValue;
address l2Contract;
uint256 l2Value;
bytes l2Calldata;
uint256 l2GasLimit;
uint256 l2GasPerPubdataByteLimit;
bytes[] factoryDeps;
address refundRecipient;
}
structL2TransactionRequestTwoBridgesOuter {
uint256 chainId;
uint256 mintValue;
uint256 l2Value;
uint256 l2GasLimit;
uint256 l2GasPerPubdataByteLimit;
address refundRecipient;
address secondBridgeAddress;
uint256 secondBridgeValue;
bytes secondBridgeCalldata;
}
structL2TransactionRequestTwoBridgesInner {
bytes32 magicValue;
address l2Contract;
bytes l2Calldata;
bytes[] factoryDeps;
bytes32 txDataHash;
}
interfaceIBridgehub{
/// @notice pendingAdmin is changed/// @dev Also emitted when new admin is accepted and in this case, `newPendingAdmin` would be zero addresseventNewPendingAdmin(addressindexed oldPendingAdmin, addressindexed newPendingAdmin);
/// @notice Admin changedeventNewAdmin(addressindexed oldAdmin, addressindexed newAdmin);
/// @notice Starts the transfer of admin rights. Only the current admin can propose a new pending one./// @notice New admin can accept admin rights by calling `acceptAdmin` function./// @param _newPendingAdmin Address of the new adminfunctionsetPendingAdmin(address _newPendingAdmin) external;
/// @notice Accepts transfer of admin rights. Only pending admin can accept the role.functionacceptAdmin() external;
/// GettersfunctionstateTransitionManagerIsRegistered(address _stateTransitionManager) externalviewreturns (bool);
functionstateTransitionManager(uint256 _chainId) externalviewreturns (address);
functiontokenIsRegistered(address _baseToken) externalviewreturns (bool);
functionbaseToken(uint256 _chainId) externalviewreturns (address);
functionsharedBridge() externalviewreturns (IL1SharedBridge);
functiongetHyperchain(uint256 _chainId) externalviewreturns (address);
/// Mailbox forwarderfunctionproveL2MessageInclusion(uint256 _chainId,
uint256 _batchNumber,
uint256 _index,
L2Message calldata _message,
bytes32[] calldata _proof
) externalviewreturns (bool);
functionproveL2LogInclusion(uint256 _chainId,
uint256 _batchNumber,
uint256 _index,
L2Log memory _log,
bytes32[] calldata _proof
) externalviewreturns (bool);
functionproveL1ToL2TransactionStatus(uint256 _chainId,
bytes32 _l2TxHash,
uint256 _l2BatchNumber,
uint256 _l2MessageIndex,
uint16 _l2TxNumberInBatch,
bytes32[] calldata _merkleProof,
TxStatus _status
) externalviewreturns (bool);
functionrequestL2TransactionDirect(
L2TransactionRequestDirect calldata _request
) externalpayablereturns (bytes32 canonicalTxHash);
functionrequestL2TransactionTwoBridges(
L2TransactionRequestTwoBridgesOuter calldata _request
) externalpayablereturns (bytes32 canonicalTxHash);
functionl2TransactionBaseCost(uint256 _chainId,
uint256 _gasPrice,
uint256 _l2GasLimit,
uint256 _l2GasPerPubdataByteLimit
) externalviewreturns (uint256);
//// RegistryfunctioncreateNewChain(uint256 _chainId,
address _stateTransitionManager,
address _baseToken,
uint256 _salt,
address _admin,
bytescalldata _initData
) externalreturns (uint256 chainId);
functionaddStateTransitionManager(address _stateTransitionManager) external;
functionremoveStateTransitionManager(address _stateTransitionManager) external;
functionaddToken(address _token) external;
functionsetSharedBridge(address _sharedBridge) external;
eventNewChain(uint256indexed chainId, address stateTransitionManager, addressindexed chainGovernance);
}
Contract Source Code
File 4 of 9: IL1ERC20Bridge.sol
// SPDX-License-Identifier: MIT// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.pragmasolidity ^0.6.12;import {IL1SharedBridge} from"./IL1SharedBridge.sol";
interfaceIL1ERC20Bridge{
eventDepositInitiated(bytes32indexed l2DepositTxHash,
addressindexedfrom,
addressindexed to,
address l1Token,
uint256 amount
);
eventWithdrawalFinalized(addressindexed to, addressindexed l1Token, uint256 amount);
eventClaimedFailedDeposit(addressindexed to, addressindexed l1Token, uint256 amount);
functionisWithdrawalFinalized(uint256 _l2BatchNumber, uint256 _l2MessageIndex) externalviewreturns (bool);
functiondeposit(address _l2Receiver,
address _l1Token,
uint256 _amount,
uint256 _l2TxGasLimit,
uint256 _l2TxGasPerPubdataByte,
address _refundRecipient
) externalpayablereturns (bytes32 txHash);
functiondeposit(address _l2Receiver,
address _l1Token,
uint256 _amount,
uint256 _l2TxGasLimit,
uint256 _l2TxGasPerPubdataByte
) externalpayablereturns (bytes32 txHash);
functionclaimFailedDeposit(address _depositSender,
address _l1Token,
bytes32 _l2TxHash,
uint256 _l2BatchNumber,
uint256 _l2MessageIndex,
uint16 _l2TxNumberInBatch,
bytes32[] calldata _merkleProof
) external;
functionfinalizeWithdrawal(uint256 _l2BatchNumber,
uint256 _l2MessageIndex,
uint16 _l2TxNumberInBatch,
bytescalldata _message,
bytes32[] calldata _merkleProof
) external;
functionl2TokenAddress(address _l1Token) externalviewreturns (address);
functionSHARED_BRIDGE() externalviewreturns (IL1SharedBridge);
functionl2TokenBeacon() externalviewreturns (address);
functionl2Bridge() externalviewreturns (address);
functiondepositAmount(address _account,
address _l1Token,
bytes32 _depositL2TxHash
) externalreturns (uint256 amount);
functiontransferTokenToSharedBridge(address _token) external;
}
Contract Source Code
File 5 of 9: IL1SharedBridge.sol
// SPDX-License-Identifier: MIT// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.pragmasolidity ^0.6.12;pragmaexperimentalABIEncoderV2;import {L2TransactionRequestTwoBridgesInner} from"./IBridgehub.sol";
import {IBridgehub} from"./IBridgehub.sol";
import {IL1ERC20Bridge} from"./IL1ERC20Bridge.sol";
interfaceIL1SharedBridge{
/// @notice pendingAdmin is changed/// @dev Also emitted when new admin is accepted and in this case, `newPendingAdmin` would be zero addresseventNewPendingAdmin(addressindexed oldPendingAdmin, addressindexed newPendingAdmin);
/// @notice Admin changedeventNewAdmin(addressindexed oldAdmin, addressindexed newAdmin);
eventLegacyDepositInitiated(uint256indexed chainId,
bytes32indexed l2DepositTxHash,
addressindexedfrom,
address to,
address l1Token,
uint256 amount
);
eventBridgehubDepositInitiated(uint256indexed chainId,
bytes32indexed txDataHash,
addressindexedfrom,
address to,
address l1Token,
uint256 amount
);
eventBridgehubDepositBaseTokenInitiated(uint256indexed chainId,
addressindexedfrom,
address l1Token,
uint256 amount
);
eventBridgehubDepositFinalized(uint256indexed chainId,
bytes32indexed txDataHash,
bytes32indexed l2DepositTxHash
);
eventWithdrawalFinalizedSharedBridge(uint256indexed chainId,
addressindexed to,
addressindexed l1Token,
uint256 amount
);
eventClaimedFailedDepositSharedBridge(uint256indexed chainId,
addressindexed to,
addressindexed l1Token,
uint256 amount
);
functionisWithdrawalFinalized(uint256 _chainId,
uint256 _l2BatchNumber,
uint256 _l2MessageIndex
) externalviewreturns (bool);
functiondepositLegacyErc20Bridge(address _msgSender,
address _l2Receiver,
address _l1Token,
uint256 _amount,
uint256 _l2TxGasLimit,
uint256 _l2TxGasPerPubdataByte,
address _refundRecipient
) externalpayablereturns (bytes32 txHash);
functionclaimFailedDepositLegacyErc20Bridge(address _depositSender,
address _l1Token,
uint256 _amount,
bytes32 _l2TxHash,
uint256 _l2BatchNumber,
uint256 _l2MessageIndex,
uint16 _l2TxNumberInBatch,
bytes32[] calldata _merkleProof
) external;
functionclaimFailedDeposit(uint256 _chainId,
address _depositSender,
address _l1Token,
uint256 _amount,
bytes32 _l2TxHash,
uint256 _l2BatchNumber,
uint256 _l2MessageIndex,
uint16 _l2TxNumberInBatch,
bytes32[] calldata _merkleProof
) external;
functionfinalizeWithdrawalLegacyErc20Bridge(uint256 _l2BatchNumber,
uint256 _l2MessageIndex,
uint16 _l2TxNumberInBatch,
bytescalldata _message,
bytes32[] calldata _merkleProof
) externalreturns (address l1Receiver, address l1Token, uint256 amount);
functionfinalizeWithdrawal(uint256 _chainId,
uint256 _l2BatchNumber,
uint256 _l2MessageIndex,
uint16 _l2TxNumberInBatch,
bytescalldata _message,
bytes32[] calldata _merkleProof
) external;
functionsetEraPostDiamondUpgradeFirstBatch(uint256 _eraPostDiamondUpgradeFirstBatch) external;
functionsetEraPostLegacyBridgeUpgradeFirstBatch(uint256 _eraPostLegacyBridgeUpgradeFirstBatch) external;
functionsetEraLegacyBridgeLastDepositTime(uint256 _eraLegacyBridgeLastDepositBatch,
uint256 _eraLegacyBridgeLastDepositTxNumber
) external;
functionL1_WETH_TOKEN() externalviewreturns (address);
functionBRIDGE_HUB() externalviewreturns (IBridgehub);
functionlegacyBridge() externalviewreturns (IL1ERC20Bridge);
functionl2BridgeAddress(uint256 _chainId) externalviewreturns (address);
functiondepositHappened(uint256 _chainId, bytes32 _l2TxHash) externalviewreturns (bytes32);
/// data is abi encoded :/// address _l1Token,/// uint256 _amount,/// address _l2ReceiverfunctionbridgehubDeposit(uint256 _chainId,
address _prevMsgSender,
uint256 _l2Value,
bytescalldata _data
) externalpayablereturns (L2TransactionRequestTwoBridgesInner memory request);
functionbridgehubDepositBaseToken(uint256 _chainId,
address _prevMsgSender,
address _l1Token,
uint256 _amount
) externalpayable;
functionbridgehubConfirmL2Transaction(uint256 _chainId, bytes32 _txDataHash, bytes32 _txHash) external;
functionreceiveEth(uint256 _chainId) externalpayable;
/// @notice Starts the transfer of admin rights. Only the current admin can propose a new pending one./// @notice New admin can accept admin rights by calling `acceptAdmin` function./// @param _newPendingAdmin Address of the new adminfunctionsetPendingAdmin(address _newPendingAdmin) external;
/// @notice Accepts transfer of admin rights. Only pending admin can accept the role.functionacceptAdmin() external;
}
Contract Source Code
File 6 of 9: Messaging.sol
// SPDX-License-Identifier: MIT// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.pragmasolidity ^0.6.12;/// @dev The enum that represents the transaction execution status/// @param Failure The transaction execution failed/// @param Success The transaction execution succeededenumTxStatus {
Failure,
Success
}
/// @dev The log passed from L2/// @param l2ShardId The shard identifier, 0 - rollup, 1 - porter/// All other values are not used but are reserved for the future/// @param isService A boolean flag that is part of the log along with `key`, `value`, and `sender` address./// This field is required formally but does not have any special meaning/// @param txNumberInBatch The L2 transaction number in a Batch, in which the log was sent/// @param sender The L2 address which sent the log/// @param key The 32 bytes of information that was sent in the log/// @param value The 32 bytes of information that was sent in the log// Both `key` and `value` are arbitrary 32-bytes selected by the log senderstructL2Log {
uint8 l2ShardId;
bool isService;
uint16 txNumberInBatch;
address sender;
bytes32 key;
bytes32 value;
}
/// @dev An arbitrary length message passed from L2/// @notice Under the hood it is `L2Log` sent from the special system L2 contract/// @param txNumberInBatch The L2 transaction number in a Batch, in which the message was sent/// @param sender The address of the L2 account from which the message was passed/// @param data An arbitrary length messagestructL2Message {
uint16 txNumberInBatch;
address sender;
bytes data;
}
/// @dev Internal structure that contains the parameters for the writePriorityOp/// internal function./// @param txId The id of the priority transaction./// @param l2GasPrice The gas price for the l2 priority operation./// @param expirationTimestamp The timestamp by which the priority operation must be processed by the operator./// @param request The external calldata request for the priority operation.structWritePriorityOpParams {
uint256 txId;
uint256 l2GasPrice;
uint64 expirationTimestamp;
BridgehubL2TransactionRequest request;
}
/// @dev Structure that includes all fields of the L2 transaction/// @dev The hash of this structure is the "canonical L2 transaction hash" and can/// be used as a unique identifier of a tx/// @param txType The tx type number, depending on which the L2 transaction can be/// interpreted differently/// @param from The sender's address. `uint256` type for possible address format changes/// and maintaining backward compatibility/// @param to The recipient's address. `uint256` type for possible address format changes/// and maintaining backward compatibility/// @param gasLimit The L2 gas limit for L2 transaction. Analog to the `gasLimit` on an/// L1 transactions/// @param gasPerPubdataByteLimit Maximum number of L2 gas that will cost one byte of pubdata/// (every piece of data that will be stored on L1 as calldata)/// @param maxFeePerGas The absolute maximum sender willing to pay per unit of L2 gas to get/// the transaction included in a Batch. Analog to the EIP-1559 `maxFeePerGas` on an L1 transactions/// @param maxPriorityFeePerGas The additional fee that is paid directly to the validator/// to incentivize them to include the transaction in a Batch. Analog to the EIP-1559/// `maxPriorityFeePerGas` on an L1 transactions/// @param paymaster The address of the EIP-4337 paymaster, that will pay fees for the/// transaction. `uint256` type for possible address format changes and maintaining backward compatibility/// @param nonce The nonce of the transaction. For L1->L2 transactions it is the priority/// operation Id/// @param value The value to pass with the transaction/// @param reserved The fixed-length fields for usage in a future extension of transaction/// formats/// @param data The calldata that is transmitted for the transaction call/// @param signature An abstract set of bytes that are used for transaction authorization/// @param factoryDeps The set of L2 bytecode hashes whose preimages were shown on L1/// @param paymasterInput The arbitrary-length data that is used as a calldata to the paymaster pre-call/// @param reservedDynamic The arbitrary-length field for usage in a future extension of transaction formatsstructL2CanonicalTransaction {
uint256 txType;
uint256from;
uint256 to;
uint256 gasLimit;
uint256 gasPerPubdataByteLimit;
uint256 maxFeePerGas;
uint256 maxPriorityFeePerGas;
uint256 paymaster;
uint256 nonce;
uint256 value;
// In the future, we might want to add some// new fields to the struct. The `txData` struct// is to be passed to account and any changes to its structure// would mean a breaking change to these accounts. To prevent this,// we should keep some fields as "reserved"// It is also recommended that their length is fixed, since// it would allow easier proof integration (in case we will need// some special circuit for preprocessing transactions)uint256[4] reserved;
bytes data;
bytes signature;
uint256[] factoryDeps;
bytes paymasterInput;
// Reserved dynamic type for the future use-case. Using it should be avoided,// But it is still here, just in case we want to enable some additional functionalitybytes reservedDynamic;
}
/// @param sender The sender's address./// @param contractAddressL2 The address of the contract on L2 to call./// @param valueToMint The amount of base token that should be minted on L2 as the result of this transaction./// @param l2Value The msg.value of the L2 transaction./// @param l2Calldata The calldata for the L2 transaction./// @param l2GasLimit The limit of the L2 gas for the L2 transaction/// @param l2GasPerPubdataByteLimit The price for a single pubdata byte in L2 gas./// @param factoryDeps The array of L2 bytecodes that the tx depends on./// @param refundRecipient The recipient of the refund for the transaction on L2. If the transaction fails, then/// this address will receive the `l2Value`.// solhint-disable-next-line gas-struct-packingstructBridgehubL2TransactionRequest {
address sender;
address contractL2;
uint256 mintValue;
uint256 l2Value;
bytes l2Calldata;
uint256 l2GasLimit;
uint256 l2GasPerPubdataByteLimit;
bytes[] factoryDeps;
address refundRecipient;
}
Contract Source Code
File 7 of 9: Ownable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"../utils/Context.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.
*/abstractcontractOwnableisContext{
addressprivate _owner;
eventOwnershipTransferred(addressindexed previousOwner, addressindexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/constructor () internal{
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/functionowner() publicviewvirtualreturns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/modifieronlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/functionrenounceOwnership() publicvirtualonlyOwner{
emit OwnershipTransferred(_owner, address(0));
_owner =address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/functiontransferOwnership(address newOwner) publicvirtualonlyOwner{
require(newOwner !=address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
Contract Source Code
File 8 of 9: Pausable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"./Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/abstractcontractPausableisContext{
/**
* @dev Emitted when the pause is triggered by `account`.
*/eventPaused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/eventUnpaused(address account);
boolprivate _paused;
/**
* @dev Initializes the contract in unpaused state.
*/constructor () internal{
_paused =false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/functionpaused() publicviewvirtualreturns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/modifierwhenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/modifierwhenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/function_pause() internalvirtualwhenNotPaused{
_paused =true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/function_unpause() internalvirtualwhenPaused{
_paused =false;
emit Unpaused(_msgSender());
}
}
Contract Source Code
File 9 of 9: ReentrancyGuard.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @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].
*/abstractcontractReentrancyGuard{
// 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.uint256privateconstant _NOT_ENTERED =1;
uint256privateconstant _ENTERED =2;
uint256private _status;
constructor () internal{
_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 make it call a
* `private` function that does the actual work.
*/modifiernonReentrant() {
// On the first call to nonReentrant, _notEntered will be truerequire(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}