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-03-24T02:00:10.889280Z
Constructor Arguments
0x00000000000000000000000016700900000000000000000000000000000000060000000000000000000000001670090000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000013d5b0
Arg [0] (address) : 0x1670090000000000000000000000000000000006
Arg [1] (address) : 0x1670090000000000000000000000000000000005
Arg [2] (uint64) : 1299888
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_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_PROOF_VERIFIER = bytes32("proof_verifier"); bytes32 internal constant B_PROVER_SET = bytes32("prover_set"); bytes32 internal constant B_QUOTA_MANAGER = bytes32("quota_manager"); bytes32 internal constant B_SGX_WATCHDOG = bytes32("sgx_watchdog"); 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/"],"outputSelection":{"*":{"*":["abi","evm.bytecode.object","evm.bytecode.sourceMap","evm.bytecode.linkReferences","evm.deployedBytecode.object","evm.deployedBytecode.sourceMap","evm.deployedBytecode.linkReferences","evm.deployedBytecode.immutableReferences","evm.methodIdentifiers","metadata"]}},"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
0x61010060405230608052348015610014575f5ffd5b50604051612ffd380380612ffd83398101604081905261003391610141565b6001600160a01b03831660a0528261004961006a565b506001600160a01b0390911660c0526001600160401b031660e05250610191565b5f54610100900460ff16156100d55760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff90811614610124575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b80516001600160a01b038116811461013c575f5ffd5b919050565b5f5f5f60608486031215610153575f5ffd5b61015c84610126565b925061016a60208501610126565b60408501519092506001600160401b0381168114610186575f5ffd5b809150509250925092565b60805160a05160c05160e051612dfa6102035f395f81816105820152818161093001526113ce01525f81816103d9015281816109c301526117a501525f818161020e0152611bde01525f81816106c70152818161071001528181610a4801528181610a880152610b030152612dfa5ff3fe6080604052600436106101fc575f3560e01c8063893f546011610113578063ba9f41e81161009d578063e902461a1161006d578063e902461a146105f5578063ee82ac5e1461060f578063f2fde38b1461062e578063f940e3851461064d578063fd85eb2d1461066c575f5ffd5b8063ba9f41e814610571578063da69d3db146105a4578063dac5df78146105c3578063e30c3978146105d8575f5ffd5b8063a4b23554116100e3578063a4b23554146102a1578063a7137c0f146104d1578063a7e022d1146104f7578063b310e9e914610533578063b8c7b30c14610552575f5ffd5b8063893f5460146104375780638abf60771461047b5780638da5cb5b1461048f5780639ee512f2146104ac575f5ffd5b806348080a45116101945780635c975abb116101645780635c975abb146103a857806362d09453146103c8578063715018a6146103fb57806379ba50971461040f5780638456cb5914610423575f5ffd5b806348080a451461032e5780634f1ef2861461034d57806352d1902d14610360578063539b8ade14610382575f5ffd5b80633075db56116101cf5780633075db56146102bf57806333d5ac9b146102d35780633659cfe6146102f95780633f4ba83a1461031a575f5ffd5b806304f3bcec1461020057806312622e5b1461024b578063136dc4a8146102825780632f980473146102a1575b5f5ffd5b34801561020b575f5ffd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020015b60405180910390f35b348015610256575f5ffd5b5060fe5461026a906001600160401b031681565b6040516001600160401b039091168152602001610242565b34801561028d575f5ffd5b5061026a61029c36600461269a565b61068b565b3480156102ac575f5ffd5b505f5b6040519015158152602001610242565b3480156102ca575f5ffd5b506102af6106a5565b3480156102de575f5ffd5b5060fd5461026a90600160401b90046001600160401b031681565b348015610304575f5ffd5b506103186103133660046126ee565b6106bd565b005b348015610325575f5ffd5b5061031861078d565b348015610339575f5ffd5b50610318610348366004612733565b610811565b61031861035b3660046127f3565b610a3e565b34801561036b575f5ffd5b50610374610af7565b604051908152602001610242565b34801561038d575f5ffd5b5060fd5461026a90600160801b90046001600160401b031681565b3480156103b3575f5ffd5b506102af60c954610100900460ff1660021490565b3480156103d3575f5ffd5b5061022e7f000000000000000000000000000000000000000000000000000000000000000081565b348015610406575f5ffd5b50610318610ba8565b34801561041a575f5ffd5b50610318610bb9565b34801561042e575f5ffd5b50610318610c30565b348015610442575f5ffd5b506104566104513660046128b6565b610caf565b604080519384526001600160401b039283166020850152911690820152606001610242565b348015610486575f5ffd5b5061022e610ddb565b34801561049a575f5ffd5b506033546001600160a01b031661022e565b3480156104b7575f5ffd5b5061022e71777735367b36bc9b61c50022d9d0700db4ec81565b3480156104dc575f5ffd5b5060fd5461026a90600160c01b90046001600160401b031681565b348015610502575f5ffd5b506105166105113660046128ee565b610de9565b604080519283526001600160401b03909116602083015201610242565b34801561053e575f5ffd5b5061031861054d36600461291f565b610e04565b34801561055d575f5ffd5b5060fd5461026a906001600160401b031681565b34801561057c575f5ffd5b5061026a7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105af575f5ffd5b506103186105be36600461293c565b611036565b3480156105ce575f5ffd5b5061037460fc5481565b3480156105e3575f5ffd5b506065546001600160a01b031661022e565b348015610600575f5ffd5b5061051661051136600461297f565b34801561061a575f5ffd5b506103746106293660046129c7565b61104f565b348015610639575f5ffd5b506103186106483660046126ee565b611087565b348015610658575f5ffd5b506103186106673660046129de565b6110f8565b348015610677575f5ffd5b50610318610686366004612a15565b6112af565b5f6040516372c0090b60e11b815260040160405180910390fd5b5f60026106b460c95460ff1690565b60ff1614905090565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361070e5760405162461bcd60e51b815260040161070590612a56565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661074061145e565b6001600160a01b0316146107665760405162461bcd60e51b815260040161070590612aa2565b61076f81611479565b604080515f8082526020820190925261078a91839190611481565b50565b6107a160c954610100900460ff1660021490565b6107be5760405163bae6e2a960e01b815260040160405180910390fd5b6107d260c9805461ff001916610100179055565b6040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9060200160405180910390a161080f335f6115f0565b565b845f8190036108335760405163ec73295960e01b815260040160405180910390fd5b866001600160401b0316805f0361085d5760405163ec73295960e01b815260040160405180910390fd5b61086d6060860160408701612aee565b63ffffffff16805f036108935760405163ec73295960e01b815260040160405180910390fd5b6108a06020870187612b07565b60ff16805f036108c35760405163ec73295960e01b815260040160405180910390fd5b3371777735367b36bc9b61c50022d9d0700db4ec146108f557604051636494e9f760e01b815260040160405180910390fd5b600261090360c95460ff1690565b60ff16036109245760405163dfc60d8560e01b815260040160405180910390fd5b61092e60026115f8565b7f00000000000000000000000000000000000000000000000000000000000000006001600160401b031643101561097857604051631799c89b60e01b815260040160405180910390fd5b5f610984600143612b3b565b905061098f8161160e565b6109998989611646565b6109a38b8b61172d565b6109ac8161184b565b604051633b78c86560e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633b78c865906109fa908a908a90600401612b4e565b5f604051808303815f87803b158015610a11575f5ffd5b505af1158015610a23573d5f5f3e3d5ffd5b5050505050610a3260016115f8565b50505050505050505050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610a865760405162461bcd60e51b815260040161070590612a56565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610ab861145e565b6001600160a01b031614610ade5760405162461bcd60e51b815260040161070590612aa2565b610ae782611479565b610af382826001611481565b5050565b5f306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b965760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610705565b505f516020612d7e5f395f51905f5290565b610bb06118e2565b61080f5f61193c565b60655433906001600160a01b03168114610c275760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610705565b61078a8161193c565b610c4460c954610100900460ff1660021490565b15610c625760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200160405180910390a161080f3360016115f0565b5f808080610cc06020860186612b07565b60ff16610cd36060870160408801612aee565b63ffffffff16610ce39190612b85565b60fd54909150610d07906001600160401b03600160c01b8204811691849116611955565b90935091505f610d1d6060870160408801612aee565b63ffffffff1660fd60109054906101000a90046001600160401b031688610d449190612bae565b610d4e9190612b85565b9050610d6060a0870160808801612aee565b63ffffffff1615801590610d915750610d7f60a0870160808801612aee565b63ffffffff16816001600160401b0316115b15610daf57610da660a0870160808801612aee565b63ffffffff1690505b610dcb8484838b610dc660808c0160608d01612bcd565b611a6d565b9099949850965092945050505050565b5f610de461145e565b905090565b5f5f6040516372c0090b60e11b815260040160405180910390fd5b5f54610100900460ff1615808015610e2257505f54600160ff909116105b80610e3b5750303b158015610e3b57505f5460ff166001145b610e9e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610705565b5f805460ff191660011790558015610ebf575f805461ff0019166101001790555b610ec884611aed565b826001600160401b03165f03610ef1576040516308279a2560e31b815260040160405180910390fd5b46836001600160401b031603610f1a576040516308279a2560e31b815260040160405180910390fd5b60014611610f3b57604051638f972ecb60e01b815260040160405180910390fd5b6001600160401b03461115610f6357604051638f972ecb60e01b815260040160405180910390fd5b4315610fad5743600103610f94575f610f7d600143612b3b565b5f81815260fb602052604090209040905550610fad565b604051635a0f9e4160e11b815260040160405180910390fd5b60fe80546001600160401b0380861667ffffffffffffffff199283161790925560fd805492851692909116919091179055610fe743611b4b565b5060fc558015611030575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6040516372c0090b60e11b815260040160405180910390fd5b5f43821061105e57505f919050565b4361106b83610100612be6565b1061107557504090565b505f90815260fb602052604090205490565b61108f6118e2565b606580546001600160a01b0383166001600160a01b031990911681179091556110c06033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b806001600160a01b0381166111205760405163538ba4f960e01b815260040160405180910390fd5b61113460c954610100900460ff1660021490565b156111525760405163bae6e2a960e01b815260040160405180910390fd5b693bb4ba34323930bbb2b960b11b6111726033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614806111ac5750611197816001611bdb565b6001600160a01b0316336001600160a01b0316145b6111c9576040516395383ea160e01b815260040160405180910390fd5b60026111d760c95460ff1690565b60ff16036111f85760405163dfc60d8560e01b815260040160405180910390fd5b61120260026115f8565b6001600160a01b038416611228576112236001600160a01b03841647611c7d565b6112a5565b6040516370a0823160e01b81523060048201526112a59084906001600160a01b038716906370a0823190602401602060405180830381865afa158015611270573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112949190612bf9565b6001600160a01b0387169190611c88565b61103060016115f8565b825f8190036112d15760405163ec73295960e01b815260040160405180910390fd5b846001600160401b0316805f036112fb5760405163ec73295960e01b815260040160405180910390fd5b61130b6060840160408501612aee565b63ffffffff16805f036113315760405163ec73295960e01b815260040160405180910390fd5b61133e6020850185612b07565b60ff16805f036113615760405163ec73295960e01b815260040160405180910390fd5b3371777735367b36bc9b61c50022d9d0700db4ec1461139357604051636494e9f760e01b815260040160405180910390fd5b60026113a160c95460ff1690565b60ff16036113c25760405163dfc60d8560e01b815260040160405180910390fd5b6113cc60026115f8565b7f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316431061141557604051631799c89b60e01b815260040160405180910390fd5b5f611421600143612b3b565b905061142c8161160e565b6114368787611646565b611440898961172d565b6114498161184b565b5061145460016115f8565b5050505050505050565b5f516020612d7e5f395f51905f52546001600160a01b031690565b61078a6118e2565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156114b9576114b483611cda565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611513575060408051601f3d908101601f1916820190925261151091810190612bf9565b60015b6115765760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610705565b5f516020612d7e5f395f51905f5281146115e45760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610705565b506114b4838383611d75565b610af36118e2565b60c9805460ff191660ff92909216919091179055565b5f5f61161983611b4b565b915091508160fc541461163f5760405163d719258d60e01b815260040160405180910390fd5b60fc555050565b5f5f5f611654854286610caf565b9250925092508248148061166557505f5b611682576040516336d54d4f60e11b815260040160405180910390fd5b60fd5460408051600160c01b83046001600160401b039081168252858116602083015292831681830152918316606083015260808201859052517f781ae5c2215806150d5c71a4ed5336e5dc3ad32aef04fc0f626a6ee0c2f8d1c89181900360a00190a160fd805477ffffffffffffffffffffffffffffffff000000000000000016600160c01b6001600160401b039485160267ffffffffffffffff19161791909216179055505050565b60fd546001600160401b03600160401b90910481169083161161174e575050565b60fe546040516313e4299d60e21b81526001600160401b0391821660048201527f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da16960248201529083166044820152606481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634f90a674906084016020604051808303815f875af11580156117f3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118179190612bf9565b505060fd80546001600160401b03909216600160401b026fffffffffffffffff000000000000000019909216919091179055565b5f81815260fb60205260409081902082409081905560fd80546001600160401b03428116600160801b0267ffffffffffffffff60801b1983168117909355935192937f41c3f410f5c8ac36bb46b1dccef0de0f964087c9e688795fa02ecfa2c20b3fe4936118d6938693908316921691909117909182526001600160401b0316602082015260400190565b60405180910390a15050565b6033546001600160a01b0316331461080f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610705565b606580546001600160a01b031916905561078a81611d99565b5f80670de0b6b3a76400006001600160401b038616820361197c5784849250925050611a65565b6001600160401b03851615806119a35750846001600160401b0316866001600160401b0316145b806119c157506119b4815f19612c24565b856001600160401b031610155b156119d25785849250925050611a65565b5f866001600160401b0316866001600160401b0316836119f29190612c37565b6119fc9190612c24565b9050801580611a1157506001600160ff1b0381115b15611a23578585935093505050611a65565b5f611a2d82611dea565b90505f828702828902015f811260018114611a4c578582049250611a50565b5f92505b505087611a5c82612007565b95509550505050505b935093915050565b5f8080611a8963ffffffff86166001600160401b038916612be6565b9050856001600160401b03168111611aa2576001611ab5565b611ab56001600160401b03871682612b3b565b9050611ad46001600160401b03611ace83878316612019565b9061202e565b9150611ae08883612042565b9250509550959350505050565b5f54610100900460ff16611b135760405162461bcd60e51b815260040161070590612c4e565b611b1b612084565b611b396001600160a01b03821615611b33578161193c565b3361193c565b5060c9805461ff001916610100179055565b5f5f611b5561265f565b46611fe08201525f5b60ff81108015611b715750806001018510155b15611ba2575f198186030180408360ff83066101008110611b9457611b94612c99565b602002015250600101611b5e565b5061200081209250834081611bb860ff87612cad565b6101008110611bc957611bc9612c99565b60200201526120009020919391925050565b5f7f0000000000000000000000000000000000000000000000000000000000000000604051633632b1fb60e11b81524660048201526024810185905283151560448201526001600160a01b039190911690636c6563f690606401602060405180830381865afa158015611c50573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c749190612cc0565b90505b92915050565b610af382825a6120aa565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526114b49084906120ed565b6001600160a01b0381163b611d475760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610705565b5f516020612d7e5f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b611d7e836121c0565b5f82511180611d8a5750805b156114b45761103083836121ff565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6fffffffffffffffffffffffffffffffff811160071b81811c6001600160401b031060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b175f8213611e4657631615e6385f526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd1901909102780a09507084cc699bb0e71ea869ffffffffffffffffffffffff190105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b5f611c77826001600160401b0361202e565b5f8183116120275781611c74565b5090919050565b5f81831161203c5782611c74565b50919050565b5f826001600160401b03165f0361205b57506001611c77565b611c746001846001600160401b03166120748686612224565b61207e9190612c24565b90612019565b5f54610100900460ff1661080f5760405162461bcd60e51b815260040161070590612c4e565b815f036120b657505050565b6120d083838360405180602001604052805f8152506122b2565b6114b457604051634c67134d60e11b815260040160405180910390fd5b5f612141826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122ef9092919063ffffffff16565b905080515f14806121615750808060200190518101906121619190612cdb565b6114b45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610705565b6121c981611cda565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b6060611c748383604051806060016040528060278152602001612d9e602791396122fd565b5f826001600160401b03165f0361223d5761223d612cfa565b5f836001600160401b0316836001600160401b0316670de0b6b3a76400006122659190612c37565b61226f9190612c24565b9050680755bf798b4a1bf1e481111561228e5750680755bf798b4a1bf1e45b670de0b6b3a76400006122a082612371565b6122aa9190612c24565b949350505050565b5f6001600160a01b0385166122da57604051634c67134d60e11b815260040160405180910390fd5b5f5f835160208501878988f195945050505050565b60606122aa84845f856124eb565b60605f5f856001600160a01b0316856040516123199190612d30565b5f60405180830381855af49150503d805f8114612351576040519150601f19603f3d011682016040523d82523d5f602084013e612356565b606091505b5091509150612367868383876125c2565b9695505050505050565b5f68023f2fa8f6da5b9d2819821361238857919050565b680755bf798b4a1bf1e582126123a55763a37bfec95f526004601cfd5b6503782dace9d9604e83901b0591505f60606bb17217f7d1cf79abc9e3b39884821b056001605f1b01901d6bb17217f7d1cf79abc9e3b39881029093036c240c330e9fb2d9cbaf0fd5aafb1981018102606090811d6d0277594991cfc85f6e2461837cd9018202811d6d1a521255e34f6a5061b25ef1c9c319018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d6e02c72388d9f74f51a9331fed693f1419018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084016d01d3967ed30fc4f89c02bab5708119010290911d6e0587f503bb6ea29d25fcb740196450019091026d360d7aeea093263ecc6e0ecb291760621b010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b60608247101561254c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610705565b5f5f866001600160a01b031685876040516125679190612d30565b5f6040518083038185875af1925050503d805f81146125a1576040519150601f19603f3d011682016040523d82523d5f602084013e6125a6565b606091505b50915091506125b7878383876125c2565b979650505050505050565b606083156126305782515f03612629576001600160a01b0385163b6126295760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610705565b50816122aa565b6122aa83838151156126455781518083602001fd5b8060405162461bcd60e51b81526004016107059190612d4b565b604051806120000160405280610100906020820280368337509192915050565b80356001600160401b0381168114612695575f5ffd5b919050565b5f5f5f606084860312156126ac575f5ffd5b6126b58461267f565b92506126c36020850161267f565b91506126d16040850161267f565b90509250925092565b6001600160a01b038116811461078a575f5ffd5b5f602082840312156126fe575f5ffd5b8135612709816126da565b9392505050565b803563ffffffff81168114612695575f5ffd5b5f60a0828403121561203c575f5ffd5b5f5f5f5f5f5f6101208789031215612749575f5ffd5b6127528761267f565b95506020870135945061276760408801612710565b93506127768860608901612723565b92506101008701356001600160401b03811115612791575f5ffd5b8701601f810189136127a1575f5ffd5b80356001600160401b038111156127b6575f5ffd5b8960208260051b84010111156127ca575f5ffd5b60208201935080925050509295509295509295565b634e487b7160e01b5f52604160045260245ffd5b5f5f60408385031215612804575f5ffd5b823561280f816126da565b915060208301356001600160401b03811115612829575f5ffd5b8301601f81018513612839575f5ffd5b80356001600160401b03811115612852576128526127df565b604051601f8201601f19908116603f011681016001600160401b0381118282101715612880576128806127df565b604052818152828201602001871015612897575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f5f5f60e084860312156128c8575f5ffd5b6128d184612710565b92506128df6020850161267f565b91506126d18560408601612723565b5f5f604083850312156128ff575f5ffd5b6129088361267f565b915061291660208401612710565b90509250929050565b5f5f5f60608486031215612931575f5ffd5b83356126b5816126da565b5f5f5f5f6080858703121561294f575f5ffd5b84359350602085013592506129666040860161267f565b915061297460608601612710565b905092959194509250565b5f5f5f5f6101008587031215612993575f5ffd5b61299d8686612723565b93506129ab60a0860161267f565b92506129b960c0860161267f565b915061297460e08601612710565b5f602082840312156129d7575f5ffd5b5035919050565b5f5f604083850312156129ef575f5ffd5b82356129fa816126da565b91506020830135612a0a816126da565b809150509250929050565b5f5f5f5f6101008587031215612a29575f5ffd5b612a328561267f565b935060208501359250612a4760408601612710565b91506129748660608701612723565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b5f60208284031215612afe575f5ffd5b611c7482612710565b5f60208284031215612b17575f5ffd5b813560ff81168114612709575f5ffd5b634e487b7160e01b5f52601160045260245ffd5b81810381811115611c7757611c77612b27565b602080825281018290525f6001600160fb1b03831115612b6c575f5ffd5b8260051b80856040850137919091016040019392505050565b6001600160401b038181168382160290811690818114612ba757612ba7612b27565b5092915050565b6001600160401b038281168282160390811115611c7757611c77612b27565b5f60208284031215612bdd575f5ffd5b611c748261267f565b80820180821115611c7757611c77612b27565b5f60208284031215612c09575f5ffd5b5051919050565b634e487b7160e01b5f52601260045260245ffd5b5f82612c3257612c32612c10565b500490565b8082028115828204841417611c7757611c77612b27565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b5f82612cbb57612cbb612c10565b500690565b5f60208284031215612cd0575f5ffd5b8151612709816126da565b5f60208284031215612ceb575f5ffd5b81518015158114612709575f5ffd5b634e487b7160e01b5f52600160045260245ffd5b5f5b83811015612d28578181015183820152602001612d10565b50505f910152565b5f8251612d41818460208701612d0e565b9190910192915050565b602081525f8251806020840152612d69816040850160208701612d0e565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122080203c3f112228d497c8fbc7bec10359ddec6cf1ad16b1d556e17b08dd27b49464736f6c634300081b003300000000000000000000000016700900000000000000000000000000000000060000000000000000000000001670090000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000013d5b0
Deployed ByteCode
0x6080604052600436106101fc575f3560e01c8063893f546011610113578063ba9f41e81161009d578063e902461a1161006d578063e902461a146105f5578063ee82ac5e1461060f578063f2fde38b1461062e578063f940e3851461064d578063fd85eb2d1461066c575f5ffd5b8063ba9f41e814610571578063da69d3db146105a4578063dac5df78146105c3578063e30c3978146105d8575f5ffd5b8063a4b23554116100e3578063a4b23554146102a1578063a7137c0f146104d1578063a7e022d1146104f7578063b310e9e914610533578063b8c7b30c14610552575f5ffd5b8063893f5460146104375780638abf60771461047b5780638da5cb5b1461048f5780639ee512f2146104ac575f5ffd5b806348080a45116101945780635c975abb116101645780635c975abb146103a857806362d09453146103c8578063715018a6146103fb57806379ba50971461040f5780638456cb5914610423575f5ffd5b806348080a451461032e5780634f1ef2861461034d57806352d1902d14610360578063539b8ade14610382575f5ffd5b80633075db56116101cf5780633075db56146102bf57806333d5ac9b146102d35780633659cfe6146102f95780633f4ba83a1461031a575f5ffd5b806304f3bcec1461020057806312622e5b1461024b578063136dc4a8146102825780632f980473146102a1575b5f5ffd5b34801561020b575f5ffd5b507f00000000000000000000000016700900000000000000000000000000000000065b6040516001600160a01b0390911681526020015b60405180910390f35b348015610256575f5ffd5b5060fe5461026a906001600160401b031681565b6040516001600160401b039091168152602001610242565b34801561028d575f5ffd5b5061026a61029c36600461269a565b61068b565b3480156102ac575f5ffd5b505f5b6040519015158152602001610242565b3480156102ca575f5ffd5b506102af6106a5565b3480156102de575f5ffd5b5060fd5461026a90600160401b90046001600160401b031681565b348015610304575f5ffd5b506103186103133660046126ee565b6106bd565b005b348015610325575f5ffd5b5061031861078d565b348015610339575f5ffd5b50610318610348366004612733565b610811565b61031861035b3660046127f3565b610a3e565b34801561036b575f5ffd5b50610374610af7565b604051908152602001610242565b34801561038d575f5ffd5b5060fd5461026a90600160801b90046001600160401b031681565b3480156103b3575f5ffd5b506102af60c954610100900460ff1660021490565b3480156103d3575f5ffd5b5061022e7f000000000000000000000000167009000000000000000000000000000000000581565b348015610406575f5ffd5b50610318610ba8565b34801561041a575f5ffd5b50610318610bb9565b34801561042e575f5ffd5b50610318610c30565b348015610442575f5ffd5b506104566104513660046128b6565b610caf565b604080519384526001600160401b039283166020850152911690820152606001610242565b348015610486575f5ffd5b5061022e610ddb565b34801561049a575f5ffd5b506033546001600160a01b031661022e565b3480156104b7575f5ffd5b5061022e71777735367b36bc9b61c50022d9d0700db4ec81565b3480156104dc575f5ffd5b5060fd5461026a90600160c01b90046001600160401b031681565b348015610502575f5ffd5b506105166105113660046128ee565b610de9565b604080519283526001600160401b03909116602083015201610242565b34801561053e575f5ffd5b5061031861054d36600461291f565b610e04565b34801561055d575f5ffd5b5060fd5461026a906001600160401b031681565b34801561057c575f5ffd5b5061026a7f000000000000000000000000000000000000000000000000000000000013d5b081565b3480156105af575f5ffd5b506103186105be36600461293c565b611036565b3480156105ce575f5ffd5b5061037460fc5481565b3480156105e3575f5ffd5b506065546001600160a01b031661022e565b348015610600575f5ffd5b5061051661051136600461297f565b34801561061a575f5ffd5b506103746106293660046129c7565b61104f565b348015610639575f5ffd5b506103186106483660046126ee565b611087565b348015610658575f5ffd5b506103186106673660046129de565b6110f8565b348015610677575f5ffd5b50610318610686366004612a15565b6112af565b5f6040516372c0090b60e11b815260040160405180910390fd5b5f60026106b460c95460ff1690565b60ff1614905090565b6001600160a01b037f00000000000000000000000071fb266ce71e11d73cce9be057401825e076f70416300361070e5760405162461bcd60e51b815260040161070590612a56565b60405180910390fd5b7f00000000000000000000000071fb266ce71e11d73cce9be057401825e076f7046001600160a01b031661074061145e565b6001600160a01b0316146107665760405162461bcd60e51b815260040161070590612aa2565b61076f81611479565b604080515f8082526020820190925261078a91839190611481565b50565b6107a160c954610100900460ff1660021490565b6107be5760405163bae6e2a960e01b815260040160405180910390fd5b6107d260c9805461ff001916610100179055565b6040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9060200160405180910390a161080f335f6115f0565b565b845f8190036108335760405163ec73295960e01b815260040160405180910390fd5b866001600160401b0316805f0361085d5760405163ec73295960e01b815260040160405180910390fd5b61086d6060860160408701612aee565b63ffffffff16805f036108935760405163ec73295960e01b815260040160405180910390fd5b6108a06020870187612b07565b60ff16805f036108c35760405163ec73295960e01b815260040160405180910390fd5b3371777735367b36bc9b61c50022d9d0700db4ec146108f557604051636494e9f760e01b815260040160405180910390fd5b600261090360c95460ff1690565b60ff16036109245760405163dfc60d8560e01b815260040160405180910390fd5b61092e60026115f8565b7f000000000000000000000000000000000000000000000000000000000013d5b06001600160401b031643101561097857604051631799c89b60e01b815260040160405180910390fd5b5f610984600143612b3b565b905061098f8161160e565b6109998989611646565b6109a38b8b61172d565b6109ac8161184b565b604051633b78c86560e01b81526001600160a01b037f00000000000000000000000016700900000000000000000000000000000000051690633b78c865906109fa908a908a90600401612b4e565b5f604051808303815f87803b158015610a11575f5ffd5b505af1158015610a23573d5f5f3e3d5ffd5b5050505050610a3260016115f8565b50505050505050505050565b6001600160a01b037f00000000000000000000000071fb266ce71e11d73cce9be057401825e076f704163003610a865760405162461bcd60e51b815260040161070590612a56565b7f00000000000000000000000071fb266ce71e11d73cce9be057401825e076f7046001600160a01b0316610ab861145e565b6001600160a01b031614610ade5760405162461bcd60e51b815260040161070590612aa2565b610ae782611479565b610af382826001611481565b5050565b5f306001600160a01b037f00000000000000000000000071fb266ce71e11d73cce9be057401825e076f7041614610b965760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610705565b505f516020612d7e5f395f51905f5290565b610bb06118e2565b61080f5f61193c565b60655433906001600160a01b03168114610c275760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610705565b61078a8161193c565b610c4460c954610100900460ff1660021490565b15610c625760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200160405180910390a161080f3360016115f0565b5f808080610cc06020860186612b07565b60ff16610cd36060870160408801612aee565b63ffffffff16610ce39190612b85565b60fd54909150610d07906001600160401b03600160c01b8204811691849116611955565b90935091505f610d1d6060870160408801612aee565b63ffffffff1660fd60109054906101000a90046001600160401b031688610d449190612bae565b610d4e9190612b85565b9050610d6060a0870160808801612aee565b63ffffffff1615801590610d915750610d7f60a0870160808801612aee565b63ffffffff16816001600160401b0316115b15610daf57610da660a0870160808801612aee565b63ffffffff1690505b610dcb8484838b610dc660808c0160608d01612bcd565b611a6d565b9099949850965092945050505050565b5f610de461145e565b905090565b5f5f6040516372c0090b60e11b815260040160405180910390fd5b5f54610100900460ff1615808015610e2257505f54600160ff909116105b80610e3b5750303b158015610e3b57505f5460ff166001145b610e9e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610705565b5f805460ff191660011790558015610ebf575f805461ff0019166101001790555b610ec884611aed565b826001600160401b03165f03610ef1576040516308279a2560e31b815260040160405180910390fd5b46836001600160401b031603610f1a576040516308279a2560e31b815260040160405180910390fd5b60014611610f3b57604051638f972ecb60e01b815260040160405180910390fd5b6001600160401b03461115610f6357604051638f972ecb60e01b815260040160405180910390fd5b4315610fad5743600103610f94575f610f7d600143612b3b565b5f81815260fb602052604090209040905550610fad565b604051635a0f9e4160e11b815260040160405180910390fd5b60fe80546001600160401b0380861667ffffffffffffffff199283161790925560fd805492851692909116919091179055610fe743611b4b565b5060fc558015611030575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6040516372c0090b60e11b815260040160405180910390fd5b5f43821061105e57505f919050565b4361106b83610100612be6565b1061107557504090565b505f90815260fb602052604090205490565b61108f6118e2565b606580546001600160a01b0383166001600160a01b031990911681179091556110c06033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b806001600160a01b0381166111205760405163538ba4f960e01b815260040160405180910390fd5b61113460c954610100900460ff1660021490565b156111525760405163bae6e2a960e01b815260040160405180910390fd5b693bb4ba34323930bbb2b960b11b6111726033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614806111ac5750611197816001611bdb565b6001600160a01b0316336001600160a01b0316145b6111c9576040516395383ea160e01b815260040160405180910390fd5b60026111d760c95460ff1690565b60ff16036111f85760405163dfc60d8560e01b815260040160405180910390fd5b61120260026115f8565b6001600160a01b038416611228576112236001600160a01b03841647611c7d565b6112a5565b6040516370a0823160e01b81523060048201526112a59084906001600160a01b038716906370a0823190602401602060405180830381865afa158015611270573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112949190612bf9565b6001600160a01b0387169190611c88565b61103060016115f8565b825f8190036112d15760405163ec73295960e01b815260040160405180910390fd5b846001600160401b0316805f036112fb5760405163ec73295960e01b815260040160405180910390fd5b61130b6060840160408501612aee565b63ffffffff16805f036113315760405163ec73295960e01b815260040160405180910390fd5b61133e6020850185612b07565b60ff16805f036113615760405163ec73295960e01b815260040160405180910390fd5b3371777735367b36bc9b61c50022d9d0700db4ec1461139357604051636494e9f760e01b815260040160405180910390fd5b60026113a160c95460ff1690565b60ff16036113c25760405163dfc60d8560e01b815260040160405180910390fd5b6113cc60026115f8565b7f000000000000000000000000000000000000000000000000000000000013d5b06001600160401b0316431061141557604051631799c89b60e01b815260040160405180910390fd5b5f611421600143612b3b565b905061142c8161160e565b6114368787611646565b611440898961172d565b6114498161184b565b5061145460016115f8565b5050505050505050565b5f516020612d7e5f395f51905f52546001600160a01b031690565b61078a6118e2565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156114b9576114b483611cda565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611513575060408051601f3d908101601f1916820190925261151091810190612bf9565b60015b6115765760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610705565b5f516020612d7e5f395f51905f5281146115e45760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610705565b506114b4838383611d75565b610af36118e2565b60c9805460ff191660ff92909216919091179055565b5f5f61161983611b4b565b915091508160fc541461163f5760405163d719258d60e01b815260040160405180910390fd5b60fc555050565b5f5f5f611654854286610caf565b9250925092508248148061166557505f5b611682576040516336d54d4f60e11b815260040160405180910390fd5b60fd5460408051600160c01b83046001600160401b039081168252858116602083015292831681830152918316606083015260808201859052517f781ae5c2215806150d5c71a4ed5336e5dc3ad32aef04fc0f626a6ee0c2f8d1c89181900360a00190a160fd805477ffffffffffffffffffffffffffffffff000000000000000016600160c01b6001600160401b039485160267ffffffffffffffff19161791909216179055505050565b60fd546001600160401b03600160401b90910481169083161161174e575050565b60fe546040516313e4299d60e21b81526001600160401b0391821660048201527f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da16960248201529083166044820152606481018290527f00000000000000000000000016700900000000000000000000000000000000056001600160a01b031690634f90a674906084016020604051808303815f875af11580156117f3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118179190612bf9565b505060fd80546001600160401b03909216600160401b026fffffffffffffffff000000000000000019909216919091179055565b5f81815260fb60205260409081902082409081905560fd80546001600160401b03428116600160801b0267ffffffffffffffff60801b1983168117909355935192937f41c3f410f5c8ac36bb46b1dccef0de0f964087c9e688795fa02ecfa2c20b3fe4936118d6938693908316921691909117909182526001600160401b0316602082015260400190565b60405180910390a15050565b6033546001600160a01b0316331461080f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610705565b606580546001600160a01b031916905561078a81611d99565b5f80670de0b6b3a76400006001600160401b038616820361197c5784849250925050611a65565b6001600160401b03851615806119a35750846001600160401b0316866001600160401b0316145b806119c157506119b4815f19612c24565b856001600160401b031610155b156119d25785849250925050611a65565b5f866001600160401b0316866001600160401b0316836119f29190612c37565b6119fc9190612c24565b9050801580611a1157506001600160ff1b0381115b15611a23578585935093505050611a65565b5f611a2d82611dea565b90505f828702828902015f811260018114611a4c578582049250611a50565b5f92505b505087611a5c82612007565b95509550505050505b935093915050565b5f8080611a8963ffffffff86166001600160401b038916612be6565b9050856001600160401b03168111611aa2576001611ab5565b611ab56001600160401b03871682612b3b565b9050611ad46001600160401b03611ace83878316612019565b9061202e565b9150611ae08883612042565b9250509550959350505050565b5f54610100900460ff16611b135760405162461bcd60e51b815260040161070590612c4e565b611b1b612084565b611b396001600160a01b03821615611b33578161193c565b3361193c565b5060c9805461ff001916610100179055565b5f5f611b5561265f565b46611fe08201525f5b60ff81108015611b715750806001018510155b15611ba2575f198186030180408360ff83066101008110611b9457611b94612c99565b602002015250600101611b5e565b5061200081209250834081611bb860ff87612cad565b6101008110611bc957611bc9612c99565b60200201526120009020919391925050565b5f7f0000000000000000000000001670090000000000000000000000000000000006604051633632b1fb60e11b81524660048201526024810185905283151560448201526001600160a01b039190911690636c6563f690606401602060405180830381865afa158015611c50573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c749190612cc0565b90505b92915050565b610af382825a6120aa565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526114b49084906120ed565b6001600160a01b0381163b611d475760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610705565b5f516020612d7e5f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b611d7e836121c0565b5f82511180611d8a5750805b156114b45761103083836121ff565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6fffffffffffffffffffffffffffffffff811160071b81811c6001600160401b031060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b175f8213611e4657631615e6385f526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd1901909102780a09507084cc699bb0e71ea869ffffffffffffffffffffffff190105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b5f611c77826001600160401b0361202e565b5f8183116120275781611c74565b5090919050565b5f81831161203c5782611c74565b50919050565b5f826001600160401b03165f0361205b57506001611c77565b611c746001846001600160401b03166120748686612224565b61207e9190612c24565b90612019565b5f54610100900460ff1661080f5760405162461bcd60e51b815260040161070590612c4e565b815f036120b657505050565b6120d083838360405180602001604052805f8152506122b2565b6114b457604051634c67134d60e11b815260040160405180910390fd5b5f612141826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122ef9092919063ffffffff16565b905080515f14806121615750808060200190518101906121619190612cdb565b6114b45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610705565b6121c981611cda565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b6060611c748383604051806060016040528060278152602001612d9e602791396122fd565b5f826001600160401b03165f0361223d5761223d612cfa565b5f836001600160401b0316836001600160401b0316670de0b6b3a76400006122659190612c37565b61226f9190612c24565b9050680755bf798b4a1bf1e481111561228e5750680755bf798b4a1bf1e45b670de0b6b3a76400006122a082612371565b6122aa9190612c24565b949350505050565b5f6001600160a01b0385166122da57604051634c67134d60e11b815260040160405180910390fd5b5f5f835160208501878988f195945050505050565b60606122aa84845f856124eb565b60605f5f856001600160a01b0316856040516123199190612d30565b5f60405180830381855af49150503d805f8114612351576040519150601f19603f3d011682016040523d82523d5f602084013e612356565b606091505b5091509150612367868383876125c2565b9695505050505050565b5f68023f2fa8f6da5b9d2819821361238857919050565b680755bf798b4a1bf1e582126123a55763a37bfec95f526004601cfd5b6503782dace9d9604e83901b0591505f60606bb17217f7d1cf79abc9e3b39884821b056001605f1b01901d6bb17217f7d1cf79abc9e3b39881029093036c240c330e9fb2d9cbaf0fd5aafb1981018102606090811d6d0277594991cfc85f6e2461837cd9018202811d6d1a521255e34f6a5061b25ef1c9c319018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d6e02c72388d9f74f51a9331fed693f1419018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084016d01d3967ed30fc4f89c02bab5708119010290911d6e0587f503bb6ea29d25fcb740196450019091026d360d7aeea093263ecc6e0ecb291760621b010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b60608247101561254c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610705565b5f5f866001600160a01b031685876040516125679190612d30565b5f6040518083038185875af1925050503d805f81146125a1576040519150601f19603f3d011682016040523d82523d5f602084013e6125a6565b606091505b50915091506125b7878383876125c2565b979650505050505050565b606083156126305782515f03612629576001600160a01b0385163b6126295760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610705565b50816122aa565b6122aa83838151156126455781518083602001fd5b8060405162461bcd60e51b81526004016107059190612d4b565b604051806120000160405280610100906020820280368337509192915050565b80356001600160401b0381168114612695575f5ffd5b919050565b5f5f5f606084860312156126ac575f5ffd5b6126b58461267f565b92506126c36020850161267f565b91506126d16040850161267f565b90509250925092565b6001600160a01b038116811461078a575f5ffd5b5f602082840312156126fe575f5ffd5b8135612709816126da565b9392505050565b803563ffffffff81168114612695575f5ffd5b5f60a0828403121561203c575f5ffd5b5f5f5f5f5f5f6101208789031215612749575f5ffd5b6127528761267f565b95506020870135945061276760408801612710565b93506127768860608901612723565b92506101008701356001600160401b03811115612791575f5ffd5b8701601f810189136127a1575f5ffd5b80356001600160401b038111156127b6575f5ffd5b8960208260051b84010111156127ca575f5ffd5b60208201935080925050509295509295509295565b634e487b7160e01b5f52604160045260245ffd5b5f5f60408385031215612804575f5ffd5b823561280f816126da565b915060208301356001600160401b03811115612829575f5ffd5b8301601f81018513612839575f5ffd5b80356001600160401b03811115612852576128526127df565b604051601f8201601f19908116603f011681016001600160401b0381118282101715612880576128806127df565b604052818152828201602001871015612897575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f5f5f60e084860312156128c8575f5ffd5b6128d184612710565b92506128df6020850161267f565b91506126d18560408601612723565b5f5f604083850312156128ff575f5ffd5b6129088361267f565b915061291660208401612710565b90509250929050565b5f5f5f60608486031215612931575f5ffd5b83356126b5816126da565b5f5f5f5f6080858703121561294f575f5ffd5b84359350602085013592506129666040860161267f565b915061297460608601612710565b905092959194509250565b5f5f5f5f6101008587031215612993575f5ffd5b61299d8686612723565b93506129ab60a0860161267f565b92506129b960c0860161267f565b915061297460e08601612710565b5f602082840312156129d7575f5ffd5b5035919050565b5f5f604083850312156129ef575f5ffd5b82356129fa816126da565b91506020830135612a0a816126da565b809150509250929050565b5f5f5f5f6101008587031215612a29575f5ffd5b612a328561267f565b935060208501359250612a4760408601612710565b91506129748660608701612723565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b5f60208284031215612afe575f5ffd5b611c7482612710565b5f60208284031215612b17575f5ffd5b813560ff81168114612709575f5ffd5b634e487b7160e01b5f52601160045260245ffd5b81810381811115611c7757611c77612b27565b602080825281018290525f6001600160fb1b03831115612b6c575f5ffd5b8260051b80856040850137919091016040019392505050565b6001600160401b038181168382160290811690818114612ba757612ba7612b27565b5092915050565b6001600160401b038281168282160390811115611c7757611c77612b27565b5f60208284031215612bdd575f5ffd5b611c748261267f565b80820180821115611c7757611c77612b27565b5f60208284031215612c09575f5ffd5b5051919050565b634e487b7160e01b5f52601260045260245ffd5b5f82612c3257612c32612c10565b500490565b8082028115828204841417611c7757611c77612b27565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b5f82612cbb57612cbb612c10565b500690565b5f60208284031215612cd0575f5ffd5b8151612709816126da565b5f60208284031215612ceb575f5ffd5b81518015158114612709575f5ffd5b634e487b7160e01b5f52600160045260245ffd5b5f5b83811015612d28578181015183820152602001612d10565b50505f910152565b5f8251612d41818460208701612d0e565b9190910192915050565b602081525f8251806020840152612d69816040850160208701612d0e565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122080203c3f112228d497c8fbc7bec10359ddec6cf1ad16b1d556e17b08dd27b49464736f6c634300081b0033