Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- TaikoAnchor
- Optimization enabled
- true
- Compiler version
- v0.8.27+commit.40a35a09
- Optimization runs
- 200
- EVM Version
- shanghai
- Verified at
- 2025-05-18T06:51:14.730168Z
Constructor Arguments
0x000000000000000000000000c32277f541bbadaa260337e71cea53871d310dc80000000000000000000000001670000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000011cab0
Arg [0] (address) : 0xc32277f541bbadaa260337e71cea53871d310dc8
Arg [1] (address) : 0x1670000000000000000000000000000000000005
Arg [2] (uint64) : 1166000
contracts/layer2/based/TaikoAnchor.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "src/shared/common/EssentialContract.sol";
import "src/shared/based/ITaiko.sol";
import "src/shared/libs/LibStrings.sol";
import "src/shared/libs/LibAddress.sol";
import "src/shared/libs/LibMath.sol";
import "src/shared/signal/ISignalService.sol";
import "./LibEIP1559.sol";
import "./LibL2Config.sol";
import "./IBlockHashProvider.sol";
import "./TaikoAnchorDeprecated.sol";
/// @title TaikoAnchor
/// @notice Taiko L2 is a smart contract that handles cross-layer message
/// verification and manages EIP-1559 gas pricing for Layer 2 (L2) operations.
/// It is used to anchor the latest L1 block details to L2 for cross-layer
/// communication, manage EIP-1559 parameters for gas pricing, and store
/// verified L1 block information.
/// @custom:security-contact security@taiko.xyz
contract TaikoAnchor is EssentialContract, IBlockHashProvider, TaikoAnchorDeprecated {
using LibAddress for address;
using LibMath for uint256;
using SafeERC20 for IERC20;
/// @notice Golden touch address is the only address that can do the anchor transaction.
address public constant GOLDEN_TOUCH_ADDRESS = 0x0000777735367b36bC9B61C50022d9D0700dB4Ec;
ISignalService public immutable signalService;
uint64 public immutable pacayaForkHeight;
/// @notice Mapping from L2 block numbers to their block hashes. All L2 block hashes will
/// be saved in this mapping.
mapping(uint256 blockId => bytes32 blockHash) private _blockhashes;
/// @notice A hash to check the integrity of public inputs.
/// @dev Slot 2.
bytes32 public publicInputHash;
/// @notice The gas excess value used to calculate the base fee.
/// @dev Slot 3.
uint64 public parentGasExcess;
/// @notice The last synced L1 block height.
uint64 public lastSyncedBlock;
/// @notice The last L2 block's timestamp.
uint64 public parentTimestamp;
/// @notice The last L2 block's gas target.
uint64 public parentGasTarget;
/// @notice The L1's chain ID.
uint64 public l1ChainId;
uint256[46] private __gap;
/// @notice Emitted when the latest L1 block details are anchored to L2.
/// @param parentHash The hash of the parent block.
/// @param parentGasExcess The gas excess value used to calculate the base fee.
event Anchored(bytes32 parentHash, uint64 parentGasExcess);
/// @notice Emitted when the gas target has been updated.
/// @param oldGasTarget The previous gas target.
/// @param newGasTarget The new gas target.
/// @param oldGasExcess The previous gas excess.
/// @param newGasExcess The new gas excess.
/// @param basefee The base fee in this block.
event EIP1559Update(
uint64 oldGasTarget,
uint64 newGasTarget,
uint64 oldGasExcess,
uint64 newGasExcess,
uint256 basefee
);
error L2_BASEFEE_MISMATCH();
error L2_FORK_ERROR();
error L2_INVALID_L1_CHAIN_ID();
error L2_INVALID_L2_CHAIN_ID();
error L2_INVALID_SENDER();
error L2_PUBLIC_INPUT_HASH_MISMATCH();
error L2_TOO_LATE();
modifier onlyGoldenTouch() {
require(msg.sender == GOLDEN_TOUCH_ADDRESS, L2_INVALID_SENDER());
_;
}
constructor(
address _resolver,
address _signalService,
uint64 _pacayaForkHeight
)
EssentialContract(_resolver)
{
signalService = ISignalService(_signalService);
pacayaForkHeight = _pacayaForkHeight;
}
/// @notice Initializes the contract.
/// @param _owner The owner of this contract. msg.sender will be used if this value is zero.
/// @param _l1ChainId The ID of the base layer.
/// @param _initialGasExcess The initial parentGasExcess.
function init(
address _owner,
uint64 _l1ChainId,
uint64 _initialGasExcess
)
external
initializer
{
__Essential_init(_owner);
require(_l1ChainId != 0, L2_INVALID_L1_CHAIN_ID());
require(_l1ChainId != block.chainid, L2_INVALID_L1_CHAIN_ID());
require(block.chainid > 1, L2_INVALID_L2_CHAIN_ID());
require(block.chainid <= type(uint64).max, L2_INVALID_L2_CHAIN_ID());
if (block.number == 0) {
// This is the case in real L2 genesis
} else if (block.number == 1) {
// This is the case in tests
uint256 parentHeight = block.number - 1;
_blockhashes[parentHeight] = blockhash(parentHeight);
} else {
revert L2_TOO_LATE();
}
l1ChainId = _l1ChainId;
parentGasExcess = _initialGasExcess;
(publicInputHash,) = _calcPublicInputHash(block.number);
}
/// @notice Anchors the latest L1 block details to L2 for cross-layer
/// message verification.
/// @dev The gas limit for this transaction must be set to 1,000,000 gas.
/// @dev This function can be called freely as the golden touch private key is publicly known,
/// but the Taiko node guarantees the first transaction of each block is always this anchor
/// transaction, and any subsequent calls will revert with L2_PUBLIC_INPUT_HASH_MISMATCH.
/// @param _anchorBlockId The `anchorBlockId` value in this block's metadata.
/// @param _anchorStateRoot The state root for the L1 block with id equals `_anchorBlockId`.
/// @param _parentGasUsed The gas used in the parent block.
/// @param _baseFeeConfig The base fee configuration.
/// @param _signalSlots The signal slots to mark as received.
function anchorV3(
uint64 _anchorBlockId,
bytes32 _anchorStateRoot,
uint32 _parentGasUsed,
LibSharedData.BaseFeeConfig calldata _baseFeeConfig,
bytes32[] calldata _signalSlots
)
external
nonZeroBytes32(_anchorStateRoot)
nonZeroValue(_anchorBlockId)
nonZeroValue(_baseFeeConfig.gasIssuancePerSecond)
nonZeroValue(_baseFeeConfig.adjustmentQuotient)
onlyGoldenTouch
nonReentrant
{
require(block.number >= pacayaForkHeight, L2_FORK_ERROR());
uint256 parentId = block.number - 1;
_verifyAndUpdatePublicInputHash(parentId);
_verifyBaseFeeAndUpdateGasExcess(_parentGasUsed, _baseFeeConfig);
_syncChainData(_anchorBlockId, _anchorStateRoot);
_updateParentHashAndTimestamp(parentId);
signalService.receiveSignals(_signalSlots);
}
/// @notice Anchors the latest L1 block details to L2 for cross-layer
/// message verification.
/// @dev The gas limit for this transaction must be set to 250,000 gas.
/// @dev This function can be called freely as the golden touch private key is publicly known,
/// but the Taiko node guarantees the first transaction of each block is always this anchor
/// transaction, and any subsequent calls will revert with L2_PUBLIC_INPUT_HASH_MISMATCH.
/// @param _anchorBlockId The `anchorBlockId` value in this block's metadata.
/// @param _anchorStateRoot The state root for the L1 block with id equals `_anchorBlockId`.
/// @param _parentGasUsed The gas used in the parent block.
/// @param _baseFeeConfig The base fee configuration.
function anchorV2(
uint64 _anchorBlockId,
bytes32 _anchorStateRoot,
uint32 _parentGasUsed,
LibSharedData.BaseFeeConfig calldata _baseFeeConfig
)
external
nonZeroBytes32(_anchorStateRoot)
nonZeroValue(_anchorBlockId)
nonZeroValue(_baseFeeConfig.gasIssuancePerSecond)
nonZeroValue(_baseFeeConfig.adjustmentQuotient)
onlyGoldenTouch
nonReentrant
{
require(block.number < pacayaForkHeight, L2_FORK_ERROR());
uint256 parentId = block.number - 1;
_verifyAndUpdatePublicInputHash(parentId);
_verifyBaseFeeAndUpdateGasExcess(_parentGasUsed, _baseFeeConfig);
_syncChainData(_anchorBlockId, _anchorStateRoot);
_updateParentHashAndTimestamp(parentId);
}
/// @notice Withdraw token or Ether from this address.
/// Note: This contract receives a portion of L2 base fees, while the remainder is directed to
/// L2 block's coinbase address.
/// @param _token Token address or address(0) if Ether.
/// @param _to Withdraw to address.
function withdraw(
address _token,
address _to
)
external
nonZeroAddr(_to)
whenNotPaused
onlyFromOwnerOrNamed(LibStrings.B_WITHDRAWER)
nonReentrant
{
if (_token == address(0)) {
_to.sendEtherAndVerify(address(this).balance);
} else {
IERC20(_token).safeTransfer(_to, IERC20(_token).balanceOf(address(this)));
}
}
/// @notice Calculates the base fee and gas excess using EIP-1559 configuration for the given
/// parameters.
/// @param _parentGasUsed Gas used in the parent block.
/// @param _baseFeeConfig Configuration parameters for base fee calculation.
/// @return basefee_ The calculated EIP-1559 base fee per gas.
/// @return newGasTarget_ The new gas target value.
/// @return newGasExcess_ The new gas excess value.
function getBasefeeV2(
uint32 _parentGasUsed,
uint64 _blockTimestamp,
LibSharedData.BaseFeeConfig calldata _baseFeeConfig
)
public
view
returns (uint256 basefee_, uint64 newGasTarget_, uint64 newGasExcess_)
{
// uint32 * uint8 will never overflow
uint64 newGasTarget =
uint64(_baseFeeConfig.gasIssuancePerSecond) * _baseFeeConfig.adjustmentQuotient;
(newGasTarget_, newGasExcess_) =
LibEIP1559.adjustExcess(parentGasTarget, newGasTarget, parentGasExcess);
uint64 gasIssuance =
(_blockTimestamp - parentTimestamp) * _baseFeeConfig.gasIssuancePerSecond;
if (
_baseFeeConfig.maxGasIssuancePerBlock != 0
&& gasIssuance > _baseFeeConfig.maxGasIssuancePerBlock
) {
gasIssuance = _baseFeeConfig.maxGasIssuancePerBlock;
}
(basefee_, newGasExcess_) = LibEIP1559.calc1559BaseFee(
newGasTarget_, newGasExcess_, gasIssuance, _parentGasUsed, _baseFeeConfig.minGasExcess
);
}
/// @inheritdoc IBlockHashProvider
function getBlockHash(uint256 _blockId) public view returns (bytes32) {
if (_blockId >= block.number) return 0;
if (_blockId + 256 >= block.number) return blockhash(_blockId);
return _blockhashes[_blockId];
}
/// @notice Determines the operational layer of the contract, whether it is on Layer 1 (L1) or
/// Layer 2 (L2).
/// @return True if the contract is operating on L1, false if on L2.
function isOnL1() external pure returns (bool) {
return false;
}
/// @notice Tells if we need to validate basefee (for simulation).
/// @return Returns true to skip checking basefee mismatch.
function skipFeeCheck() public pure virtual returns (bool) {
return false;
}
/// @dev Synchronizes chain data with the given anchor block ID and state root.
/// @param _anchorBlockId The ID of the anchor block.
/// @param _anchorStateRoot The state root of the anchor block.
function _syncChainData(uint64 _anchorBlockId, bytes32 _anchorStateRoot) private {
/// @dev If the anchor block ID is less than or equal to the last synced block, return
/// early.
if (_anchorBlockId <= lastSyncedBlock) return;
/// @dev Store the L1's state root as a signal to the local signal service to
/// allow for multi-hop bridging.
signalService.syncChainData(
l1ChainId, LibStrings.H_STATE_ROOT, _anchorBlockId, _anchorStateRoot
);
/// @dev Update the last synced block to the current anchor block ID.
lastSyncedBlock = _anchorBlockId;
}
/// @dev Updates the parent block hash and timestamp.
/// @param _parentId The ID of the parent block.
function _updateParentHashAndTimestamp(uint256 _parentId) private {
// Get the block hash of the parent block.
bytes32 parentHash = blockhash(_parentId);
// Store the parent block hash in the _blockhashes mapping.
_blockhashes[_parentId] = parentHash;
// Update the parent timestamp to the current block timestamp.
parentTimestamp = uint64(block.timestamp);
// Emit an event to signal that the parent hash and gas excess have been anchored.
emit Anchored(parentHash, parentGasExcess);
}
/// @dev Verifies the current ancestor block hash and updates it with a new aggregated hash.
/// @param _parentId The ID of the parent block.
function _verifyAndUpdatePublicInputHash(uint256 _parentId) private {
// Calculate the current and new ancestor hashes based on the parent block ID.
(bytes32 currPublicInputHash_, bytes32 newPublicInputHash_) =
_calcPublicInputHash(_parentId);
// Ensure the current ancestor block hash matches the expected value.
require(publicInputHash == currPublicInputHash_, L2_PUBLIC_INPUT_HASH_MISMATCH());
// Update the ancestor block hash to the new calculated value.
publicInputHash = newPublicInputHash_;
}
/// @dev Verifies that the base fee per gas is correct and updates the gas excess.
/// @param _parentGasUsed The gas used by the parent block.
/// @param _baseFeeConfig The configuration parameters for calculating the base fee.
function _verifyBaseFeeAndUpdateGasExcess(
uint32 _parentGasUsed,
LibSharedData.BaseFeeConfig calldata _baseFeeConfig
)
private
{
(uint256 basefee, uint64 newGasTarget, uint64 newGasExcess) =
getBasefeeV2(_parentGasUsed, uint64(block.timestamp), _baseFeeConfig);
require(block.basefee == basefee || skipFeeCheck(), L2_BASEFEE_MISMATCH());
emit EIP1559Update(parentGasTarget, newGasTarget, parentGasExcess, newGasExcess, basefee);
parentGasTarget = newGasTarget;
parentGasExcess = newGasExcess;
}
/// @dev Calculates the aggregated ancestor block hash for the given block ID.
/// @dev This function computes two public input hashes: one for the previous state and one for
/// the new state.
/// It uses a ring buffer to store the previous 255 block hashes and the current chain ID.
/// @param _blockId The ID of the block for which the public input hash is calculated.
/// @return currPublicInputHash_ The public input hash for the previous state.
/// @return newPublicInputHash_ The public input hash for the new state.
function _calcPublicInputHash(uint256 _blockId)
private
view
returns (bytes32 currPublicInputHash_, bytes32 newPublicInputHash_)
{
// 255 bytes32 ring buffer + 1 bytes32 for chainId
bytes32[256] memory inputs;
inputs[255] = bytes32(block.chainid);
// Unchecked is safe because it cannot overflow.
unchecked {
// Put the previous 255 blockhashes (excluding the parent's) into a
// ring buffer.
for (uint256 i; i < 255 && _blockId >= i + 1; ++i) {
uint256 j = _blockId - i - 1;
inputs[j % 255] = blockhash(j);
}
}
assembly {
currPublicInputHash_ := keccak256(inputs, 8192 /*mul(256, 32)*/ )
}
inputs[_blockId % 255] = blockhash(_blockId);
assembly {
newPublicInputHash_ := keccak256(inputs, 8192 /*mul(256, 32)*/ )
}
}
}
contracts/layer2/based/IBlockHashProvider.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title IBlockHashProvider
/// @notice Interface for retrieving block hashes.
interface IBlockHashProvider {
/// @notice Retrieves the block hash for a given block ID.
/// @param blockId The ID of the block whose hash is being requested.
/// @return _ The block hash of the specified block ID, or 0 if no hash is found.
function getBlockHash(uint256 blockId) external view returns (bytes32);
}
contracts/layer2/based/LibEIP1559.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@solady/src/utils/FixedPointMathLib.sol";
import "src/shared/libs/LibMath.sol";
/// @title LibEIP1559
/// @notice Implements e^(x) based bonding curve for EIP-1559
/// @dev See https://ethresear.ch/t/make-eip-1559-more-like-an-amm-curve/9082 but some minor
/// difference as stated in docs/eip1559_on_l2.md.
/// @custom:security-contact security@taiko.xyz
library LibEIP1559 {
using LibMath for uint256;
/// @notice The maximum allowable input value for the exp() function.
uint128 public constant MAX_EXP_INPUT = 135_305_999_368_893_231_588;
/// @notice Calculates the base fee and gas excess for EIP-1559
/// @param _gasTarget The target gas usage
/// @param _gasExcess The current gas excess
/// @param _gasIssuance The gas issuance
/// @param _parentGasUsed The gas used by the parent block
/// @param _minGasExcess The minimum gas excess
/// @return basefee_ The calculated base fee
/// @return gasExcess_ The calculated gas excess
function calc1559BaseFee(
uint64 _gasTarget,
uint64 _gasExcess,
uint64 _gasIssuance,
uint32 _parentGasUsed,
uint64 _minGasExcess
)
internal
pure
returns (uint256 basefee_, uint64 gasExcess_)
{
// We always add the gas used by parent block to the gas excess
// value as this has already happened
uint256 excess = uint256(_gasExcess) + _parentGasUsed;
excess = excess > _gasIssuance ? excess - _gasIssuance : 1;
gasExcess_ = uint64(excess.max(_minGasExcess).min(type(uint64).max));
// The base fee per gas used by this block is the spot price at the
// bonding curve, regardless the actual amount of gas used by this
// block, however, this block's gas used will affect the next
// block's base fee.
basefee_ = basefee(_gasTarget, gasExcess_);
}
/// @dev Adjusts the gas excess to maintain the same base fee when the gas target changes.
/// The formula used for adjustment is:
/// `_newGasTarget*ln(_newGasTarget/_gasTarget)+_gasExcess*_newGasTarget/_gasTarget`
/// @param _oldGasTarget The current gas target.
/// @param _newGasTarget The new gas target.
/// @param _oldGasExcess The current gas excess.
/// @return newGasTarget_ The new gas target value.
/// @return newGasExcess_ The new gas excess value.
function adjustExcess(
uint64 _oldGasTarget,
uint64 _newGasTarget,
uint64 _oldGasExcess
)
internal
pure
returns (uint64 newGasTarget_, uint64 newGasExcess_)
{
uint256 f = FixedPointMathLib.WAD;
if (_oldGasTarget == 0) {
return (_newGasTarget, _oldGasExcess);
}
if (
_newGasTarget == 0 || _oldGasTarget == _newGasTarget
|| _newGasTarget >= type(uint256).max / f
) {
return (_oldGasTarget, _oldGasExcess);
}
uint256 ratio = f * _newGasTarget / _oldGasTarget;
if (ratio == 0 || ratio > uint256(type(int256).max)) {
return (_newGasTarget, _oldGasExcess);
}
int256 lnRatio = FixedPointMathLib.lnWad(int256(ratio)); // may be negative
uint256 newGasExcess;
assembly {
// compute x = (_newGasTarget * lnRatio + _gasExcess * ratio)
let x := add(mul(_newGasTarget, lnRatio), mul(_oldGasExcess, ratio))
// If x < 0, set newGasExcess to 0, otherwise calculate newGasExcess = x / f
switch slt(x, 0)
case 1 { newGasExcess := 0 }
default { newGasExcess := div(x, f) }
}
return (_newGasTarget, newGasExcess.capToUint64());
}
/// @dev Calculates the base fee using the formula: exp(_gasExcess/_gasTarget)/_gasTarget
/// @param _gasTarget The current gas target.
/// @param _gasExcess The current gas excess.
/// @return The calculated base fee.
function basefee(uint64 _gasTarget, uint64 _gasExcess) internal pure returns (uint256) {
if (_gasTarget == 0) return 1;
return (ethQty(_gasTarget, _gasExcess) / _gasTarget).max(1);
}
/// @dev Calculates the exponential of the ratio of gas excess to gas target.
/// @param _gasTarget The current gas target.
/// @param _gasExcess The current gas excess.
/// @return The calculated exponential value.
function ethQty(uint64 _gasTarget, uint64 _gasExcess) internal pure returns (uint256) {
assert(_gasTarget != 0);
uint256 input = FixedPointMathLib.WAD * _gasExcess / _gasTarget;
if (input > MAX_EXP_INPUT) {
input = MAX_EXP_INPUT;
}
return uint256(FixedPointMathLib.expWad(int256(input))) / FixedPointMathLib.WAD;
}
}
contracts/layer2/based/LibL2Config.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @dev DEPRECATED but used by node/client for syncing old blocks
/// @title LibL2Config
library LibL2Config {
struct Config {
uint32 gasTargetPerL1Block;
uint8 basefeeAdjustmentQuotient;
}
/// @notice Returns EIP1559 related configurations.
/// @return config_ struct containing configuration parameters.
function get() internal pure returns (Config memory config_) {
// Assuming we sell 3x more blockspace than Ethereum: 15_000_000 * 4
// Note that Brecht's concern is that this value may be too large.
// We need to monitor L2 state growth and lower this value when necessary.
config_.gasTargetPerL1Block = 60_000_000;
config_.basefeeAdjustmentQuotient = 8;
}
}
contracts/layer2/based/TaikoAnchorDeprecated.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "src/shared/based/LibSharedData.sol";
/// @title TaikoAnchorDeprecated
/// @notice This contract includes deprecated functions whose ABI are still used by client for old
/// blocks.
/// @custom:security-contact security@taiko.xyz
abstract contract TaikoAnchorDeprecated {
error L2_DEPRECATED_METHOD();
modifier deprecated() {
revert L2_DEPRECATED_METHOD();
_;
}
function anchor(
bytes32 _l1BlockHash,
bytes32 _l1StateRoot,
uint64 _l1BlockId,
uint32 _parentGasUsed
)
external
deprecated
{ }
function getBasefee(
uint64 _anchorBlockId,
uint32 _parentGasUsed
)
public
pure
deprecated
returns (uint256 basefee_, uint64 parentGasExcess_)
{ }
function adjustExcess(
uint64 _currGasExcess,
uint64 _currGasTarget,
uint64 _newGasTarget
)
public
pure
deprecated
returns (uint64 newGasExcess_)
{ }
function calculateBaseFee(
LibSharedData.BaseFeeConfig calldata _baseFeeConfig,
uint64 _blocktime,
uint64 _parentGasExcess,
uint32 _parentGasUsed
)
public
pure
deprecated
returns (uint256 basefee_, uint64 parentGasExcess_)
{ }
}
contracts/shared/based/ITaiko.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title ITaiko
/// @notice This interface is used for contracts identified by the "taiko" label in the address
/// resolver, specifically the TaikoInbox and TaikoAnchor contracts.
/// @custom:security-contact security@taiko.xyz
interface ITaiko {
/// @notice Determines the operational layer of the contract, whether it is on Layer 1 (L1) or
/// Layer 2 (L2).
/// @return True if the contract is operating on L1, false if on L2.
function isOnL1() external pure returns (bool);
}
contracts/shared/based/LibSharedData.sol
// 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;
}
}
contracts/shared/common/EssentialContract.sol
// 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/shared/common/IResolver.sol
// 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/shared/libs/LibAddress.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/// @title LibAddress
/// @dev Provides utilities for address-related operations.
/// @custom:security-contact security@taiko.xyz
library LibAddress {
error ETH_TRANSFER_FAILED();
/// @dev Sends Ether to the specified address. This method will not revert even if sending ether
/// fails.
/// This function is inspired by
/// https://github.com/nomad-xyz/ExcessivelySafeCall/blob/main/src/ExcessivelySafeCall.sol
/// @param _to The recipient address.
/// @param _amount The amount of Ether to send in wei.
/// @param _gasLimit The max amount gas to pay for this transaction.
/// @return success_ true if the call is successful, false otherwise.
function sendEther(
address _to,
uint256 _amount,
uint256 _gasLimit,
bytes memory _calldata
)
internal
returns (bool success_)
{
// Check for zero-address transactions
require(_to != address(0), ETH_TRANSFER_FAILED());
// dispatch message to recipient
// by assembly calling "handle" function
// we call via assembly to avoid memcopying a very large returndata
// returned by a malicious contract
assembly {
success_ :=
call(
_gasLimit, // gas
_to, // recipient
_amount, // ether value
add(_calldata, 0x20), // inloc
mload(_calldata), // inlen
0, // outloc
0 // outlen
)
}
}
/// @dev Sends Ether to the specified address. This method will revert if sending ether fails.
/// @param _to The recipient address.
/// @param _amount The amount of Ether to send in wei.
/// @param _gasLimit The max amount gas to pay for this transaction.
function sendEtherAndVerify(address _to, uint256 _amount, uint256 _gasLimit) internal {
if (_amount == 0) return;
require(sendEther(_to, _amount, _gasLimit, ""), ETH_TRANSFER_FAILED());
}
/// @dev Sends Ether to the specified address. This method will revert if sending ether fails.
/// @param _to The recipient address.
/// @param _amount The amount of Ether to send in wei.
function sendEtherAndVerify(address _to, uint256 _amount) internal {
sendEtherAndVerify(_to, _amount, gasleft());
}
function supportsInterface(
address _addr,
bytes4 _interfaceId
)
internal
view
returns (bool result_)
{
(bool success, bytes memory data) =
_addr.staticcall(abi.encodeCall(IERC165.supportsInterface, (_interfaceId)));
if (success && data.length == 32) {
result_ = abi.decode(data, (bool));
}
}
}
contracts/shared/libs/LibMath.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title LibMath
/// @dev This library offers additional math functions for uint256.
/// @custom:security-contact security@taiko.xyz
library LibMath {
/// @dev Returns the smaller of the two given values.
/// @param _a The first number to compare.
/// @param _b The second number to compare.
/// @return The smaller of the two numbers.
function min(uint256 _a, uint256 _b) internal pure returns (uint256) {
return _a > _b ? _b : _a;
}
/// @dev Returns the larger of the two given values.
/// @param _a The first number to compare.
/// @param _b The second number to compare.
/// @return The larger of the two numbers.
function max(uint256 _a, uint256 _b) internal pure returns (uint256) {
return _a > _b ? _a : _b;
}
function capToUint64(uint256 _value) internal pure returns (uint64) {
return uint64(min(_value, type(uint64).max));
}
}
contracts/shared/libs/LibStrings.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title LibStrings
/// @custom:security-contact security@taiko.xyz
library LibStrings {
bytes32 internal constant B_AUTOMATA_DCAP_ATTESTATION = bytes32("automata_dcap_attestation");
bytes32 internal constant B_SGX_GETH_AUTOMATA = bytes32("sgx_geth_automata");
bytes32 internal constant B_BOND_TOKEN = bytes32("bond_token");
bytes32 internal constant B_BRIDGE = bytes32("bridge");
bytes32 internal constant B_BRIDGE_WATCHDOG = bytes32("bridge_watchdog");
bytes32 internal constant B_BRIDGED_ERC1155 = bytes32("bridged_erc1155");
bytes32 internal constant B_BRIDGED_ERC20 = bytes32("bridged_erc20");
bytes32 internal constant B_BRIDGED_ERC721 = bytes32("bridged_erc721");
bytes32 internal constant B_CHAIN_WATCHDOG = bytes32("chain_watchdog");
bytes32 internal constant B_ERC1155_VAULT = bytes32("erc1155_vault");
bytes32 internal constant B_ERC20_VAULT = bytes32("erc20_vault");
bytes32 internal constant B_ERC721_VAULT = bytes32("erc721_vault");
bytes32 internal constant B_FORCED_INCLUSION_STORE = bytes32("forced_inclusion_store");
bytes32 internal constant B_PRECONF_WHITELIST = bytes32("preconf_whitelist");
bytes32 internal constant B_PRECONF_WHITELIST_OWNER = bytes32("preconf_whitelist_owner");
bytes32 internal constant B_PRECONF_ROUTER = bytes32("preconf_router");
bytes32 internal constant B_TAIKO_WRAPPER = bytes32("taiko_wrapper");
bytes32 internal constant B_PROOF_VERIFIER = bytes32("proof_verifier");
bytes32 internal constant B_SGX_RETH_VERIFIER = bytes32("sgx_reth_verifier");
bytes32 internal constant B_SGX_GETH_VERIFIER = bytes32("sgx_geth_verifier");
bytes32 internal constant B_RISC0_RETH_VERIFIER = bytes32("risc0_reth_verifier");
bytes32 internal constant B_SP1_RETH_VERIFIER = bytes32("sp1_reth_verifier");
bytes32 internal constant B_PROVER_SET = bytes32("prover_set");
bytes32 internal constant B_QUOTA_MANAGER = bytes32("quota_manager");
bytes32 internal constant B_SIGNAL_SERVICE = bytes32("signal_service");
bytes32 internal constant B_TAIKO = bytes32("taiko");
bytes32 internal constant B_TAIKO_TOKEN = bytes32("taiko_token");
bytes32 internal constant B_WITHDRAWER = bytes32("withdrawer");
bytes32 internal constant H_SIGNAL_ROOT = keccak256("SIGNAL_ROOT");
bytes32 internal constant H_STATE_ROOT = keccak256("STATE_ROOT");
}
contracts/shared/signal/ISignalService.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title ISignalService
/// @notice The SignalService contract serves as a secure cross-chain message
/// passing system. It defines methods for sending and verifying signals with
/// merkle proofs. The trust assumption is that the target chain has secure
/// access to the merkle root (such as Taiko injects it in the anchor
/// transaction). With this, verifying a signal is reduced to simply verifying
/// a merkle proof.
/// @custom:security-contact security@taiko.xyz
interface ISignalService {
enum CacheOption {
CACHE_NOTHING,
CACHE_SIGNAL_ROOT,
CACHE_STATE_ROOT,
CACHE_BOTH
}
struct HopProof {
/// @notice This hop's destination chain ID. If there is a next hop, this ID is the next
/// hop's source chain ID.
uint64 chainId;
/// @notice The ID of a source chain block whose state root has been synced to the hop's
/// destination chain.
/// Note that this block ID must be greater than or equal to the block ID where the signal
/// was sent on the source chain.
uint64 blockId;
/// @notice The state root or signal root of the source chain at the above blockId. This
/// value has been synced to the destination chain.
/// @dev To get both the blockId and the rootHash, apps should subscribe to the
/// ChainDataSynced event or query `topBlockId` first using the source chain's ID and
/// LibStrings.H_STATE_ROOT to get the most recent block ID synced, then call
/// `getSyncedChainData` to read the synchronized data.
bytes32 rootHash;
/// @notice Options to cache either the state roots or signal roots of middle-hops to the
/// current chain.
CacheOption cacheOption;
/// @notice The signal service's account proof. If this value is empty, then `rootHash` will
/// be used as the signal root, otherwise, `rootHash` will be used as the state root.
bytes[] accountProof;
/// @notice The signal service's storage proof.
bytes[] storageProof;
}
/// @notice Emitted when a remote chain's state root or signal root is
/// synced locally as a signal.
/// @param chainId The remote chainId.
/// @param blockId The chain data's corresponding blockId.
/// @param kind A value to mark the data type.
/// @param data The remote data.
/// @param signal The signal for this chain data.
event ChainDataSynced(
uint64 indexed chainId,
uint64 indexed blockId,
bytes32 indexed kind,
bytes32 data,
bytes32 signal
);
/// @notice Emitted when signals are received directly by TaikoL2 in its Anchor transaction.
/// @param signalSlots The signal slots that were received.
event SignalsReceived(bytes32[] signalSlots);
/// @notice Emitted when a signal is sent.
/// @param app The address that initiated the signal.
/// @param signal The signal (message) that was sent.
/// @param slot The location in storage where this signal is stored.
/// @param value The value of the signal.
event SignalSent(address app, bytes32 signal, bytes32 slot, bytes32 value);
/// @notice Emitted when an address is authorized or deauthorized.
/// @param addr The address to be authorized or deauthorized.
/// @param authorized True if authorized, false otherwise.
event Authorized(address indexed addr, bool authorized);
/// @dev Allow TaikoL2 to receive signals directly in its Anchor transaction.
/// @param _signalSlots The signal slots to mark as received.
function receiveSignals(bytes32[] calldata _signalSlots) external;
/// @notice Send a signal (message) by setting the storage slot to the same value as the signal
/// itself.
/// @param _signal The signal (message) to send.
/// @return slot_ The location in storage where this signal is stored.
function sendSignal(bytes32 _signal) external returns (bytes32 slot_);
/// @notice Sync a data from a remote chain locally as a signal. The signal is calculated
/// uniquely from chainId, kind, and data.
/// @param _chainId The remote chainId.
/// @param _kind A value to mark the data type.
/// @param _blockId The chain data's corresponding blockId
/// @param _chainData The remote data.
/// @return signal_ The signal for this chain data.
function syncChainData(
uint64 _chainId,
bytes32 _kind,
uint64 _blockId,
bytes32 _chainData
)
external
returns (bytes32 signal_);
/// @notice Verifies if a signal has been received on the target chain.
/// @param _chainId The identifier for the source chain from which the
/// signal originated.
/// @param _app The address that initiated the signal.
/// @param _signal The signal (message) to send.
/// @param _proof Merkle proof that the signal was persisted on the
/// source chain. If this proof is empty, then we check if this signal has been marked as
/// received by TaikoL2.
/// @return numCacheOps_ The number of newly cached items.
function proveSignalReceived(
uint64 _chainId,
address _app,
bytes32 _signal,
bytes calldata _proof
)
external
returns (uint256 numCacheOps_);
/// @notice Verifies if a signal has been received on the target chain.
/// This is the "readonly" version of proveSignalReceived.
/// @param _chainId The identifier for the source chain from which the
/// signal originated.
/// @param _app The address that initiated the signal.
/// @param _signal The signal (message) to send.
/// @param _proof Merkle proof that the signal was persisted on the
/// source chain. If this proof is empty, then we check if this signal has been marked as
/// received by TaikoL2.
function verifySignalReceived(
uint64 _chainId,
address _app,
bytes32 _signal,
bytes calldata _proof
)
external
view;
/// @notice Verifies if a particular signal has already been sent.
/// @param _app The address that initiated the signal.
/// @param _signal The signal (message) that was sent.
/// @return true if the signal has been sent, otherwise false.
function isSignalSent(address _app, bytes32 _signal) external view returns (bool);
/// @notice Verifies if a particular signal has already been sent.
/// @param _signalSlot The location in storage where this signal is stored.
function isSignalSent(bytes32 _signalSlot) external view returns (bool);
/// @notice Checks if a chain data has been synced.
/// @param _chainId The remote chainId.
/// @param _kind A value to mark the data type.
/// @param _blockId The chain data's corresponding blockId
/// @param _chainData The remote data.
/// @return true if the data has been synced, otherwise false.
function isChainDataSynced(
uint64 _chainId,
bytes32 _kind,
uint64 _blockId,
bytes32 _chainData
)
external
view
returns (bool);
/// @notice Returns the given block's chain data.
/// @param _chainId Identifier of the chainId.
/// @param _kind A value to mark the data type.
/// @param _blockId The chain data's corresponding block id. If this value is 0, use the top
/// block id.
/// @return blockId_ The actual block id.
/// @return chainData_ The synced chain data.
function getSyncedChainData(
uint64 _chainId,
bytes32 _kind,
uint64 _blockId
)
external
view
returns (uint64 blockId_, bytes32 chainData_);
/// @notice Returns the data to be used for caching slot generation.
/// @param _chainId Identifier of the chainId.
/// @param _kind A value to mark the data type.
/// @param _blockId The chain data's corresponding block id. If this value is 0, use the top
/// block id.
/// @return signal_ The signal used for caching slot creation.
function signalForChainData(
uint64 _chainId,
bytes32 _kind,
uint64 _blockId
)
external
pure
returns (bytes32 signal_);
}
node_modules/@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol
// 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;
}
node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol
// 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
// 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-upgradeable/utils/AddressUpgradeable.sol
// 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 AddressUpgradeable {
/**
* @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,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
import {Initializable} from "../proxy/utils/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;
}
/**
* @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[50] private __gap;
}
node_modules/@openzeppelin/contracts/interfaces/IERC1967.sol
// 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/interfaces/draft-IERC1822.sol
// 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
// 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/proxy/beacon/IBeacon.sol
// 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/proxy/utils/UUPSUpgradeable.sol
// 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/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
node_modules/@openzeppelin/contracts/utils/Address.sol
// 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,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
node_modules/@openzeppelin/contracts/utils/StorageSlot.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.0;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```solidity
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
* _Available since v4.9 for `string`, `bytes`._
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
/**
* @dev Returns an `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
}
node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
node_modules/solady/src/utils/FixedPointMathLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
library FixedPointMathLib {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The operation failed, as the output exceeds the maximum value of uint256.
error ExpOverflow();
/// @dev The operation failed, as the output exceeds the maximum value of uint256.
error FactorialOverflow();
/// @dev The operation failed, due to an overflow.
error RPowOverflow();
/// @dev The mantissa is too big to fit.
error MantissaOverflow();
/// @dev The operation failed, due to an multiplication overflow.
error MulWadFailed();
/// @dev The operation failed, due to an multiplication overflow.
error SMulWadFailed();
/// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.
error DivWadFailed();
/// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.
error SDivWadFailed();
/// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.
error MulDivFailed();
/// @dev The division failed, as the denominator is zero.
error DivFailed();
/// @dev The full precision multiply-divide operation failed, either due
/// to the result being larger than 256 bits, or a division by a zero.
error FullMulDivFailed();
/// @dev The output is undefined, as the input is less-than-or-equal to zero.
error LnWadUndefined();
/// @dev The input outside the acceptable domain.
error OutOfDomain();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CONSTANTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The scalar of ETH and most ERC20s.
uint256 internal constant WAD = 1e18;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* SIMPLIFIED FIXED POINT OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Equivalent to `(x * y) / WAD` rounded down.
function mulWad(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.
if mul(y, gt(x, div(not(0), y))) {
mstore(0x00, 0xbac65e5b) // `MulWadFailed()`.
revert(0x1c, 0x04)
}
z := div(mul(x, y), WAD)
}
}
/// @dev Equivalent to `(x * y) / WAD` rounded down.
function sMulWad(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mul(x, y)
// Equivalent to `require((x == 0 || z / x == y) && !(x == -1 && y == type(int256).min))`.
if iszero(gt(or(iszero(x), eq(sdiv(z, x), y)), lt(not(x), eq(y, shl(255, 1))))) {
mstore(0x00, 0xedcd4dd4) // `SMulWadFailed()`.
revert(0x1c, 0x04)
}
z := sdiv(z, WAD)
}
}
/// @dev Equivalent to `(x * y) / WAD` rounded down, but without overflow checks.
function rawMulWad(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := div(mul(x, y), WAD)
}
}
/// @dev Equivalent to `(x * y) / WAD` rounded down, but without overflow checks.
function rawSMulWad(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := sdiv(mul(x, y), WAD)
}
}
/// @dev Equivalent to `(x * y) / WAD` rounded up.
function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.
if mul(y, gt(x, div(not(0), y))) {
mstore(0x00, 0xbac65e5b) // `MulWadFailed()`.
revert(0x1c, 0x04)
}
z := add(iszero(iszero(mod(mul(x, y), WAD))), div(mul(x, y), WAD))
}
}
/// @dev Equivalent to `(x * y) / WAD` rounded up, but without overflow checks.
function rawMulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := add(iszero(iszero(mod(mul(x, y), WAD))), div(mul(x, y), WAD))
}
}
/// @dev Equivalent to `(x * WAD) / y` rounded down.
function divWad(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`.
if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) {
mstore(0x00, 0x7c5f487d) // `DivWadFailed()`.
revert(0x1c, 0x04)
}
z := div(mul(x, WAD), y)
}
}
/// @dev Equivalent to `(x * WAD) / y` rounded down.
function sDivWad(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mul(x, WAD)
// Equivalent to `require(y != 0 && ((x * WAD) / WAD == x))`.
if iszero(and(iszero(iszero(y)), eq(sdiv(z, WAD), x))) {
mstore(0x00, 0x5c43740d) // `SDivWadFailed()`.
revert(0x1c, 0x04)
}
z := sdiv(mul(x, WAD), y)
}
}
/// @dev Equivalent to `(x * WAD) / y` rounded down, but without overflow and divide by zero checks.
function rawDivWad(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := div(mul(x, WAD), y)
}
}
/// @dev Equivalent to `(x * WAD) / y` rounded down, but without overflow and divide by zero checks.
function rawSDivWad(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := sdiv(mul(x, WAD), y)
}
}
/// @dev Equivalent to `(x * WAD) / y` rounded up.
function divWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`.
if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) {
mstore(0x00, 0x7c5f487d) // `DivWadFailed()`.
revert(0x1c, 0x04)
}
z := add(iszero(iszero(mod(mul(x, WAD), y))), div(mul(x, WAD), y))
}
}
/// @dev Equivalent to `(x * WAD) / y` rounded up, but without overflow and divide by zero checks.
function rawDivWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := add(iszero(iszero(mod(mul(x, WAD), y))), div(mul(x, WAD), y))
}
}
/// @dev Equivalent to `x` to the power of `y`.
/// because `x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)`.
/// Note: This function is an approximation.
function powWad(int256 x, int256 y) internal pure returns (int256) {
// Using `ln(x)` means `x` must be greater than 0.
return expWad((lnWad(x) * y) / int256(WAD));
}
/// @dev Returns `exp(x)`, denominated in `WAD`.
/// Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln
/// Note: This function is an approximation. Monotonically increasing.
function expWad(int256 x) internal pure returns (int256 r) {
unchecked {
// When the result is less than 0.5 we return zero.
// This happens when `x <= (log(1e-18) * 1e18) ~ -4.15e19`.
if (x <= -41446531673892822313) return r;
/// @solidity memory-safe-assembly
assembly {
// When the result is greater than `(2**255 - 1) / 1e18` we can not represent it as
// an int. This happens when `x >= floor(log((2**255 - 1) / 1e18) * 1e18) ≈ 135`.
if iszero(slt(x, 135305999368893231589)) {
mstore(0x00, 0xa37bfec9) // `ExpOverflow()`.
revert(0x1c, 0x04)
}
}
// `x` is now in the range `(-42, 136) * 1e18`. Convert to `(-42, 136) * 2**96`
// for more intermediate precision and a binary basis. This base conversion
// is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.
x = (x << 78) / 5 ** 18;
// Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers
// of two such that exp(x) = exp(x') * 2**k, where k is an integer.
// Solving this gives k = round(x / log(2)) and x' = x - k * log(2).
int256 k = ((x << 96) / 54916777467707473351141471128 + 2 ** 95) >> 96;
x = x - k * 54916777467707473351141471128;
// `k` is in the range `[-61, 195]`.
// Evaluate using a (6, 7)-term rational approximation.
// `p` is made monic, we'll multiply by a scale factor later.
int256 y = x + 1346386616545796478920950773328;
y = ((y * x) >> 96) + 57155421227552351082224309758442;
int256 p = y + x - 94201549194550492254356042504812;
p = ((p * y) >> 96) + 28719021644029726153956944680412240;
p = p * x + (4385272521454847904659076985693276 << 96);
// We leave `p` in `2**192` basis so we don't need to scale it back up for the division.
int256 q = x - 2855989394907223263936484059900;
q = ((q * x) >> 96) + 50020603652535783019961831881945;
q = ((q * x) >> 96) - 533845033583426703283633433725380;
q = ((q * x) >> 96) + 3604857256930695427073651918091429;
q = ((q * x) >> 96) - 14423608567350463180887372962807573;
q = ((q * x) >> 96) + 26449188498355588339934803723976023;
/// @solidity memory-safe-assembly
assembly {
// Div in assembly because solidity adds a zero check despite the unchecked.
// The q polynomial won't have zeros in the domain as all its roots are complex.
// No scaling is necessary because p is already `2**96` too large.
r := sdiv(p, q)
}
// r should be in the range `(0.09, 0.25) * 2**96`.
// We now need to multiply r by:
// - The scale factor `s ≈ 6.031367120`.
// - The `2**k` factor from the range reduction.
// - The `1e18 / 2**96` factor for base conversion.
// We do this all at once, with an intermediate result in `2**213`
// basis, so the final right shift is always by a positive amount.
r = int256(
(uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k)
);
}
}
/// @dev Returns `ln(x)`, denominated in `WAD`.
/// Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln
/// Note: This function is an approximation. Monotonically increasing.
function lnWad(int256 x) internal pure returns (int256 r) {
/// @solidity memory-safe-assembly
assembly {
// We want to convert `x` from `10**18` fixed point to `2**96` fixed point.
// We do this by multiplying by `2**96 / 10**18`. But since
// `ln(x * C) = ln(x) + ln(C)`, we can simply do nothing here
// and add `ln(2**96 / 10**18)` at the end.
// Compute `k = log2(x) - 96`, `r = 159 - k = 255 - log2(x) = 255 ^ log2(x)`.
r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(r, shl(3, lt(0xff, shr(r, x))))
// We place the check here for more optimal stack operations.
if iszero(sgt(x, 0)) {
mstore(0x00, 0x1615e638) // `LnWadUndefined()`.
revert(0x1c, 0x04)
}
// forgefmt: disable-next-item
r := xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff))
// Reduce range of x to (1, 2) * 2**96
// ln(2^k * x) = k * ln(2) + ln(x)
x := shr(159, shl(r, x))
// Evaluate using a (8, 8)-term rational approximation.
// `p` is made monic, we will multiply by a scale factor later.
// forgefmt: disable-next-item
let p := sub( // This heavily nested expression is to avoid stack-too-deep for via-ir.
sar(96, mul(add(43456485725739037958740375743393,
sar(96, mul(add(24828157081833163892658089445524,
sar(96, mul(add(3273285459638523848632254066296,
x), x))), x))), x)), 11111509109440967052023855526967)
p := sub(sar(96, mul(p, x)), 45023709667254063763336534515857)
p := sub(sar(96, mul(p, x)), 14706773417378608786704636184526)
p := sub(mul(p, x), shl(96, 795164235651350426258249787498))
// We leave `p` in `2**192` basis so we don't need to scale it back up for the division.
// `q` is monic by convention.
let q := add(5573035233440673466300451813936, x)
q := add(71694874799317883764090561454958, sar(96, mul(x, q)))
q := add(283447036172924575727196451306956, sar(96, mul(x, q)))
q := add(401686690394027663651624208769553, sar(96, mul(x, q)))
q := add(204048457590392012362485061816622, sar(96, mul(x, q)))
q := add(31853899698501571402653359427138, sar(96, mul(x, q)))
q := add(909429971244387300277376558375, sar(96, mul(x, q)))
// `p / q` is in the range `(0, 0.125) * 2**96`.
// Finalization, we need to:
// - Multiply by the scale factor `s = 5.549…`.
// - Add `ln(2**96 / 10**18)`.
// - Add `k * ln(2)`.
// - Multiply by `10**18 / 2**96 = 5**18 >> 78`.
// The q polynomial is known not to have zeros in the domain.
// No scaling required because p is already `2**96` too large.
p := sdiv(p, q)
// Multiply by the scaling factor: `s * 5**18 * 2**96`, base is now `5**18 * 2**192`.
p := mul(1677202110996718588342820967067443963516166, p)
// Add `ln(2) * k * 5**18 * 2**192`.
// forgefmt: disable-next-item
p := add(mul(16597577552685614221487285958193947469193820559219878177908093499208371, sub(159, r)), p)
// Add `ln(2**96 / 10**18) * 5**18 * 2**192`.
p := add(600920179829731861736702779321621459595472258049074101567377883020018308, p)
// Base conversion: mul `2**18 / 2**192`.
r := sar(174, p)
}
}
/// @dev Returns `W_0(x)`, denominated in `WAD`.
/// See: https://en.wikipedia.org/wiki/Lambert_W_function
/// a.k.a. Product log function. This is an approximation of the principal branch.
/// Note: This function is an approximation. Monotonically increasing.
function lambertW0Wad(int256 x) internal pure returns (int256 w) {
// forgefmt: disable-next-item
unchecked {
if ((w = x) <= -367879441171442322) revert OutOfDomain(); // `x` less than `-1/e`.
int256 wad = int256(WAD);
int256 p = x;
uint256 c; // Whether we need to avoid catastrophic cancellation.
uint256 i = 4; // Number of iterations.
if (w <= 0x1ffffffffffff) {
if (-0x4000000000000 <= w) {
i = 1; // Inputs near zero only take one step to converge.
} else if (w <= -0x3ffffffffffffff) {
i = 32; // Inputs near `-1/e` take very long to converge.
}
} else if (uint256(w >> 63) == uint256(0)) {
/// @solidity memory-safe-assembly
assembly {
// Inline log2 for more performance, since the range is small.
let v := shr(49, w)
let l := shl(3, lt(0xff, v))
l := add(or(l, byte(and(0x1f, shr(shr(l, v), 0x8421084210842108cc6318c6db6d54be)),
0x0706060506020504060203020504030106050205030304010505030400000000)), 49)
w := sdiv(shl(l, 7), byte(sub(l, 31), 0x0303030303030303040506080c13))
c := gt(l, 60)
i := add(2, add(gt(l, 53), c))
}
} else {
int256 ll = lnWad(w = lnWad(w));
/// @solidity memory-safe-assembly
assembly {
// `w = ln(x) - ln(ln(x)) + b * ln(ln(x)) / ln(x)`.
w := add(sdiv(mul(ll, 1023715080943847266), w), sub(w, ll))
i := add(3, iszero(shr(68, x)))
c := iszero(shr(143, x))
}
if (c == uint256(0)) {
do { // If `x` is big, use Newton's so that intermediate values won't overflow.
int256 e = expWad(w);
/// @solidity memory-safe-assembly
assembly {
let t := mul(w, div(e, wad))
w := sub(w, sdiv(sub(t, x), div(add(e, t), wad)))
}
if (p <= w) break;
p = w;
} while (--i != uint256(0));
/// @solidity memory-safe-assembly
assembly {
w := sub(w, sgt(w, 2))
}
return w;
}
}
do { // Otherwise, use Halley's for faster convergence.
int256 e = expWad(w);
/// @solidity memory-safe-assembly
assembly {
let t := add(w, wad)
let s := sub(mul(w, e), mul(x, wad))
w := sub(w, sdiv(mul(s, wad), sub(mul(e, t), sdiv(mul(add(t, wad), s), add(t, t)))))
}
if (p <= w) break;
p = w;
} while (--i != c);
/// @solidity memory-safe-assembly
assembly {
w := sub(w, sgt(w, 2))
}
// For certain ranges of `x`, we'll use the quadratic-rate recursive formula of
// R. Iacono and J.P. Boyd for the last iteration, to avoid catastrophic cancellation.
if (c == uint256(0)) return w;
int256 t = w | 1;
/// @solidity memory-safe-assembly
assembly {
x := sdiv(mul(x, wad), t)
}
x = (t * (wad + lnWad(x)));
/// @solidity memory-safe-assembly
assembly {
w := sdiv(x, add(wad, t))
}
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* GENERAL NUMBER UTILITIES */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Calculates `floor(x * y / d)` with full precision.
/// Throws if result overflows a uint256 or when `d` is zero.
/// Credit to Remco Bloemen under MIT license: https://2π.com/21/muldiv
function fullMulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
// 512-bit multiply `[p1 p0] = x * y`.
// Compute the product mod `2**256` and mod `2**256 - 1`
// then use the Chinese Remainder Theorem to reconstruct
// the 512 bit result. The result is stored in two 256
// variables such that `product = p1 * 2**256 + p0`.
// Temporarily use `result` as `p0` to save gas.
result := mul(x, y) // Lower 256 bits of `x * y`.
for {} 1 {} {
// If overflows.
if iszero(mul(or(iszero(x), eq(div(result, x), y)), d)) {
let mm := mulmod(x, y, not(0))
let p1 := sub(mm, add(result, lt(mm, result))) // Upper 256 bits of `x * y`.
/*------------------- 512 by 256 division --------------------*/
// Make division exact by subtracting the remainder from `[p1 p0]`.
let r := mulmod(x, y, d) // Compute remainder using mulmod.
let t := and(d, sub(0, d)) // The least significant bit of `d`. `t >= 1`.
// Make sure the result is less than `2**256`. Also prevents `d == 0`.
// Placing the check here seems to give more optimal stack operations.
if iszero(gt(d, p1)) {
mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.
revert(0x1c, 0x04)
}
d := div(d, t) // Divide `d` by `t`, which is a power of two.
// Invert `d mod 2**256`
// Now that `d` is an odd number, it has an inverse
// modulo `2**256` such that `d * inv = 1 mod 2**256`.
// Compute the inverse by starting with a seed that is correct
// correct for four bits. That is, `d * inv = 1 mod 2**4`.
let inv := xor(2, mul(3, d))
// Now use Newton-Raphson iteration to improve the precision.
// Thanks to Hensel's lifting lemma, this also works in modular
// arithmetic, doubling the correct bits in each step.
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**8
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**16
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**32
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**64
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**128
result :=
mul(
// Divide [p1 p0] by the factors of two.
// Shift in bits from `p1` into `p0`. For this we need
// to flip `t` such that it is `2**256 / t`.
or(
mul(sub(p1, gt(r, result)), add(div(sub(0, t), t), 1)),
div(sub(result, r), t)
),
mul(sub(2, mul(d, inv)), inv) // inverse mod 2**256
)
break
}
result := div(result, d)
break
}
}
}
/// @dev Calculates `floor(x * y / d)` with full precision.
/// Behavior is undefined if `d` is zero or the final result cannot fit in 256 bits.
/// Performs the full 512 bit calculation regardless.
function fullMulDivUnchecked(uint256 x, uint256 y, uint256 d)
internal
pure
returns (uint256 result)
{
/// @solidity memory-safe-assembly
assembly {
result := mul(x, y)
let mm := mulmod(x, y, not(0))
let p1 := sub(mm, add(result, lt(mm, result)))
let t := and(d, sub(0, d))
let r := mulmod(x, y, d)
d := div(d, t)
let inv := xor(2, mul(3, d))
inv := mul(inv, sub(2, mul(d, inv)))
inv := mul(inv, sub(2, mul(d, inv)))
inv := mul(inv, sub(2, mul(d, inv)))
inv := mul(inv, sub(2, mul(d, inv)))
inv := mul(inv, sub(2, mul(d, inv)))
result :=
mul(
or(mul(sub(p1, gt(r, result)), add(div(sub(0, t), t), 1)), div(sub(result, r), t)),
mul(sub(2, mul(d, inv)), inv)
)
}
}
/// @dev Calculates `floor(x * y / d)` with full precision, rounded up.
/// Throws if result overflows a uint256 or when `d` is zero.
/// Credit to Uniswap-v3-core under MIT license:
/// https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/FullMath.sol
function fullMulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 result) {
result = fullMulDiv(x, y, d);
/// @solidity memory-safe-assembly
assembly {
if mulmod(x, y, d) {
result := add(result, 1)
if iszero(result) {
mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.
revert(0x1c, 0x04)
}
}
}
}
/// @dev Returns `floor(x * y / d)`.
/// Reverts if `x * y` overflows, or `d` is zero.
function mulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mul(x, y)
// Equivalent to `require(d != 0 && (y == 0 || x <= type(uint256).max / y))`.
if iszero(mul(or(iszero(x), eq(div(z, x), y)), d)) {
mstore(0x00, 0xad251c27) // `MulDivFailed()`.
revert(0x1c, 0x04)
}
z := div(z, d)
}
}
/// @dev Returns `ceil(x * y / d)`.
/// Reverts if `x * y` overflows, or `d` is zero.
function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mul(x, y)
// Equivalent to `require(d != 0 && (y == 0 || x <= type(uint256).max / y))`.
if iszero(mul(or(iszero(x), eq(div(z, x), y)), d)) {
mstore(0x00, 0xad251c27) // `MulDivFailed()`.
revert(0x1c, 0x04)
}
z := add(iszero(iszero(mod(z, d))), div(z, d))
}
}
/// @dev Returns `ceil(x / d)`.
/// Reverts if `d` is zero.
function divUp(uint256 x, uint256 d) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
if iszero(d) {
mstore(0x00, 0x65244e4e) // `DivFailed()`.
revert(0x1c, 0x04)
}
z := add(iszero(iszero(mod(x, d))), div(x, d))
}
}
/// @dev Returns `max(0, x - y)`.
function zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mul(gt(x, y), sub(x, y))
}
}
/// @dev Returns `condition ? x : y`, without branching.
function ternary(bool condition, uint256 x, uint256 y) internal pure returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
result := xor(x, mul(xor(x, y), iszero(condition)))
}
}
/// @dev Exponentiate `x` to `y` by squaring, denominated in base `b`.
/// Reverts if the computation overflows.
function rpow(uint256 x, uint256 y, uint256 b) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mul(b, iszero(y)) // `0 ** 0 = 1`. Otherwise, `0 ** n = 0`.
if x {
z := xor(b, mul(xor(b, x), and(y, 1))) // `z = isEven(y) ? scale : x`
let half := shr(1, b) // Divide `b` by 2.
// Divide `y` by 2 every iteration.
for { y := shr(1, y) } y { y := shr(1, y) } {
let xx := mul(x, x) // Store x squared.
let xxRound := add(xx, half) // Round to the nearest number.
// Revert if `xx + half` overflowed, or if `x ** 2` overflows.
if or(lt(xxRound, xx), shr(128, x)) {
mstore(0x00, 0x49f7642b) // `RPowOverflow()`.
revert(0x1c, 0x04)
}
x := div(xxRound, b) // Set `x` to scaled `xxRound`.
// If `y` is odd:
if and(y, 1) {
let zx := mul(z, x) // Compute `z * x`.
let zxRound := add(zx, half) // Round to the nearest number.
// If `z * x` overflowed or `zx + half` overflowed:
if or(xor(div(zx, x), z), lt(zxRound, zx)) {
// Revert if `x` is non-zero.
if x {
mstore(0x00, 0x49f7642b) // `RPowOverflow()`.
revert(0x1c, 0x04)
}
}
z := div(zxRound, b) // Return properly scaled `zxRound`.
}
}
}
}
}
/// @dev Returns the square root of `x`, rounded down.
function sqrt(uint256 x) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// `floor(sqrt(2**15)) = 181`. `sqrt(2**15) - 181 = 2.84`.
z := 181 // The "correct" value is 1, but this saves a multiplication later.
// This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
// start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.
// Let `y = x / 2**r`. We check `y >= 2**(k + 8)`
// but shift right by `k` bits to ensure that if `x >= 256`, then `y >= 256`.
let r := shl(7, lt(0xffffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffffff, shr(r, x))))
z := shl(shr(1, r), z)
// Goal was to get `z*z*y` within a small factor of `x`. More iterations could
// get y in a tighter range. Currently, we will have y in `[256, 256*(2**16))`.
// We ensured `y >= 256` so that the relative difference between `y` and `y+1` is small.
// That's not possible if `x < 256` but we can just verify those cases exhaustively.
// Now, `z*z*y <= x < z*z*(y+1)`, and `y <= 2**(16+8)`, and either `y >= 256`, or `x < 256`.
// Correctness can be checked exhaustively for `x < 256`, so we assume `y >= 256`.
// Then `z*sqrt(y)` is within `sqrt(257)/sqrt(256)` of `sqrt(x)`, or about 20bps.
// For `s` in the range `[1/256, 256]`, the estimate `f(s) = (181/1024) * (s+1)`
// is in the range `(1/2.84 * sqrt(s), 2.84 * sqrt(s))`,
// with largest error when `s = 1` and when `s = 256` or `1/256`.
// Since `y` is in `[256, 256*(2**16))`, let `a = y/65536`, so that `a` is in `[1/256, 256)`.
// Then we can estimate `sqrt(y)` using
// `sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2**18`.
// There is no overflow risk here since `y < 2**136` after the first branch above.
z := shr(18, mul(z, add(shr(r, x), 65536))) // A `mul()` is saved from starting `z` at 181.
// Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
// If `x+1` is a perfect square, the Babylonian method cycles between
// `floor(sqrt(x))` and `ceil(sqrt(x))`. This statement ensures we return floor.
// See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
z := sub(z, lt(div(x, z), z))
}
}
/// @dev Returns the cube root of `x`, rounded down.
/// Credit to bout3fiddy and pcaversaccio under AGPLv3 license:
/// https://github.com/pcaversaccio/snekmate/blob/main/src/utils/Math.vy
/// Formally verified by xuwinnie:
/// https://github.com/vectorized/solady/blob/main/audits/xuwinnie-solady-cbrt-proof.pdf
function cbrt(uint256 x) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
let r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(r, shl(3, lt(0xff, shr(r, x))))
// Makeshift lookup table to nudge the approximate log2 result.
z := div(shl(div(r, 3), shl(lt(0xf, shr(r, x)), 0xf)), xor(7, mod(r, 3)))
// Newton-Raphson's.
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := div(add(add(div(x, mul(z, z)), z), z), 3)
// Round down.
z := sub(z, lt(div(x, mul(z, z)), z))
}
}
/// @dev Returns the square root of `x`, denominated in `WAD`, rounded down.
function sqrtWad(uint256 x) internal pure returns (uint256 z) {
unchecked {
if (x <= type(uint256).max / 10 ** 18) return sqrt(x * 10 ** 18);
z = (1 + sqrt(x)) * 10 ** 9;
z = (fullMulDivUnchecked(x, 10 ** 18, z) + z) >> 1;
}
/// @solidity memory-safe-assembly
assembly {
z := sub(z, gt(999999999999999999, sub(mulmod(z, z, x), 1))) // Round down.
}
}
/// @dev Returns the cube root of `x`, denominated in `WAD`, rounded down.
/// Formally verified by xuwinnie:
/// https://github.com/vectorized/solady/blob/main/audits/xuwinnie-solady-cbrt-proof.pdf
function cbrtWad(uint256 x) internal pure returns (uint256 z) {
unchecked {
if (x <= type(uint256).max / 10 ** 36) return cbrt(x * 10 ** 36);
z = (1 + cbrt(x)) * 10 ** 12;
z = (fullMulDivUnchecked(x, 10 ** 36, z * z) + z + z) / 3;
}
/// @solidity memory-safe-assembly
assembly {
let p := x
for {} 1 {} {
if iszero(shr(229, p)) {
if iszero(shr(199, p)) {
p := mul(p, 100000000000000000) // 10 ** 17.
break
}
p := mul(p, 100000000) // 10 ** 8.
break
}
if iszero(shr(249, p)) { p := mul(p, 100) }
break
}
let t := mulmod(mul(z, z), z, p)
z := sub(z, gt(lt(t, shr(1, p)), iszero(t))) // Round down.
}
}
/// @dev Returns the factorial of `x`.
function factorial(uint256 x) internal pure returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
result := 1
if iszero(lt(x, 58)) {
mstore(0x00, 0xaba0f2a2) // `FactorialOverflow()`.
revert(0x1c, 0x04)
}
for {} x { x := sub(x, 1) } { result := mul(result, x) }
}
}
/// @dev Returns the log2 of `x`.
/// Equivalent to computing the index of the most significant bit (MSB) of `x`.
/// Returns 0 if `x` is zero.
function log2(uint256 x) internal pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(r, shl(3, lt(0xff, shr(r, x))))
// forgefmt: disable-next-item
r := or(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
0x0706060506020504060203020504030106050205030304010505030400000000))
}
}
/// @dev Returns the log2 of `x`, rounded up.
/// Returns 0 if `x` is zero.
function log2Up(uint256 x) internal pure returns (uint256 r) {
r = log2(x);
/// @solidity memory-safe-assembly
assembly {
r := add(r, lt(shl(r, 1), x))
}
}
/// @dev Returns the log10 of `x`.
/// Returns 0 if `x` is zero.
function log10(uint256 x) internal pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
if iszero(lt(x, 100000000000000000000000000000000000000)) {
x := div(x, 100000000000000000000000000000000000000)
r := 38
}
if iszero(lt(x, 100000000000000000000)) {
x := div(x, 100000000000000000000)
r := add(r, 20)
}
if iszero(lt(x, 10000000000)) {
x := div(x, 10000000000)
r := add(r, 10)
}
if iszero(lt(x, 100000)) {
x := div(x, 100000)
r := add(r, 5)
}
r := add(r, add(gt(x, 9), add(gt(x, 99), add(gt(x, 999), gt(x, 9999)))))
}
}
/// @dev Returns the log10 of `x`, rounded up.
/// Returns 0 if `x` is zero.
function log10Up(uint256 x) internal pure returns (uint256 r) {
r = log10(x);
/// @solidity memory-safe-assembly
assembly {
r := add(r, lt(exp(10, r), x))
}
}
/// @dev Returns the log256 of `x`.
/// Returns 0 if `x` is zero.
function log256(uint256 x) internal pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(shr(3, r), lt(0xff, shr(r, x)))
}
}
/// @dev Returns the log256 of `x`, rounded up.
/// Returns 0 if `x` is zero.
function log256Up(uint256 x) internal pure returns (uint256 r) {
r = log256(x);
/// @solidity memory-safe-assembly
assembly {
r := add(r, lt(shl(shl(3, r), 1), x))
}
}
/// @dev Returns the scientific notation format `mantissa * 10 ** exponent` of `x`.
/// Useful for compressing prices (e.g. using 25 bit mantissa and 7 bit exponent).
function sci(uint256 x) internal pure returns (uint256 mantissa, uint256 exponent) {
/// @solidity memory-safe-assembly
assembly {
mantissa := x
if mantissa {
if iszero(mod(mantissa, 1000000000000000000000000000000000)) {
mantissa := div(mantissa, 1000000000000000000000000000000000)
exponent := 33
}
if iszero(mod(mantissa, 10000000000000000000)) {
mantissa := div(mantissa, 10000000000000000000)
exponent := add(exponent, 19)
}
if iszero(mod(mantissa, 1000000000000)) {
mantissa := div(mantissa, 1000000000000)
exponent := add(exponent, 12)
}
if iszero(mod(mantissa, 1000000)) {
mantissa := div(mantissa, 1000000)
exponent := add(exponent, 6)
}
if iszero(mod(mantissa, 10000)) {
mantissa := div(mantissa, 10000)
exponent := add(exponent, 4)
}
if iszero(mod(mantissa, 100)) {
mantissa := div(mantissa, 100)
exponent := add(exponent, 2)
}
if iszero(mod(mantissa, 10)) {
mantissa := div(mantissa, 10)
exponent := add(exponent, 1)
}
}
}
}
/// @dev Convenience function for packing `x` into a smaller number using `sci`.
/// The `mantissa` will be in bits [7..255] (the upper 249 bits).
/// The `exponent` will be in bits [0..6] (the lower 7 bits).
/// Use `SafeCastLib` to safely ensure that the `packed` number is small
/// enough to fit in the desired unsigned integer type:
/// ```
/// uint32 packed = SafeCastLib.toUint32(FixedPointMathLib.packSci(777 ether));
/// ```
function packSci(uint256 x) internal pure returns (uint256 packed) {
(x, packed) = sci(x); // Reuse for `mantissa` and `exponent`.
/// @solidity memory-safe-assembly
assembly {
if shr(249, x) {
mstore(0x00, 0xce30380c) // `MantissaOverflow()`.
revert(0x1c, 0x04)
}
packed := or(shl(7, x), packed)
}
}
/// @dev Convenience function for unpacking a packed number from `packSci`.
function unpackSci(uint256 packed) internal pure returns (uint256 unpacked) {
unchecked {
unpacked = (packed >> 7) * 10 ** (packed & 0x7f);
}
}
/// @dev Returns the average of `x` and `y`. Rounds towards zero.
function avg(uint256 x, uint256 y) internal pure returns (uint256 z) {
unchecked {
z = (x & y) + ((x ^ y) >> 1);
}
}
/// @dev Returns the average of `x` and `y`. Rounds towards negative infinity.
function avg(int256 x, int256 y) internal pure returns (int256 z) {
unchecked {
z = (x >> 1) + (y >> 1) + (x & y & 1);
}
}
/// @dev Returns the absolute value of `x`.
function abs(int256 x) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(sar(255, x), add(sar(255, x), x))
}
}
/// @dev Returns the absolute distance between `x` and `y`.
function dist(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(mul(xor(sub(y, x), sub(x, y)), gt(x, y)), sub(y, x))
}
}
/// @dev Returns the absolute distance between `x` and `y`.
function dist(int256 x, int256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(mul(xor(sub(y, x), sub(x, y)), sgt(x, y)), sub(y, x))
}
}
/// @dev Returns the minimum of `x` and `y`.
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(x, mul(xor(x, y), lt(y, x)))
}
}
/// @dev Returns the minimum of `x` and `y`.
function min(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(x, mul(xor(x, y), slt(y, x)))
}
}
/// @dev Returns the maximum of `x` and `y`.
function max(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(x, mul(xor(x, y), gt(y, x)))
}
}
/// @dev Returns the maximum of `x` and `y`.
function max(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(x, mul(xor(x, y), sgt(y, x)))
}
}
/// @dev Returns `x`, bounded to `minValue` and `maxValue`.
function clamp(uint256 x, uint256 minValue, uint256 maxValue)
internal
pure
returns (uint256 z)
{
/// @solidity memory-safe-assembly
assembly {
z := xor(x, mul(xor(x, minValue), gt(minValue, x)))
z := xor(z, mul(xor(z, maxValue), lt(maxValue, z)))
}
}
/// @dev Returns `x`, bounded to `minValue` and `maxValue`.
function clamp(int256 x, int256 minValue, int256 maxValue) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(x, mul(xor(x, minValue), sgt(minValue, x)))
z := xor(z, mul(xor(z, maxValue), slt(maxValue, z)))
}
}
/// @dev Returns greatest common divisor of `x` and `y`.
function gcd(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
for { z := x } y {} {
let t := y
y := mod(z, y)
z := t
}
}
}
/// @dev Returns `a + (b - a) * (t - begin) / (end - begin)`,
/// with `t` clamped between `begin` and `end` (inclusive).
/// Agnostic to the order of (`a`, `b`) and (`end`, `begin`).
/// If `begins == end`, returns `t <= begin ? a : b`.
function lerp(uint256 a, uint256 b, uint256 t, uint256 begin, uint256 end)
internal
pure
returns (uint256)
{
if (begin > end) {
t = ~t;
begin = ~begin;
end = ~end;
}
if (t <= begin) return a;
if (t >= end) return b;
unchecked {
if (b >= a) return a + fullMulDiv(b - a, t - begin, end - begin);
return a - fullMulDiv(a - b, t - begin, end - begin);
}
}
/// @dev Returns `a + (b - a) * (t - begin) / (end - begin)`.
/// with `t` clamped between `begin` and `end` (inclusive).
/// Agnostic to the order of (`a`, `b`) and (`end`, `begin`).
/// If `begins == end`, returns `t <= begin ? a : b`.
function lerp(int256 a, int256 b, int256 t, int256 begin, int256 end)
internal
pure
returns (int256)
{
if (begin > end) {
t = int256(~uint256(t));
begin = int256(~uint256(begin));
end = int256(~uint256(end));
}
if (t <= begin) return a;
if (t >= end) return b;
// forgefmt: disable-next-item
unchecked {
if (b >= a) return int256(uint256(a) + fullMulDiv(uint256(b) - uint256(a),
uint256(t) - uint256(begin), uint256(end) - uint256(begin)));
return int256(uint256(a) - fullMulDiv(uint256(a) - uint256(b),
uint256(t) - uint256(begin), uint256(end) - uint256(begin)));
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* RAW NUMBER OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns `x + y`, without checking for overflow.
function rawAdd(uint256 x, uint256 y) internal pure returns (uint256 z) {
unchecked {
z = x + y;
}
}
/// @dev Returns `x + y`, without checking for overflow.
function rawAdd(int256 x, int256 y) internal pure returns (int256 z) {
unchecked {
z = x + y;
}
}
/// @dev Returns `x - y`, without checking for underflow.
function rawSub(uint256 x, uint256 y) internal pure returns (uint256 z) {
unchecked {
z = x - y;
}
}
/// @dev Returns `x - y`, without checking for underflow.
function rawSub(int256 x, int256 y) internal pure returns (int256 z) {
unchecked {
z = x - y;
}
}
/// @dev Returns `x * y`, without checking for overflow.
function rawMul(uint256 x, uint256 y) internal pure returns (uint256 z) {
unchecked {
z = x * y;
}
}
/// @dev Returns `x * y`, without checking for overflow.
function rawMul(int256 x, int256 y) internal pure returns (int256 z) {
unchecked {
z = x * y;
}
}
/// @dev Returns `x / y`, returning 0 if `y` is zero.
function rawDiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := div(x, y)
}
}
/// @dev Returns `x / y`, returning 0 if `y` is zero.
function rawSDiv(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := sdiv(x, y)
}
}
/// @dev Returns `x % y`, returning 0 if `y` is zero.
function rawMod(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mod(x, y)
}
}
/// @dev Returns `x % y`, returning 0 if `y` is zero.
function rawSMod(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := smod(x, y)
}
}
/// @dev Returns `(x + y) % d`, return 0 if `d` if zero.
function rawAddMod(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := addmod(x, y, d)
}
}
/// @dev Returns `(x * y) % d`, return 0 if `d` if zero.
function rawMulMod(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mulmod(x, y, d)
}
}
}
Compiler Settings
{"viaIR":false,"remappings":["openzeppelin/=node_modules/@openzeppelin/","@openzeppelin/=node_modules/@openzeppelin/","@openzeppelin-upgrades/contracts/=node_modules/@openzeppelin/contracts-upgradeable/","@risc0/contracts/=node_modules/risc0-ethereum/contracts/src/","@solady/=node_modules/solady/","@optimism/=node_modules/optimism/","@sp1-contracts/=node_modules/sp1-contracts/contracts/","forge-std/=node_modules/forge-std/","ds-test/=node_modules/ds-test/src/","@p256-verifier/contracts/=node_modules/p256-verifier/src/","eigenlayer-middleware/=node_modules/eigenlayer-middleware/","eigenlayer-contracts/=node_modules/eigenlayer-contracts/","src/=contracts/","test/=test/","script/=script/","optimism/=node_modules/optimism/","p256-verifier/=node_modules/p256-verifier/","risc0-ethereum/=node_modules/risc0-ethereum/","solady/=node_modules/solady/","sp1-contracts/=node_modules/sp1-contracts/","urc/=node_modules/urc/"],"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"shanghai"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_resolver","internalType":"address"},{"type":"address","name":"_signalService","internalType":"address"},{"type":"uint64","name":"_pacayaForkHeight","internalType":"uint64"}]},{"type":"error","name":"ACCESS_DENIED","inputs":[]},{"type":"error","name":"ETH_TRANSFER_FAILED","inputs":[]},{"type":"error","name":"FUNC_NOT_IMPLEMENTED","inputs":[]},{"type":"error","name":"INVALID_PAUSE_STATUS","inputs":[]},{"type":"error","name":"L2_BASEFEE_MISMATCH","inputs":[]},{"type":"error","name":"L2_DEPRECATED_METHOD","inputs":[]},{"type":"error","name":"L2_FORK_ERROR","inputs":[]},{"type":"error","name":"L2_INVALID_L1_CHAIN_ID","inputs":[]},{"type":"error","name":"L2_INVALID_L2_CHAIN_ID","inputs":[]},{"type":"error","name":"L2_INVALID_SENDER","inputs":[]},{"type":"error","name":"L2_PUBLIC_INPUT_HASH_MISMATCH","inputs":[]},{"type":"error","name":"L2_TOO_LATE","inputs":[]},{"type":"error","name":"REENTRANT_CALL","inputs":[]},{"type":"error","name":"RESOLVER_NOT_FOUND","inputs":[]},{"type":"error","name":"ZERO_ADDRESS","inputs":[]},{"type":"error","name":"ZERO_VALUE","inputs":[]},{"type":"event","name":"AdminChanged","inputs":[{"type":"address","name":"previousAdmin","internalType":"address","indexed":false},{"type":"address","name":"newAdmin","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Anchored","inputs":[{"type":"bytes32","name":"parentHash","internalType":"bytes32","indexed":false},{"type":"uint64","name":"parentGasExcess","internalType":"uint64","indexed":false}],"anonymous":false},{"type":"event","name":"BeaconUpgraded","inputs":[{"type":"address","name":"beacon","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"EIP1559Update","inputs":[{"type":"uint64","name":"oldGasTarget","internalType":"uint64","indexed":false},{"type":"uint64","name":"newGasTarget","internalType":"uint64","indexed":false},{"type":"uint64","name":"oldGasExcess","internalType":"uint64","indexed":false},{"type":"uint64","name":"newGasExcess","internalType":"uint64","indexed":false},{"type":"uint256","name":"basefee","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"type":"uint8","name":"version","internalType":"uint8","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferStarted","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Upgraded","inputs":[{"type":"address","name":"implementation","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"GOLDEN_TOUCH_ADDRESS","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint64","name":"newGasExcess_","internalType":"uint64"}],"name":"adjustExcess","inputs":[{"type":"uint64","name":"_currGasExcess","internalType":"uint64"},{"type":"uint64","name":"_currGasTarget","internalType":"uint64"},{"type":"uint64","name":"_newGasTarget","internalType":"uint64"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"anchor","inputs":[{"type":"bytes32","name":"_l1BlockHash","internalType":"bytes32"},{"type":"bytes32","name":"_l1StateRoot","internalType":"bytes32"},{"type":"uint64","name":"_l1BlockId","internalType":"uint64"},{"type":"uint32","name":"_parentGasUsed","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"anchorV2","inputs":[{"type":"uint64","name":"_anchorBlockId","internalType":"uint64"},{"type":"bytes32","name":"_anchorStateRoot","internalType":"bytes32"},{"type":"uint32","name":"_parentGasUsed","internalType":"uint32"},{"type":"tuple","name":"_baseFeeConfig","internalType":"struct LibSharedData.BaseFeeConfig","components":[{"type":"uint8","name":"adjustmentQuotient","internalType":"uint8"},{"type":"uint8","name":"sharingPctg","internalType":"uint8"},{"type":"uint32","name":"gasIssuancePerSecond","internalType":"uint32"},{"type":"uint64","name":"minGasExcess","internalType":"uint64"},{"type":"uint32","name":"maxGasIssuancePerBlock","internalType":"uint32"}]}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"anchorV3","inputs":[{"type":"uint64","name":"_anchorBlockId","internalType":"uint64"},{"type":"bytes32","name":"_anchorStateRoot","internalType":"bytes32"},{"type":"uint32","name":"_parentGasUsed","internalType":"uint32"},{"type":"tuple","name":"_baseFeeConfig","internalType":"struct LibSharedData.BaseFeeConfig","components":[{"type":"uint8","name":"adjustmentQuotient","internalType":"uint8"},{"type":"uint8","name":"sharingPctg","internalType":"uint8"},{"type":"uint32","name":"gasIssuancePerSecond","internalType":"uint32"},{"type":"uint64","name":"minGasExcess","internalType":"uint64"},{"type":"uint32","name":"maxGasIssuancePerBlock","internalType":"uint32"}]},{"type":"bytes32[]","name":"_signalSlots","internalType":"bytes32[]"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"basefee_","internalType":"uint256"},{"type":"uint64","name":"parentGasExcess_","internalType":"uint64"}],"name":"calculateBaseFee","inputs":[{"type":"tuple","name":"_baseFeeConfig","internalType":"struct LibSharedData.BaseFeeConfig","components":[{"type":"uint8","name":"adjustmentQuotient","internalType":"uint8"},{"type":"uint8","name":"sharingPctg","internalType":"uint8"},{"type":"uint32","name":"gasIssuancePerSecond","internalType":"uint32"},{"type":"uint64","name":"minGasExcess","internalType":"uint64"},{"type":"uint32","name":"maxGasIssuancePerBlock","internalType":"uint32"}]},{"type":"uint64","name":"_blocktime","internalType":"uint64"},{"type":"uint64","name":"_parentGasExcess","internalType":"uint64"},{"type":"uint32","name":"_parentGasUsed","internalType":"uint32"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"basefee_","internalType":"uint256"},{"type":"uint64","name":"parentGasExcess_","internalType":"uint64"}],"name":"getBasefee","inputs":[{"type":"uint64","name":"_anchorBlockId","internalType":"uint64"},{"type":"uint32","name":"_parentGasUsed","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"basefee_","internalType":"uint256"},{"type":"uint64","name":"newGasTarget_","internalType":"uint64"},{"type":"uint64","name":"newGasExcess_","internalType":"uint64"}],"name":"getBasefeeV2","inputs":[{"type":"uint32","name":"_parentGasUsed","internalType":"uint32"},{"type":"uint64","name":"_blockTimestamp","internalType":"uint64"},{"type":"tuple","name":"_baseFeeConfig","internalType":"struct LibSharedData.BaseFeeConfig","components":[{"type":"uint8","name":"adjustmentQuotient","internalType":"uint8"},{"type":"uint8","name":"sharingPctg","internalType":"uint8"},{"type":"uint32","name":"gasIssuancePerSecond","internalType":"uint32"},{"type":"uint64","name":"minGasExcess","internalType":"uint64"},{"type":"uint32","name":"maxGasIssuancePerBlock","internalType":"uint32"}]}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getBlockHash","inputs":[{"type":"uint256","name":"_blockId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"impl","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"inNonReentrant","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"init","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"uint64","name":"_l1ChainId","internalType":"uint64"},{"type":"uint64","name":"_initialGasExcess","internalType":"uint64"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isOnL1","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"l1ChainId","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"lastSyncedBlock","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"pacayaForkHeight","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"parentGasExcess","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"parentGasTarget","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"parentTimestamp","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"proxiableUUID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"publicInputHash","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"resolver","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ISignalService"}],"name":"signalService","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"skipFeeCheck","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unpause","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"upgradeTo","inputs":[{"type":"address","name":"newImplementation","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"upgradeToAndCall","inputs":[{"type":"address","name":"newImplementation","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"address","name":"_to","internalType":"address"}]}]
Contract Creation Code
0x61010060405230608052348015610014575f5ffd5b50604051612ffd380380612ffd83398101604081905261003391610141565b6001600160a01b03831660a0528261004961006a565b506001600160a01b0390911660c0526001600160401b031660e05250610191565b5f54610100900460ff16156100d55760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff90811614610124575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b80516001600160a01b038116811461013c575f5ffd5b919050565b5f5f5f60608486031215610153575f5ffd5b61015c84610126565b925061016a60208501610126565b60408501519092506001600160401b0381168114610186575f5ffd5b809150509250925092565b60805160a05160c05160e051612dfa6102035f395f81816105820152818161093001526113ce01525f81816103d9015281816109c301526117a501525f818161020e0152611bde01525f81816106c70152818161071001528181610a4801528181610a880152610b030152612dfa5ff3fe6080604052600436106101fc575f3560e01c8063893f546011610113578063ba9f41e81161009d578063e902461a1161006d578063e902461a146105f5578063ee82ac5e1461060f578063f2fde38b1461062e578063f940e3851461064d578063fd85eb2d1461066c575f5ffd5b8063ba9f41e814610571578063da69d3db146105a4578063dac5df78146105c3578063e30c3978146105d8575f5ffd5b8063a4b23554116100e3578063a4b23554146102a1578063a7137c0f146104d1578063a7e022d1146104f7578063b310e9e914610533578063b8c7b30c14610552575f5ffd5b8063893f5460146104375780638abf60771461047b5780638da5cb5b1461048f5780639ee512f2146104ac575f5ffd5b806348080a45116101945780635c975abb116101645780635c975abb146103a857806362d09453146103c8578063715018a6146103fb57806379ba50971461040f5780638456cb5914610423575f5ffd5b806348080a451461032e5780634f1ef2861461034d57806352d1902d14610360578063539b8ade14610382575f5ffd5b80633075db56116101cf5780633075db56146102bf57806333d5ac9b146102d35780633659cfe6146102f95780633f4ba83a1461031a575f5ffd5b806304f3bcec1461020057806312622e5b1461024b578063136dc4a8146102825780632f980473146102a1575b5f5ffd5b34801561020b575f5ffd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020015b60405180910390f35b348015610256575f5ffd5b5060fe5461026a906001600160401b031681565b6040516001600160401b039091168152602001610242565b34801561028d575f5ffd5b5061026a61029c36600461269a565b61068b565b3480156102ac575f5ffd5b505f5b6040519015158152602001610242565b3480156102ca575f5ffd5b506102af6106a5565b3480156102de575f5ffd5b5060fd5461026a90600160401b90046001600160401b031681565b348015610304575f5ffd5b506103186103133660046126ee565b6106bd565b005b348015610325575f5ffd5b5061031861078d565b348015610339575f5ffd5b50610318610348366004612733565b610811565b61031861035b3660046127f3565b610a3e565b34801561036b575f5ffd5b50610374610af7565b604051908152602001610242565b34801561038d575f5ffd5b5060fd5461026a90600160801b90046001600160401b031681565b3480156103b3575f5ffd5b506102af60c954610100900460ff1660021490565b3480156103d3575f5ffd5b5061022e7f000000000000000000000000000000000000000000000000000000000000000081565b348015610406575f5ffd5b50610318610ba8565b34801561041a575f5ffd5b50610318610bb9565b34801561042e575f5ffd5b50610318610c30565b348015610442575f5ffd5b506104566104513660046128b6565b610caf565b604080519384526001600160401b039283166020850152911690820152606001610242565b348015610486575f5ffd5b5061022e610ddb565b34801561049a575f5ffd5b506033546001600160a01b031661022e565b3480156104b7575f5ffd5b5061022e71777735367b36bc9b61c50022d9d0700db4ec81565b3480156104dc575f5ffd5b5060fd5461026a90600160c01b90046001600160401b031681565b348015610502575f5ffd5b506105166105113660046128ee565b610de9565b604080519283526001600160401b03909116602083015201610242565b34801561053e575f5ffd5b5061031861054d36600461291f565b610e04565b34801561055d575f5ffd5b5060fd5461026a906001600160401b031681565b34801561057c575f5ffd5b5061026a7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105af575f5ffd5b506103186105be36600461293c565b611036565b3480156105ce575f5ffd5b5061037460fc5481565b3480156105e3575f5ffd5b506065546001600160a01b031661022e565b348015610600575f5ffd5b5061051661051136600461297f565b34801561061a575f5ffd5b506103746106293660046129c7565b61104f565b348015610639575f5ffd5b506103186106483660046126ee565b611087565b348015610658575f5ffd5b506103186106673660046129de565b6110f8565b348015610677575f5ffd5b50610318610686366004612a15565b6112af565b5f6040516372c0090b60e11b815260040160405180910390fd5b5f60026106b460c95460ff1690565b60ff1614905090565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361070e5760405162461bcd60e51b815260040161070590612a56565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661074061145e565b6001600160a01b0316146107665760405162461bcd60e51b815260040161070590612aa2565b61076f81611479565b604080515f8082526020820190925261078a91839190611481565b50565b6107a160c954610100900460ff1660021490565b6107be5760405163bae6e2a960e01b815260040160405180910390fd5b6107d260c9805461ff001916610100179055565b6040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9060200160405180910390a161080f335f6115f0565b565b845f8190036108335760405163ec73295960e01b815260040160405180910390fd5b866001600160401b0316805f0361085d5760405163ec73295960e01b815260040160405180910390fd5b61086d6060860160408701612aee565b63ffffffff16805f036108935760405163ec73295960e01b815260040160405180910390fd5b6108a06020870187612b07565b60ff16805f036108c35760405163ec73295960e01b815260040160405180910390fd5b3371777735367b36bc9b61c50022d9d0700db4ec146108f557604051636494e9f760e01b815260040160405180910390fd5b600261090360c95460ff1690565b60ff16036109245760405163dfc60d8560e01b815260040160405180910390fd5b61092e60026115f8565b7f00000000000000000000000000000000000000000000000000000000000000006001600160401b031643101561097857604051631799c89b60e01b815260040160405180910390fd5b5f610984600143612b3b565b905061098f8161160e565b6109998989611646565b6109a38b8b61172d565b6109ac8161184b565b604051633b78c86560e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633b78c865906109fa908a908a90600401612b4e565b5f604051808303815f87803b158015610a11575f5ffd5b505af1158015610a23573d5f5f3e3d5ffd5b5050505050610a3260016115f8565b50505050505050505050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610a865760405162461bcd60e51b815260040161070590612a56565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610ab861145e565b6001600160a01b031614610ade5760405162461bcd60e51b815260040161070590612aa2565b610ae782611479565b610af382826001611481565b5050565b5f306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b965760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610705565b505f516020612d7e5f395f51905f5290565b610bb06118e2565b61080f5f61193c565b60655433906001600160a01b03168114610c275760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610705565b61078a8161193c565b610c4460c954610100900460ff1660021490565b15610c625760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200160405180910390a161080f3360016115f0565b5f808080610cc06020860186612b07565b60ff16610cd36060870160408801612aee565b63ffffffff16610ce39190612b85565b60fd54909150610d07906001600160401b03600160c01b8204811691849116611955565b90935091505f610d1d6060870160408801612aee565b63ffffffff1660fd60109054906101000a90046001600160401b031688610d449190612bae565b610d4e9190612b85565b9050610d6060a0870160808801612aee565b63ffffffff1615801590610d915750610d7f60a0870160808801612aee565b63ffffffff16816001600160401b0316115b15610daf57610da660a0870160808801612aee565b63ffffffff1690505b610dcb8484838b610dc660808c0160608d01612bcd565b611a6d565b9099949850965092945050505050565b5f610de461145e565b905090565b5f5f6040516372c0090b60e11b815260040160405180910390fd5b5f54610100900460ff1615808015610e2257505f54600160ff909116105b80610e3b5750303b158015610e3b57505f5460ff166001145b610e9e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610705565b5f805460ff191660011790558015610ebf575f805461ff0019166101001790555b610ec884611aed565b826001600160401b03165f03610ef1576040516308279a2560e31b815260040160405180910390fd5b46836001600160401b031603610f1a576040516308279a2560e31b815260040160405180910390fd5b60014611610f3b57604051638f972ecb60e01b815260040160405180910390fd5b6001600160401b03461115610f6357604051638f972ecb60e01b815260040160405180910390fd5b4315610fad5743600103610f94575f610f7d600143612b3b565b5f81815260fb602052604090209040905550610fad565b604051635a0f9e4160e11b815260040160405180910390fd5b60fe80546001600160401b0380861667ffffffffffffffff199283161790925560fd805492851692909116919091179055610fe743611b4b565b5060fc558015611030575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6040516372c0090b60e11b815260040160405180910390fd5b5f43821061105e57505f919050565b4361106b83610100612be6565b1061107557504090565b505f90815260fb602052604090205490565b61108f6118e2565b606580546001600160a01b0383166001600160a01b031990911681179091556110c06033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b806001600160a01b0381166111205760405163538ba4f960e01b815260040160405180910390fd5b61113460c954610100900460ff1660021490565b156111525760405163bae6e2a960e01b815260040160405180910390fd5b693bb4ba34323930bbb2b960b11b6111726033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614806111ac5750611197816001611bdb565b6001600160a01b0316336001600160a01b0316145b6111c9576040516395383ea160e01b815260040160405180910390fd5b60026111d760c95460ff1690565b60ff16036111f85760405163dfc60d8560e01b815260040160405180910390fd5b61120260026115f8565b6001600160a01b038416611228576112236001600160a01b03841647611c7d565b6112a5565b6040516370a0823160e01b81523060048201526112a59084906001600160a01b038716906370a0823190602401602060405180830381865afa158015611270573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112949190612bf9565b6001600160a01b0387169190611c88565b61103060016115f8565b825f8190036112d15760405163ec73295960e01b815260040160405180910390fd5b846001600160401b0316805f036112fb5760405163ec73295960e01b815260040160405180910390fd5b61130b6060840160408501612aee565b63ffffffff16805f036113315760405163ec73295960e01b815260040160405180910390fd5b61133e6020850185612b07565b60ff16805f036113615760405163ec73295960e01b815260040160405180910390fd5b3371777735367b36bc9b61c50022d9d0700db4ec1461139357604051636494e9f760e01b815260040160405180910390fd5b60026113a160c95460ff1690565b60ff16036113c25760405163dfc60d8560e01b815260040160405180910390fd5b6113cc60026115f8565b7f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316431061141557604051631799c89b60e01b815260040160405180910390fd5b5f611421600143612b3b565b905061142c8161160e565b6114368787611646565b611440898961172d565b6114498161184b565b5061145460016115f8565b5050505050505050565b5f516020612d7e5f395f51905f52546001600160a01b031690565b61078a6118e2565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156114b9576114b483611cda565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611513575060408051601f3d908101601f1916820190925261151091810190612bf9565b60015b6115765760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610705565b5f516020612d7e5f395f51905f5281146115e45760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610705565b506114b4838383611d75565b610af36118e2565b60c9805460ff191660ff92909216919091179055565b5f5f61161983611b4b565b915091508160fc541461163f5760405163d719258d60e01b815260040160405180910390fd5b60fc555050565b5f5f5f611654854286610caf565b9250925092508248148061166557505f5b611682576040516336d54d4f60e11b815260040160405180910390fd5b60fd5460408051600160c01b83046001600160401b039081168252858116602083015292831681830152918316606083015260808201859052517f781ae5c2215806150d5c71a4ed5336e5dc3ad32aef04fc0f626a6ee0c2f8d1c89181900360a00190a160fd805477ffffffffffffffffffffffffffffffff000000000000000016600160c01b6001600160401b039485160267ffffffffffffffff19161791909216179055505050565b60fd546001600160401b03600160401b90910481169083161161174e575050565b60fe546040516313e4299d60e21b81526001600160401b0391821660048201527f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da16960248201529083166044820152606481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634f90a674906084016020604051808303815f875af11580156117f3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118179190612bf9565b505060fd80546001600160401b03909216600160401b026fffffffffffffffff000000000000000019909216919091179055565b5f81815260fb60205260409081902082409081905560fd80546001600160401b03428116600160801b0267ffffffffffffffff60801b1983168117909355935192937f41c3f410f5c8ac36bb46b1dccef0de0f964087c9e688795fa02ecfa2c20b3fe4936118d6938693908316921691909117909182526001600160401b0316602082015260400190565b60405180910390a15050565b6033546001600160a01b0316331461080f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610705565b606580546001600160a01b031916905561078a81611d99565b5f80670de0b6b3a76400006001600160401b038616820361197c5784849250925050611a65565b6001600160401b03851615806119a35750846001600160401b0316866001600160401b0316145b806119c157506119b4815f19612c24565b856001600160401b031610155b156119d25785849250925050611a65565b5f866001600160401b0316866001600160401b0316836119f29190612c37565b6119fc9190612c24565b9050801580611a1157506001600160ff1b0381115b15611a23578585935093505050611a65565b5f611a2d82611dea565b90505f828702828902015f811260018114611a4c578582049250611a50565b5f92505b505087611a5c82612007565b95509550505050505b935093915050565b5f8080611a8963ffffffff86166001600160401b038916612be6565b9050856001600160401b03168111611aa2576001611ab5565b611ab56001600160401b03871682612b3b565b9050611ad46001600160401b03611ace83878316612019565b9061202e565b9150611ae08883612042565b9250509550959350505050565b5f54610100900460ff16611b135760405162461bcd60e51b815260040161070590612c4e565b611b1b612084565b611b396001600160a01b03821615611b33578161193c565b3361193c565b5060c9805461ff001916610100179055565b5f5f611b5561265f565b46611fe08201525f5b60ff81108015611b715750806001018510155b15611ba2575f198186030180408360ff83066101008110611b9457611b94612c99565b602002015250600101611b5e565b5061200081209250834081611bb860ff87612cad565b6101008110611bc957611bc9612c99565b60200201526120009020919391925050565b5f7f0000000000000000000000000000000000000000000000000000000000000000604051633632b1fb60e11b81524660048201526024810185905283151560448201526001600160a01b039190911690636c6563f690606401602060405180830381865afa158015611c50573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c749190612cc0565b90505b92915050565b610af382825a6120aa565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526114b49084906120ed565b6001600160a01b0381163b611d475760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610705565b5f516020612d7e5f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b611d7e836121c0565b5f82511180611d8a5750805b156114b45761103083836121ff565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6fffffffffffffffffffffffffffffffff811160071b81811c6001600160401b031060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b175f8213611e4657631615e6385f526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd1901909102780a09507084cc699bb0e71ea869ffffffffffffffffffffffff190105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b5f611c77826001600160401b0361202e565b5f8183116120275781611c74565b5090919050565b5f81831161203c5782611c74565b50919050565b5f826001600160401b03165f0361205b57506001611c77565b611c746001846001600160401b03166120748686612224565b61207e9190612c24565b90612019565b5f54610100900460ff1661080f5760405162461bcd60e51b815260040161070590612c4e565b815f036120b657505050565b6120d083838360405180602001604052805f8152506122b2565b6114b457604051634c67134d60e11b815260040160405180910390fd5b5f612141826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122ef9092919063ffffffff16565b905080515f14806121615750808060200190518101906121619190612cdb565b6114b45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610705565b6121c981611cda565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b6060611c748383604051806060016040528060278152602001612d9e602791396122fd565b5f826001600160401b03165f0361223d5761223d612cfa565b5f836001600160401b0316836001600160401b0316670de0b6b3a76400006122659190612c37565b61226f9190612c24565b9050680755bf798b4a1bf1e481111561228e5750680755bf798b4a1bf1e45b670de0b6b3a76400006122a082612371565b6122aa9190612c24565b949350505050565b5f6001600160a01b0385166122da57604051634c67134d60e11b815260040160405180910390fd5b5f5f835160208501878988f195945050505050565b60606122aa84845f856124eb565b60605f5f856001600160a01b0316856040516123199190612d30565b5f60405180830381855af49150503d805f8114612351576040519150601f19603f3d011682016040523d82523d5f602084013e612356565b606091505b5091509150612367868383876125c2565b9695505050505050565b5f68023f2fa8f6da5b9d2819821361238857919050565b680755bf798b4a1bf1e582126123a55763a37bfec95f526004601cfd5b6503782dace9d9604e83901b0591505f60606bb17217f7d1cf79abc9e3b39884821b056001605f1b01901d6bb17217f7d1cf79abc9e3b39881029093036c240c330e9fb2d9cbaf0fd5aafb1981018102606090811d6d0277594991cfc85f6e2461837cd9018202811d6d1a521255e34f6a5061b25ef1c9c319018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d6e02c72388d9f74f51a9331fed693f1419018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084016d01d3967ed30fc4f89c02bab5708119010290911d6e0587f503bb6ea29d25fcb740196450019091026d360d7aeea093263ecc6e0ecb291760621b010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b60608247101561254c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610705565b5f5f866001600160a01b031685876040516125679190612d30565b5f6040518083038185875af1925050503d805f81146125a1576040519150601f19603f3d011682016040523d82523d5f602084013e6125a6565b606091505b50915091506125b7878383876125c2565b979650505050505050565b606083156126305782515f03612629576001600160a01b0385163b6126295760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610705565b50816122aa565b6122aa83838151156126455781518083602001fd5b8060405162461bcd60e51b81526004016107059190612d4b565b604051806120000160405280610100906020820280368337509192915050565b80356001600160401b0381168114612695575f5ffd5b919050565b5f5f5f606084860312156126ac575f5ffd5b6126b58461267f565b92506126c36020850161267f565b91506126d16040850161267f565b90509250925092565b6001600160a01b038116811461078a575f5ffd5b5f602082840312156126fe575f5ffd5b8135612709816126da565b9392505050565b803563ffffffff81168114612695575f5ffd5b5f60a0828403121561203c575f5ffd5b5f5f5f5f5f5f6101208789031215612749575f5ffd5b6127528761267f565b95506020870135945061276760408801612710565b93506127768860608901612723565b92506101008701356001600160401b03811115612791575f5ffd5b8701601f810189136127a1575f5ffd5b80356001600160401b038111156127b6575f5ffd5b8960208260051b84010111156127ca575f5ffd5b60208201935080925050509295509295509295565b634e487b7160e01b5f52604160045260245ffd5b5f5f60408385031215612804575f5ffd5b823561280f816126da565b915060208301356001600160401b03811115612829575f5ffd5b8301601f81018513612839575f5ffd5b80356001600160401b03811115612852576128526127df565b604051601f8201601f19908116603f011681016001600160401b0381118282101715612880576128806127df565b604052818152828201602001871015612897575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f5f5f60e084860312156128c8575f5ffd5b6128d184612710565b92506128df6020850161267f565b91506126d18560408601612723565b5f5f604083850312156128ff575f5ffd5b6129088361267f565b915061291660208401612710565b90509250929050565b5f5f5f60608486031215612931575f5ffd5b83356126b5816126da565b5f5f5f5f6080858703121561294f575f5ffd5b84359350602085013592506129666040860161267f565b915061297460608601612710565b905092959194509250565b5f5f5f5f6101008587031215612993575f5ffd5b61299d8686612723565b93506129ab60a0860161267f565b92506129b960c0860161267f565b915061297460e08601612710565b5f602082840312156129d7575f5ffd5b5035919050565b5f5f604083850312156129ef575f5ffd5b82356129fa816126da565b91506020830135612a0a816126da565b809150509250929050565b5f5f5f5f6101008587031215612a29575f5ffd5b612a328561267f565b935060208501359250612a4760408601612710565b91506129748660608701612723565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b5f60208284031215612afe575f5ffd5b611c7482612710565b5f60208284031215612b17575f5ffd5b813560ff81168114612709575f5ffd5b634e487b7160e01b5f52601160045260245ffd5b81810381811115611c7757611c77612b27565b602080825281018290525f6001600160fb1b03831115612b6c575f5ffd5b8260051b80856040850137919091016040019392505050565b6001600160401b038181168382160290811690818114612ba757612ba7612b27565b5092915050565b6001600160401b038281168282160390811115611c7757611c77612b27565b5f60208284031215612bdd575f5ffd5b611c748261267f565b80820180821115611c7757611c77612b27565b5f60208284031215612c09575f5ffd5b5051919050565b634e487b7160e01b5f52601260045260245ffd5b5f82612c3257612c32612c10565b500490565b8082028115828204841417611c7757611c77612b27565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b5f82612cbb57612cbb612c10565b500690565b5f60208284031215612cd0575f5ffd5b8151612709816126da565b5f60208284031215612ceb575f5ffd5b81518015158114612709575f5ffd5b634e487b7160e01b5f52600160045260245ffd5b5f5b83811015612d28578181015183820152602001612d10565b50505f910152565b5f8251612d41818460208701612d0e565b9190910192915050565b602081525f8251806020840152612d69816040850160208701612d0e565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209543ab1badc44a23602e2e677be18e5e9d57d645dc1383edec8f3fbb5ae9cd3c64736f6c634300081b0033000000000000000000000000c32277f541bbadaa260337e71cea53871d310dc80000000000000000000000001670000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000011cab0
Deployed ByteCode
0x6080604052600436106101fc575f3560e01c8063893f546011610113578063ba9f41e81161009d578063e902461a1161006d578063e902461a146105f5578063ee82ac5e1461060f578063f2fde38b1461062e578063f940e3851461064d578063fd85eb2d1461066c575f5ffd5b8063ba9f41e814610571578063da69d3db146105a4578063dac5df78146105c3578063e30c3978146105d8575f5ffd5b8063a4b23554116100e3578063a4b23554146102a1578063a7137c0f146104d1578063a7e022d1146104f7578063b310e9e914610533578063b8c7b30c14610552575f5ffd5b8063893f5460146104375780638abf60771461047b5780638da5cb5b1461048f5780639ee512f2146104ac575f5ffd5b806348080a45116101945780635c975abb116101645780635c975abb146103a857806362d09453146103c8578063715018a6146103fb57806379ba50971461040f5780638456cb5914610423575f5ffd5b806348080a451461032e5780634f1ef2861461034d57806352d1902d14610360578063539b8ade14610382575f5ffd5b80633075db56116101cf5780633075db56146102bf57806333d5ac9b146102d35780633659cfe6146102f95780633f4ba83a1461031a575f5ffd5b806304f3bcec1461020057806312622e5b1461024b578063136dc4a8146102825780632f980473146102a1575b5f5ffd5b34801561020b575f5ffd5b507f000000000000000000000000c32277f541bbadaa260337e71cea53871d310dc85b6040516001600160a01b0390911681526020015b60405180910390f35b348015610256575f5ffd5b5060fe5461026a906001600160401b031681565b6040516001600160401b039091168152602001610242565b34801561028d575f5ffd5b5061026a61029c36600461269a565b61068b565b3480156102ac575f5ffd5b505f5b6040519015158152602001610242565b3480156102ca575f5ffd5b506102af6106a5565b3480156102de575f5ffd5b5060fd5461026a90600160401b90046001600160401b031681565b348015610304575f5ffd5b506103186103133660046126ee565b6106bd565b005b348015610325575f5ffd5b5061031861078d565b348015610339575f5ffd5b50610318610348366004612733565b610811565b61031861035b3660046127f3565b610a3e565b34801561036b575f5ffd5b50610374610af7565b604051908152602001610242565b34801561038d575f5ffd5b5060fd5461026a90600160801b90046001600160401b031681565b3480156103b3575f5ffd5b506102af60c954610100900460ff1660021490565b3480156103d3575f5ffd5b5061022e7f000000000000000000000000167000000000000000000000000000000000000581565b348015610406575f5ffd5b50610318610ba8565b34801561041a575f5ffd5b50610318610bb9565b34801561042e575f5ffd5b50610318610c30565b348015610442575f5ffd5b506104566104513660046128b6565b610caf565b604080519384526001600160401b039283166020850152911690820152606001610242565b348015610486575f5ffd5b5061022e610ddb565b34801561049a575f5ffd5b506033546001600160a01b031661022e565b3480156104b7575f5ffd5b5061022e71777735367b36bc9b61c50022d9d0700db4ec81565b3480156104dc575f5ffd5b5060fd5461026a90600160c01b90046001600160401b031681565b348015610502575f5ffd5b506105166105113660046128ee565b610de9565b604080519283526001600160401b03909116602083015201610242565b34801561053e575f5ffd5b5061031861054d36600461291f565b610e04565b34801561055d575f5ffd5b5060fd5461026a906001600160401b031681565b34801561057c575f5ffd5b5061026a7f000000000000000000000000000000000000000000000000000000000011cab081565b3480156105af575f5ffd5b506103186105be36600461293c565b611036565b3480156105ce575f5ffd5b5061037460fc5481565b3480156105e3575f5ffd5b506065546001600160a01b031661022e565b348015610600575f5ffd5b5061051661051136600461297f565b34801561061a575f5ffd5b506103746106293660046129c7565b61104f565b348015610639575f5ffd5b506103186106483660046126ee565b611087565b348015610658575f5ffd5b506103186106673660046129de565b6110f8565b348015610677575f5ffd5b50610318610686366004612a15565b6112af565b5f6040516372c0090b60e11b815260040160405180910390fd5b5f60026106b460c95460ff1690565b60ff1614905090565b6001600160a01b037f0000000000000000000000003cfe9b8e0e12289d78c91295c8353ab1731f06e116300361070e5760405162461bcd60e51b815260040161070590612a56565b60405180910390fd5b7f0000000000000000000000003cfe9b8e0e12289d78c91295c8353ab1731f06e16001600160a01b031661074061145e565b6001600160a01b0316146107665760405162461bcd60e51b815260040161070590612aa2565b61076f81611479565b604080515f8082526020820190925261078a91839190611481565b50565b6107a160c954610100900460ff1660021490565b6107be5760405163bae6e2a960e01b815260040160405180910390fd5b6107d260c9805461ff001916610100179055565b6040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9060200160405180910390a161080f335f6115f0565b565b845f8190036108335760405163ec73295960e01b815260040160405180910390fd5b866001600160401b0316805f0361085d5760405163ec73295960e01b815260040160405180910390fd5b61086d6060860160408701612aee565b63ffffffff16805f036108935760405163ec73295960e01b815260040160405180910390fd5b6108a06020870187612b07565b60ff16805f036108c35760405163ec73295960e01b815260040160405180910390fd5b3371777735367b36bc9b61c50022d9d0700db4ec146108f557604051636494e9f760e01b815260040160405180910390fd5b600261090360c95460ff1690565b60ff16036109245760405163dfc60d8560e01b815260040160405180910390fd5b61092e60026115f8565b7f000000000000000000000000000000000000000000000000000000000011cab06001600160401b031643101561097857604051631799c89b60e01b815260040160405180910390fd5b5f610984600143612b3b565b905061098f8161160e565b6109998989611646565b6109a38b8b61172d565b6109ac8161184b565b604051633b78c86560e01b81526001600160a01b037f00000000000000000000000016700000000000000000000000000000000000051690633b78c865906109fa908a908a90600401612b4e565b5f604051808303815f87803b158015610a11575f5ffd5b505af1158015610a23573d5f5f3e3d5ffd5b5050505050610a3260016115f8565b50505050505050505050565b6001600160a01b037f0000000000000000000000003cfe9b8e0e12289d78c91295c8353ab1731f06e1163003610a865760405162461bcd60e51b815260040161070590612a56565b7f0000000000000000000000003cfe9b8e0e12289d78c91295c8353ab1731f06e16001600160a01b0316610ab861145e565b6001600160a01b031614610ade5760405162461bcd60e51b815260040161070590612aa2565b610ae782611479565b610af382826001611481565b5050565b5f306001600160a01b037f0000000000000000000000003cfe9b8e0e12289d78c91295c8353ab1731f06e11614610b965760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610705565b505f516020612d7e5f395f51905f5290565b610bb06118e2565b61080f5f61193c565b60655433906001600160a01b03168114610c275760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610705565b61078a8161193c565b610c4460c954610100900460ff1660021490565b15610c625760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200160405180910390a161080f3360016115f0565b5f808080610cc06020860186612b07565b60ff16610cd36060870160408801612aee565b63ffffffff16610ce39190612b85565b60fd54909150610d07906001600160401b03600160c01b8204811691849116611955565b90935091505f610d1d6060870160408801612aee565b63ffffffff1660fd60109054906101000a90046001600160401b031688610d449190612bae565b610d4e9190612b85565b9050610d6060a0870160808801612aee565b63ffffffff1615801590610d915750610d7f60a0870160808801612aee565b63ffffffff16816001600160401b0316115b15610daf57610da660a0870160808801612aee565b63ffffffff1690505b610dcb8484838b610dc660808c0160608d01612bcd565b611a6d565b9099949850965092945050505050565b5f610de461145e565b905090565b5f5f6040516372c0090b60e11b815260040160405180910390fd5b5f54610100900460ff1615808015610e2257505f54600160ff909116105b80610e3b5750303b158015610e3b57505f5460ff166001145b610e9e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610705565b5f805460ff191660011790558015610ebf575f805461ff0019166101001790555b610ec884611aed565b826001600160401b03165f03610ef1576040516308279a2560e31b815260040160405180910390fd5b46836001600160401b031603610f1a576040516308279a2560e31b815260040160405180910390fd5b60014611610f3b57604051638f972ecb60e01b815260040160405180910390fd5b6001600160401b03461115610f6357604051638f972ecb60e01b815260040160405180910390fd5b4315610fad5743600103610f94575f610f7d600143612b3b565b5f81815260fb602052604090209040905550610fad565b604051635a0f9e4160e11b815260040160405180910390fd5b60fe80546001600160401b0380861667ffffffffffffffff199283161790925560fd805492851692909116919091179055610fe743611b4b565b5060fc558015611030575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6040516372c0090b60e11b815260040160405180910390fd5b5f43821061105e57505f919050565b4361106b83610100612be6565b1061107557504090565b505f90815260fb602052604090205490565b61108f6118e2565b606580546001600160a01b0383166001600160a01b031990911681179091556110c06033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b806001600160a01b0381166111205760405163538ba4f960e01b815260040160405180910390fd5b61113460c954610100900460ff1660021490565b156111525760405163bae6e2a960e01b815260040160405180910390fd5b693bb4ba34323930bbb2b960b11b6111726033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614806111ac5750611197816001611bdb565b6001600160a01b0316336001600160a01b0316145b6111c9576040516395383ea160e01b815260040160405180910390fd5b60026111d760c95460ff1690565b60ff16036111f85760405163dfc60d8560e01b815260040160405180910390fd5b61120260026115f8565b6001600160a01b038416611228576112236001600160a01b03841647611c7d565b6112a5565b6040516370a0823160e01b81523060048201526112a59084906001600160a01b038716906370a0823190602401602060405180830381865afa158015611270573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112949190612bf9565b6001600160a01b0387169190611c88565b61103060016115f8565b825f8190036112d15760405163ec73295960e01b815260040160405180910390fd5b846001600160401b0316805f036112fb5760405163ec73295960e01b815260040160405180910390fd5b61130b6060840160408501612aee565b63ffffffff16805f036113315760405163ec73295960e01b815260040160405180910390fd5b61133e6020850185612b07565b60ff16805f036113615760405163ec73295960e01b815260040160405180910390fd5b3371777735367b36bc9b61c50022d9d0700db4ec1461139357604051636494e9f760e01b815260040160405180910390fd5b60026113a160c95460ff1690565b60ff16036113c25760405163dfc60d8560e01b815260040160405180910390fd5b6113cc60026115f8565b7f000000000000000000000000000000000000000000000000000000000011cab06001600160401b0316431061141557604051631799c89b60e01b815260040160405180910390fd5b5f611421600143612b3b565b905061142c8161160e565b6114368787611646565b611440898961172d565b6114498161184b565b5061145460016115f8565b5050505050505050565b5f516020612d7e5f395f51905f52546001600160a01b031690565b61078a6118e2565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156114b9576114b483611cda565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611513575060408051601f3d908101601f1916820190925261151091810190612bf9565b60015b6115765760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610705565b5f516020612d7e5f395f51905f5281146115e45760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610705565b506114b4838383611d75565b610af36118e2565b60c9805460ff191660ff92909216919091179055565b5f5f61161983611b4b565b915091508160fc541461163f5760405163d719258d60e01b815260040160405180910390fd5b60fc555050565b5f5f5f611654854286610caf565b9250925092508248148061166557505f5b611682576040516336d54d4f60e11b815260040160405180910390fd5b60fd5460408051600160c01b83046001600160401b039081168252858116602083015292831681830152918316606083015260808201859052517f781ae5c2215806150d5c71a4ed5336e5dc3ad32aef04fc0f626a6ee0c2f8d1c89181900360a00190a160fd805477ffffffffffffffffffffffffffffffff000000000000000016600160c01b6001600160401b039485160267ffffffffffffffff19161791909216179055505050565b60fd546001600160401b03600160401b90910481169083161161174e575050565b60fe546040516313e4299d60e21b81526001600160401b0391821660048201527f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da16960248201529083166044820152606481018290527f00000000000000000000000016700000000000000000000000000000000000056001600160a01b031690634f90a674906084016020604051808303815f875af11580156117f3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118179190612bf9565b505060fd80546001600160401b03909216600160401b026fffffffffffffffff000000000000000019909216919091179055565b5f81815260fb60205260409081902082409081905560fd80546001600160401b03428116600160801b0267ffffffffffffffff60801b1983168117909355935192937f41c3f410f5c8ac36bb46b1dccef0de0f964087c9e688795fa02ecfa2c20b3fe4936118d6938693908316921691909117909182526001600160401b0316602082015260400190565b60405180910390a15050565b6033546001600160a01b0316331461080f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610705565b606580546001600160a01b031916905561078a81611d99565b5f80670de0b6b3a76400006001600160401b038616820361197c5784849250925050611a65565b6001600160401b03851615806119a35750846001600160401b0316866001600160401b0316145b806119c157506119b4815f19612c24565b856001600160401b031610155b156119d25785849250925050611a65565b5f866001600160401b0316866001600160401b0316836119f29190612c37565b6119fc9190612c24565b9050801580611a1157506001600160ff1b0381115b15611a23578585935093505050611a65565b5f611a2d82611dea565b90505f828702828902015f811260018114611a4c578582049250611a50565b5f92505b505087611a5c82612007565b95509550505050505b935093915050565b5f8080611a8963ffffffff86166001600160401b038916612be6565b9050856001600160401b03168111611aa2576001611ab5565b611ab56001600160401b03871682612b3b565b9050611ad46001600160401b03611ace83878316612019565b9061202e565b9150611ae08883612042565b9250509550959350505050565b5f54610100900460ff16611b135760405162461bcd60e51b815260040161070590612c4e565b611b1b612084565b611b396001600160a01b03821615611b33578161193c565b3361193c565b5060c9805461ff001916610100179055565b5f5f611b5561265f565b46611fe08201525f5b60ff81108015611b715750806001018510155b15611ba2575f198186030180408360ff83066101008110611b9457611b94612c99565b602002015250600101611b5e565b5061200081209250834081611bb860ff87612cad565b6101008110611bc957611bc9612c99565b60200201526120009020919391925050565b5f7f000000000000000000000000c32277f541bbadaa260337e71cea53871d310dc8604051633632b1fb60e11b81524660048201526024810185905283151560448201526001600160a01b039190911690636c6563f690606401602060405180830381865afa158015611c50573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c749190612cc0565b90505b92915050565b610af382825a6120aa565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526114b49084906120ed565b6001600160a01b0381163b611d475760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610705565b5f516020612d7e5f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b611d7e836121c0565b5f82511180611d8a5750805b156114b45761103083836121ff565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6fffffffffffffffffffffffffffffffff811160071b81811c6001600160401b031060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b175f8213611e4657631615e6385f526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd1901909102780a09507084cc699bb0e71ea869ffffffffffffffffffffffff190105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b5f611c77826001600160401b0361202e565b5f8183116120275781611c74565b5090919050565b5f81831161203c5782611c74565b50919050565b5f826001600160401b03165f0361205b57506001611c77565b611c746001846001600160401b03166120748686612224565b61207e9190612c24565b90612019565b5f54610100900460ff1661080f5760405162461bcd60e51b815260040161070590612c4e565b815f036120b657505050565b6120d083838360405180602001604052805f8152506122b2565b6114b457604051634c67134d60e11b815260040160405180910390fd5b5f612141826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122ef9092919063ffffffff16565b905080515f14806121615750808060200190518101906121619190612cdb565b6114b45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610705565b6121c981611cda565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b6060611c748383604051806060016040528060278152602001612d9e602791396122fd565b5f826001600160401b03165f0361223d5761223d612cfa565b5f836001600160401b0316836001600160401b0316670de0b6b3a76400006122659190612c37565b61226f9190612c24565b9050680755bf798b4a1bf1e481111561228e5750680755bf798b4a1bf1e45b670de0b6b3a76400006122a082612371565b6122aa9190612c24565b949350505050565b5f6001600160a01b0385166122da57604051634c67134d60e11b815260040160405180910390fd5b5f5f835160208501878988f195945050505050565b60606122aa84845f856124eb565b60605f5f856001600160a01b0316856040516123199190612d30565b5f60405180830381855af49150503d805f8114612351576040519150601f19603f3d011682016040523d82523d5f602084013e612356565b606091505b5091509150612367868383876125c2565b9695505050505050565b5f68023f2fa8f6da5b9d2819821361238857919050565b680755bf798b4a1bf1e582126123a55763a37bfec95f526004601cfd5b6503782dace9d9604e83901b0591505f60606bb17217f7d1cf79abc9e3b39884821b056001605f1b01901d6bb17217f7d1cf79abc9e3b39881029093036c240c330e9fb2d9cbaf0fd5aafb1981018102606090811d6d0277594991cfc85f6e2461837cd9018202811d6d1a521255e34f6a5061b25ef1c9c319018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d6e02c72388d9f74f51a9331fed693f1419018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084016d01d3967ed30fc4f89c02bab5708119010290911d6e0587f503bb6ea29d25fcb740196450019091026d360d7aeea093263ecc6e0ecb291760621b010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b60608247101561254c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610705565b5f5f866001600160a01b031685876040516125679190612d30565b5f6040518083038185875af1925050503d805f81146125a1576040519150601f19603f3d011682016040523d82523d5f602084013e6125a6565b606091505b50915091506125b7878383876125c2565b979650505050505050565b606083156126305782515f03612629576001600160a01b0385163b6126295760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610705565b50816122aa565b6122aa83838151156126455781518083602001fd5b8060405162461bcd60e51b81526004016107059190612d4b565b604051806120000160405280610100906020820280368337509192915050565b80356001600160401b0381168114612695575f5ffd5b919050565b5f5f5f606084860312156126ac575f5ffd5b6126b58461267f565b92506126c36020850161267f565b91506126d16040850161267f565b90509250925092565b6001600160a01b038116811461078a575f5ffd5b5f602082840312156126fe575f5ffd5b8135612709816126da565b9392505050565b803563ffffffff81168114612695575f5ffd5b5f60a0828403121561203c575f5ffd5b5f5f5f5f5f5f6101208789031215612749575f5ffd5b6127528761267f565b95506020870135945061276760408801612710565b93506127768860608901612723565b92506101008701356001600160401b03811115612791575f5ffd5b8701601f810189136127a1575f5ffd5b80356001600160401b038111156127b6575f5ffd5b8960208260051b84010111156127ca575f5ffd5b60208201935080925050509295509295509295565b634e487b7160e01b5f52604160045260245ffd5b5f5f60408385031215612804575f5ffd5b823561280f816126da565b915060208301356001600160401b03811115612829575f5ffd5b8301601f81018513612839575f5ffd5b80356001600160401b03811115612852576128526127df565b604051601f8201601f19908116603f011681016001600160401b0381118282101715612880576128806127df565b604052818152828201602001871015612897575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f5f5f60e084860312156128c8575f5ffd5b6128d184612710565b92506128df6020850161267f565b91506126d18560408601612723565b5f5f604083850312156128ff575f5ffd5b6129088361267f565b915061291660208401612710565b90509250929050565b5f5f5f60608486031215612931575f5ffd5b83356126b5816126da565b5f5f5f5f6080858703121561294f575f5ffd5b84359350602085013592506129666040860161267f565b915061297460608601612710565b905092959194509250565b5f5f5f5f6101008587031215612993575f5ffd5b61299d8686612723565b93506129ab60a0860161267f565b92506129b960c0860161267f565b915061297460e08601612710565b5f602082840312156129d7575f5ffd5b5035919050565b5f5f604083850312156129ef575f5ffd5b82356129fa816126da565b91506020830135612a0a816126da565b809150509250929050565b5f5f5f5f6101008587031215612a29575f5ffd5b612a328561267f565b935060208501359250612a4760408601612710565b91506129748660608701612723565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b5f60208284031215612afe575f5ffd5b611c7482612710565b5f60208284031215612b17575f5ffd5b813560ff81168114612709575f5ffd5b634e487b7160e01b5f52601160045260245ffd5b81810381811115611c7757611c77612b27565b602080825281018290525f6001600160fb1b03831115612b6c575f5ffd5b8260051b80856040850137919091016040019392505050565b6001600160401b038181168382160290811690818114612ba757612ba7612b27565b5092915050565b6001600160401b038281168282160390811115611c7757611c77612b27565b5f60208284031215612bdd575f5ffd5b611c748261267f565b80820180821115611c7757611c77612b27565b5f60208284031215612c09575f5ffd5b5051919050565b634e487b7160e01b5f52601260045260245ffd5b5f82612c3257612c32612c10565b500490565b8082028115828204841417611c7757611c77612b27565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b5f82612cbb57612cbb612c10565b500690565b5f60208284031215612cd0575f5ffd5b8151612709816126da565b5f60208284031215612ceb575f5ffd5b81518015158114612709575f5ffd5b634e487b7160e01b5f52600160045260245ffd5b5f5b83811015612d28578181015183820152602001612d10565b50505f910152565b5f8251612d41818460208701612d0e565b9190910192915050565b602081525f8251806020840152612d69816040850160208701612d0e565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209543ab1badc44a23602e2e677be18e5e9d57d645dc1383edec8f3fbb5ae9cd3c64736f6c634300081b0033