Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- HeklaTaikoL2
- Optimization enabled
- true
- Compiler version
- v0.8.27+commit.40a35a09
- Optimization runs
- 200
- EVM Version
- shanghai
- Verified at
- 2024-10-29T06:35:15.331637Z
contracts/layer2/hekla/HeklaTaikoL2.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import "../based/TaikoL2.sol"; /// @title HeklaTaikoL2 /// @custom:security-contact security@taiko.xyz contract HeklaTaikoL2 is TaikoL2 { function ontakeForkHeight() public pure override returns (uint64) { return 840_512; } }
contracts/layer2/based/IBlockHash.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; /// @title IBlockHash /// @notice Interface for retrieving block hashes. interface IBlockHash { /// @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); }
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); } } }
contracts/layer2/based/Lib1559Math.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import "@solady/src/utils/FixedPointMathLib.sol"; import "src/shared/common/LibMath.sol"; /// @title Lib1559Math /// @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 Lib1559Math { using LibMath for uint256; uint128 public constant MAX_EXP_INPUT = 135_305_999_368_893_231_588; error EIP1559_INVALID_PARAMS(); function calc1559BaseFee( uint256 _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(gasExcess_, _gasTarget); } /// @dev Returns the new gas excess that will keep the basefee the same. /// `_newGasTarget * ln(_newGasTarget / _target) + _gasExcess * _newGasTarget / _target` function adjustExcess( uint64 _gasExcess, uint64 _gasTarget, uint64 _newGasTarget ) internal pure returns (uint64) { if (_gasTarget == 0) { return _newGasTarget; } uint256 f = FixedPointMathLib.WAD; uint256 ratio = f * _newGasTarget / _gasTarget; if (ratio == 0 || ratio > uint256(type(int256).max)) revert EIP1559_INVALID_PARAMS(); 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(_gasExcess, 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 uint64(newGasExcess.min(type(uint64).max)); } /// @dev exp(_gasExcess / _gasTarget) / _gasTarget function basefee(uint256 _gasExcess, uint256 _gasTarget) internal pure returns (uint256) { uint256 fee = ethQty(_gasExcess, _gasTarget) / _gasTarget; return fee == 0 ? 1 : fee; } /// @dev exp(_gasExcess / _gasTarget) function ethQty(uint256 _gasExcess, uint256 _gasTarget) internal pure returns (uint256) { if (_gasTarget == 0) revert EIP1559_INVALID_PARAMS(); 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; /// @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/TaikoL2.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/data/LibSharedData.sol"; import "src/shared/common/EssentialContract.sol"; import "src/shared/common/LibStrings.sol"; import "src/shared/common/LibAddress.sol"; import "src/shared/signal/ISignalService.sol"; import "./Lib1559Math.sol"; import "./LibL2Config.sol"; import "./IBlockHash.sol"; /// @title TaikoL2 /// @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 TaikoL2 is EssentialContract, IBlockHash { using LibAddress for address; 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; /// @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; uint64 public parentTimestamp; 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); error L2_BASEFEE_MISMATCH(); error L2_FORK_ERROR(); error L2_INVALID_L1_CHAIN_ID(); error L2_INVALID_L2_CHAIN_ID(); error L2_INVALID_PARAM(); error L2_INVALID_SENDER(); error L2_PUBLIC_INPUT_HASH_MISMATCH(); error L2_TOO_LATE(); modifier onlyGoldenTouch() { if (msg.sender != GOLDEN_TOUCH_ADDRESS) revert L2_INVALID_SENDER(); _; } /// @notice Initializes the contract. /// @param _owner The owner of this contract. msg.sender will be used if this value is zero. /// @param _rollupAddressManager The address of the {AddressManager} contract. /// @param _l1ChainId The ID of the base layer. /// @param _initialGasExcess The initial parentGasExcess. function init( address _owner, address _rollupAddressManager, uint64 _l1ChainId, uint64 _initialGasExcess ) external initializer { __Essential_init(_owner, _rollupAddressManager); if (_l1ChainId == 0 || _l1ChainId == block.chainid) { revert L2_INVALID_L1_CHAIN_ID(); } if (block.chainid <= 1 || block.chainid > type(uint64).max) { revert 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 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 _l1StateRoot The state root for the L1 block with id equals `_anchorBlockId` /// @param _l1BlockId The `anchorBlockId` value in this block's metadata. /// @param _parentGasUsed The gas used in the parent block. function anchor( bytes32, /*_l1BlockHash*/ bytes32 _l1StateRoot, uint64 _l1BlockId, uint32 _parentGasUsed ) external nonZeroValue(uint256(_l1StateRoot)) nonZeroValue(uint256(_l1BlockId)) onlyGoldenTouch nonReentrant { if (block.number >= ontakeForkHeight()) revert L2_FORK_ERROR(); // Verify ancestor hashes uint256 parentId = block.number - 1; (bytes32 currentPublicInputHash, bytes32 newPublicInputHash) = _calcPublicInputHash(parentId); if (publicInputHash != currentPublicInputHash) revert L2_PUBLIC_INPUT_HASH_MISMATCH(); // Verify the base fee per gas is correct (uint256 basefee, uint64 newGasExcess) = getBasefee(_l1BlockId, _parentGasUsed); if (!skipFeeCheck() && block.basefee != basefee) revert L2_BASEFEE_MISMATCH(); if (_l1BlockId > lastSyncedBlock) { // Store the L1's state root as a signal to the local signal service to // allow for multi-hop bridging. ISignalService(resolve(LibStrings.B_SIGNAL_SERVICE, false)).syncChainData( l1ChainId, LibStrings.H_STATE_ROOT, _l1BlockId, _l1StateRoot ); lastSyncedBlock = _l1BlockId; } // Update state variables bytes32 parentHash = blockhash(parentId); _blockhashes[parentId] = parentHash; publicInputHash = newPublicInputHash; parentGasExcess = newGasExcess; parentTimestamp = uint64(block.timestamp); emit Anchored(parentHash, newGasExcess); } function anchorV2( uint64 _anchorBlockId, bytes32 _anchorStateRoot, uint32 _parentGasUsed, LibSharedData.BaseFeeConfig calldata _baseFeeConfig ) external nonZeroValue(uint256(_anchorStateRoot)) nonZeroValue(uint256(_anchorBlockId)) nonZeroValue(uint256(_baseFeeConfig.gasIssuancePerSecond)) nonZeroValue(uint256(_baseFeeConfig.adjustmentQuotient)) onlyGoldenTouch nonReentrant { if (block.number < ontakeForkHeight()) revert L2_FORK_ERROR(); uint256 parentId = block.number - 1; // Verify ancestor hashes { (bytes32 currentPublicInputHash, bytes32 newPublicInputHash) = _calcPublicInputHash(parentId); if (publicInputHash != currentPublicInputHash) revert L2_PUBLIC_INPUT_HASH_MISMATCH(); publicInputHash = newPublicInputHash; } // Check if the gas settings has changed { uint64 newGasTarget = uint64(_baseFeeConfig.gasIssuancePerSecond) * _baseFeeConfig.adjustmentQuotient; if (parentGasTarget != newGasTarget) { if (parentGasTarget != 0) { parentGasExcess = adjustExcess(parentGasExcess, parentGasTarget, newGasTarget); } parentGasTarget = newGasTarget; } } // Verify the base fee per gas is correct { (uint256 basefee, uint64 newGasExcess) = calculateBaseFee( _baseFeeConfig, uint64(block.timestamp - parentTimestamp), parentGasExcess, _parentGasUsed ); if (!skipFeeCheck() && block.basefee != basefee) revert L2_BASEFEE_MISMATCH(); parentGasExcess = newGasExcess; } if (_anchorBlockId > lastSyncedBlock) { // Store the L1's state root as a signal to the local signal service to // allow for multi-hop bridging. ISignalService(resolve(LibStrings.B_SIGNAL_SERVICE, false)).syncChainData( l1ChainId, LibStrings.H_STATE_ROOT, _anchorBlockId, _anchorStateRoot ); lastSyncedBlock = _anchorBlockId; } // Update state variables bytes32 parentHash = blockhash(parentId); _blockhashes[parentId] = parentHash; parentTimestamp = uint64(block.timestamp); emit Anchored(parentHash, parentGasExcess); } /// @notice Withdraw token or Ether from this address /// @param _token Token address or address(0) if Ether. /// @param _to Withdraw to address. function withdraw( address _token, address _to ) external whenNotPaused onlyFromOwnerOrNamed(LibStrings.B_WITHDRAWER) nonReentrant { if (_to == address(0)) revert L2_INVALID_PARAM(); if (_token == address(0)) { _to.sendEtherAndVerify(address(this).balance); } else { IERC20(_token).safeTransfer(_to, IERC20(_token).balanceOf(address(this))); } } /// @notice Gets the basefee and gas excess using EIP-1559 configuration for /// the given parameters. /// @dev This function will deprecate after Ontake fork, node/client shall use calculateBaseFee /// instead for base fee prediction. /// @param _anchorBlockId The synced L1 height in the next Taiko block /// @param _parentGasUsed Gas used in the parent block. /// @return basefee_ The calculated EIP-1559 base fee per gas. /// @return parentGasExcess_ The new parentGasExcess value. function getBasefee( uint64 _anchorBlockId, uint32 _parentGasUsed ) public view returns (uint256 basefee_, uint64 parentGasExcess_) { LibL2Config.Config memory config = getConfig(); (basefee_, parentGasExcess_) = Lib1559Math.calc1559BaseFee( uint256(config.gasTargetPerL1Block) * config.basefeeAdjustmentQuotient, parentGasExcess, uint64(_anchorBlockId - lastSyncedBlock) * config.gasTargetPerL1Block, _parentGasUsed, 0 ); } /// @inheritdoc IBlockHash 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 Returns EIP1559 related configurations. /// @return config_ struct containing configuration parameters. function getConfig() public view virtual returns (LibL2Config.Config memory) { return LibL2Config.get(); } /// @notice Returns the new gas excess that will keep the basefee the same. /// @param _currGasExcess The current gas excess value. /// @param _currGasTarget The current gas target. /// @param _newGasTarget The new gas target. /// @return newGasExcess_ The new gas excess value. function adjustExcess( uint64 _currGasExcess, uint64 _currGasTarget, uint64 _newGasTarget ) public pure returns (uint64 newGasExcess_) { return Lib1559Math.adjustExcess(_currGasExcess, _currGasTarget, _newGasTarget); } /// @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; } function ontakeForkHeight() public pure virtual returns (uint64) { return 0; } /// @notice Calculates the basefee and the new gas excess value based on parent gas used and gas /// excess. /// @param _baseFeeConfig The base fee config object. /// @param _blocktime The time between this block and the parent block. /// @param _parentGasExcess The current gas excess value. /// @param _parentGasUsed Total gas used by the parent block. /// @return basefee_ Next block's base fee. /// @return parentGasExcess_ The new gas excess value. function calculateBaseFee( LibSharedData.BaseFeeConfig calldata _baseFeeConfig, uint64 _blocktime, uint64 _parentGasExcess, uint32 _parentGasUsed ) public pure returns (uint256 basefee_, uint64 parentGasExcess_) { uint64 gasIssuance = _blocktime * _baseFeeConfig.gasIssuancePerSecond; if ( _baseFeeConfig.maxGasIssuancePerBlock != 0 && gasIssuance > _baseFeeConfig.maxGasIssuancePerBlock ) { gasIssuance = _baseFeeConfig.maxGasIssuancePerBlock; } uint256 gasTarget = uint256(_baseFeeConfig.gasIssuancePerSecond) * _baseFeeConfig.adjustmentQuotient; return Lib1559Math.calc1559BaseFee( gasTarget, _parentGasExcess, gasIssuance, _parentGasUsed, _baseFeeConfig.minGasExcess ); } function _calcPublicInputHash(uint256 _blockId) private view returns (bytes32 publicInputHashOld, bytes32 publicInputHashNew) { bytes32[256] memory inputs; // 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); } } inputs[255] = bytes32(block.chainid); assembly { publicInputHashOld := keccak256(inputs, 8192 /*mul(256, 32)*/ ) } inputs[_blockId % 255] = blockhash(_blockId); assembly { publicInputHashNew := keccak256(inputs, 8192 /*mul(256, 32)*/ ) } } }
contracts/shared/common/AddressResolver.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./IAddressManager.sol"; import "./IAddressResolver.sol"; /// @title AddressResolver /// @notice See the documentation in {IAddressResolver}. /// @custom:security-contact security@taiko.xyz abstract contract AddressResolver is IAddressResolver, Initializable { /// @notice Address of the AddressManager. address public addressManager; uint256[49] private __gap; error RESOLVER_DENIED(); error RESOLVER_INVALID_MANAGER(); error RESOLVER_UNEXPECTED_CHAINID(); error RESOLVER_ZERO_ADDR(uint64 chainId, bytes32 name); /// @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) { if (msg.sender != resolve(_name, true)) revert RESOLVER_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); if (addr != address(0) && msg.sender != addr) revert RESOLVER_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) { if (msg.sender != resolve(_name1, true) && msg.sender != resolve(_name2, true)) { revert RESOLVER_DENIED(); } _; } /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } /// @inheritdoc IAddressResolver function resolve(bytes32 _name, bool _allowZeroAddress) public view virtual returns (address) { return _resolve(uint64(block.chainid), _name, _allowZeroAddress); } /// @inheritdoc IAddressResolver function resolve( uint64 _chainId, bytes32 _name, bool _allowZeroAddress ) public view virtual returns (address) { return _resolve(_chainId, _name, _allowZeroAddress); } /// @dev Initialization method for setting up AddressManager reference. /// @param _addressManager Address of the AddressManager. function __AddressResolver_init(address _addressManager) internal virtual onlyInitializing { if (block.chainid > type(uint64).max) { revert RESOLVER_UNEXPECTED_CHAINID(); } addressManager = _addressManager; } /// @dev Helper method to resolve name-to-address. /// @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 addr_ Address associated with the given name on the specified /// chain. function _resolve( uint64 _chainId, bytes32 _name, bool _allowZeroAddress ) internal view returns (address addr_) { addr_ = _getAddress(_chainId, _name); if (!_allowZeroAddress && addr_ == address(0)) { revert RESOLVER_ZERO_ADDR(_chainId, _name); } } function _getAddress(uint64 _chainId, bytes32 _name) internal view virtual returns (address) { address _addressManager = addressManager; if (_addressManager == address(0)) revert RESOLVER_INVALID_MANAGER(); return IAddressManager(_addressManager).getAddress(_chainId, _name); } }
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 "./AddressResolver.sol"; /// @title EssentialContract /// @custom:security-contact security@taiko.xyz abstract contract EssentialContract is UUPSUpgradeable, Ownable2StepUpgradeable, AddressResolver { uint8 private constant _FALSE = 1; uint8 private constant _TRUE = 2; /// @dev Slot 1. uint8 private __reentry; uint8 private __paused; uint64 public lastUnpausedAt; 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 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) { if (msg.sender != owner() && msg.sender != resolve(_name, true)) revert RESOLVER_DENIED(); _; } modifier notImplemented() { revert FUNC_NOT_IMPLEMENTED(); _; } modifier nonReentrant() { if (_loadReentryLock() == _TRUE) revert REENTRANT_CALL(); _storeReentryLock(_TRUE); _; _storeReentryLock(_FALSE); } modifier whenPaused() { if (!paused()) revert INVALID_PAUSE_STATUS(); _; } modifier whenNotPaused() { if (paused()) revert INVALID_PAUSE_STATUS(); _; } modifier nonZeroAddr(address _addr) { if (_addr == address(0)) revert ZERO_ADDRESS(); _; } modifier nonZeroValue(uint256 _value) { if (_value == 0) revert ZERO_VALUE(); _; } /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } /// @notice Pauses the contract. function pause() public virtual { _pause(); // We call the authorize function here to avoid: // Warning (5740): Unreachable code. _authorizePause(msg.sender, true); } /// @notice Unpauses the contract. function unpause() public virtual { _unpause(); // 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 returns (bool) { return __paused == _TRUE; } function inNonReentrant() public view returns (bool) { return _loadReentryLock() == _TRUE; } /// @notice Initializes the contract. /// @param _owner The owner of this contract. msg.sender will be used if this value is zero. /// @param _addressManager The address of the {AddressManager} contract. function __Essential_init( address _owner, address _addressManager ) internal nonZeroAddr(_addressManager) { __Essential_init(_owner); __AddressResolver_init(_addressManager); } function __Essential_init(address _owner) internal virtual onlyInitializing { __Context_init(); _transferOwnership(_owner == address(0) ? msg.sender : _owner); __paused = _FALSE; } function _pause() internal whenNotPaused { __paused = _TRUE; emit Paused(msg.sender); } function _unpause() internal whenPaused { __paused = _FALSE; lastUnpausedAt = uint64(block.timestamp); emit Unpaused(msg.sender); } 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/IAddressManager.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; /// @title IAddressManager /// @notice Manages a mapping of (chainId, name) pairs to Ethereum addresses. /// @custom:security-contact security@taiko.xyz interface IAddressManager { /// @notice Gets the address mapped to a specific chainId-name pair. /// @dev Note that in production, this method shall be a pure function /// without any storage access. /// @param _chainId The chainId for which the address needs to be fetched. /// @param _name The name for which the address needs to be fetched. /// @return Address associated with the chainId-name pair. function getAddress(uint64 _chainId, bytes32 _name) external view returns (address); }
contracts/shared/common/IAddressResolver.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; /// @title IAddressResolver /// @notice This contract acts as a bridge for name-to-address resolution. /// It delegates the resolution to the AddressManager. By separating the logic, /// we can maintain flexibility in address management without affecting the /// resolving process. /// @dev Note that the address manager should be changed using upgradability, there /// is no setAddressManager() function to guarantee atomicity across all /// contracts that are resolvers. /// @custom:security-contact security@taiko.xyz interface IAddressResolver { /// @notice Resolves a name to its address deployed on this chain. /// @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. function resolve(bytes32 _name, bool _allowZeroAddress) external view returns (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( uint64 _chainId, bytes32 _name, bool _allowZeroAddress ) external view returns (address); }
contracts/shared/common/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 if (_to == address(0)) revert 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; if (!sendEther(_to, _amount, _gasLimit, "")) { revert 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/common/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; } }
contracts/shared/common/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_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_PRECONF_REGISTRY = bytes32("preconf_registry"); bytes32 internal constant B_PROVER_ASSIGNMENT = bytes32("PROVER_ASSIGNMENT"); 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_SP1_REMOTE_VERIFIER = bytes32("sp1_remote_verifier"); bytes32 internal constant B_TAIKO = bytes32("taiko"); bytes32 internal constant B_TAIKO_TOKEN = bytes32("taiko_token"); bytes32 internal constant B_TIER_GUARDIAN = bytes32("tier_guardian"); bytes32 internal constant B_TIER_GUARDIAN_MINORITY = bytes32("tier_guardian_minority"); bytes32 internal constant B_TIER_ROUTER = bytes32("tier_router"); bytes32 internal constant B_TIER_SGX = bytes32("tier_sgx"); bytes32 internal constant B_TIER_TDX = bytes32("tier_tdx"); bytes32 internal constant B_TIER_TEE_ANY = bytes32("tier_tee_any"); bytes32 internal constant B_TIER_ZKVM_RISC0 = bytes32("tier_zkvm_risc0"); bytes32 internal constant B_TIER_ZKVM_SP1 = bytes32("tier_zkvm_sp1"); bytes32 internal constant B_TIER_ZKVM_ANY = bytes32("tier_zkvm_any"); bytes32 internal constant B_TIER_ZKVM_AND_TEE = bytes32("tier_zkvm_and_tee"); bytes32 internal constant B_RISCZERO_GROTH16_VERIFIER = bytes32("risc0_groth16_verifier"); bytes32 internal constant B_WITHDRAWER = bytes32("withdrawer"); bytes32 internal constant H_RETURN_LIVENESS_BOND = keccak256("RETURN_LIVENESS_BOND"); bytes32 internal constant H_SIGNAL_ROOT = keccak256("SIGNAL_ROOT"); bytes32 internal constant H_STATE_ROOT = keccak256("STATE_ROOT"); }
contracts/shared/data/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/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 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); /// @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. /// @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. 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 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/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/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/","openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/","@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/","openzeppelin/contracts/=node_modules/@openzeppelin/contracts/","@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/","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","evm.deployedBytecode","evm.methodIdentifiers","metadata"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"shanghai"}
Contract ABI
[{"type":"error","name":"EIP1559_INVALID_PARAMS","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_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_PARAM","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_DENIED","inputs":[]},{"type":"error","name":"RESOLVER_INVALID_MANAGER","inputs":[]},{"type":"error","name":"RESOLVER_UNEXPECTED_CHAINID","inputs":[]},{"type":"error","name":"RESOLVER_ZERO_ADDR","inputs":[{"type":"uint64","name":"chainId","internalType":"uint64"},{"type":"bytes32","name":"name","internalType":"bytes32"}]},{"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":"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":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"addressManager","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":"","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":"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":"view","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":"bytes32","name":"","internalType":"bytes32"}],"name":"getBlockHash","inputs":[{"type":"uint256","name":"_blockId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct LibL2Config.Config","components":[{"type":"uint32","name":"gasTargetPerL1Block","internalType":"uint32"},{"type":"uint8","name":"basefeeAdjustmentQuotient","internalType":"uint8"}]}],"name":"getConfig","inputs":[]},{"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":"address","name":"_rollupAddressManager","internalType":"address"},{"type":"uint64","name":"_l1ChainId","internalType":"uint64"},{"type":"uint64","name":"_initialGasExcess","internalType":"uint64"}]},{"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":"uint64","name":"","internalType":"uint64"}],"name":"lastUnpausedAt","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"ontakeForkHeight","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":"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":"resolve","inputs":[{"type":"uint64","name":"_chainId","internalType":"uint64"},{"type":"bytes32","name":"_name","internalType":"bytes32"},{"type":"bool","name":"_allowZeroAddress","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"resolve","inputs":[{"type":"bytes32","name":"_name","internalType":"bytes32"},{"type":"bool","name":"_allowZeroAddress","internalType":"bool"}]},{"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
0x60a060405230608052348015610013575f5ffd5b5061001c610029565b610024610029565b6100e5565b5f54610100900460ff16156100945760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff908116146100e3575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051612ef86101195f395f81816106a0015281816106e901528181610790015281816107d0015261084b0152612ef85ff3fe6080604052600436106101fc575f3560e01c80638456cb5911610113578063da69d3db1161009d578063e902461a1161006d578063e902461a146105cd578063ee82ac5e146105ec578063f2fde38b1461060b578063f940e3851461062a578063fd85eb2d14610649575f5ffd5b8063da69d3db14610557578063dac5df7814610576578063e07baba61461058b578063e30c3978146105b0575f5ffd5b8063a7137c0f116100e3578063a7137c0f1461047f578063a7e022d1146104a5578063a86f9d9e146104e1578063b8c7b30c14610500578063c3f909d41461051f575f5ffd5b80638456cb59146104155780638abf6077146104295780638da5cb5b1461043d5780639ee512f21461045a575f5ffd5b80633eb6b8cf11610194578063539b8ade11610164578063539b8ade146103885780635950f9f1146103ae5780635c975abb146103cd578063715018a6146103ed57806379ba509714610401575f5ffd5b80633eb6b8cf146103205780633f4ba83a1461033f5780634f1ef2861461035357806352d1902d14610366575f5ffd5b806333d5ac9b116101cf57806333d5ac9b1461028d578063356aec04146102b35780633659cfe6146102c85780633ab76e9f146102e9575f5ffd5b806312622e5b14610200578063136dc4a81461023c5780632f9804731461025b5780633075db5614610279575b5f5ffd5b34801561020b575f5ffd5b5060fe5461021f906001600160401b031681565b6040516001600160401b0390911681526020015b60405180910390f35b348015610247575f5ffd5b5061021f610256366004612838565b610668565b348015610266575f5ffd5b505f5b6040519015158152602001610233565b348015610284575f5ffd5b5061026961067e565b348015610298575f5ffd5b5060fd5461021f90600160401b90046001600160401b031681565b3480156102be575f5ffd5b50620cd34061021f565b3480156102d3575f5ffd5b506102e76102e236600461288c565b610696565b005b3480156102f4575f5ffd5b50609754610308906001600160a01b031681565b6040516001600160a01b039091168152602001610233565b34801561032b575f5ffd5b5061030861033a3660046128b4565b610766565b34801561034a575f5ffd5b506102e7610772565b6102e7610361366004612905565b610786565b348015610371575f5ffd5b5061037a61083f565b604051908152602001610233565b348015610393575f5ffd5b5060fd5461021f90600160801b90046001600160401b031681565b3480156103b9575f5ffd5b506102e76103c83660046129c8565b6108f0565b3480156103d8575f5ffd5b5061026960c954610100900460ff1660021490565b3480156103f8575f5ffd5b506102e7610af9565b34801561040c575f5ffd5b506102e7610b0a565b348015610420575f5ffd5b506102e7610b81565b348015610434575f5ffd5b50610308610b94565b348015610448575f5ffd5b506033546001600160a01b0316610308565b348015610465575f5ffd5b5061030871777735367b36bc9b61c50022d9d0700db4ec81565b34801561048a575f5ffd5b5060fd5461021f90600160c01b90046001600160401b031681565b3480156104b0575f5ffd5b506104c46104bf366004612a30565b610ba2565b604080519283526001600160401b03909116602083015201610233565b3480156104ec575f5ffd5b506103086104fb366004612a61565b610c18565b34801561050b575f5ffd5b5060fd5461021f906001600160401b031681565b34801561052a575f5ffd5b50610533610c2d565b60408051825163ffffffff16815260209283015160ff169281019290925201610233565b348015610562575f5ffd5b506102e7610571366004612a8f565b610c5e565b348015610581575f5ffd5b5061037a60fc5481565b348015610596575f5ffd5b5060c95461021f906201000090046001600160401b031681565b3480156105bb575f5ffd5b506065546001600160a01b0316610308565b3480156105d8575f5ffd5b506104c46105e7366004612ad7565b610f7b565b3480156105f7575f5ffd5b5061037a610606366004612b1f565b61105d565b348015610616575f5ffd5b506102e761062536600461288c565b611095565b348015610635575f5ffd5b506102e7610644366004612b36565b611106565b348015610654575f5ffd5b506102e7610663366004612b62565b6112c5565b5f61067484848461174e565b90505b9392505050565b5f600261068d60c95460ff1690565b60ff1614905090565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036106e75760405162461bcd60e51b81526004016106de90612ba3565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610719611812565b6001600160a01b03161461073f5760405162461bcd60e51b81526004016106de90612bef565b6107488161182d565b604080515f8082526020820190925261076391839190611835565b50565b5f61067484848461199f565b61077a6119f1565b610784335f611a81565b565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036107ce5760405162461bcd60e51b81526004016106de90612ba3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610800611812565b6001600160a01b0316146108265760405162461bcd60e51b81526004016106de90612bef565b61082f8261182d565b61083b82826001611835565b5050565b5f306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108de5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016106de565b505f516020612e7c5f395f51905f5290565b5f54610100900460ff161580801561090e57505f54600160ff909116105b806109275750303b15801561092757505f5460ff166001145b61098a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106de565b5f805460ff1916600117905580156109ab575f805461ff0019166101001790555b6109b58585611a89565b6001600160401b03831615806109d3575046836001600160401b0316145b156109f1576040516308279a2560e31b815260040160405180910390fd5b600146111580610a0757506001600160401b0346115b15610a2557604051638f972ecb60e01b815260040160405180910390fd5b4315610a6f5743600103610a56575f610a3f600143612c4f565b5f81815260fb602052604090209040905550610a6f565b604051635a0f9e4160e11b815260040160405180910390fd5b60fe80546001600160401b0380861667ffffffffffffffff199283161790925560fd805492851692909116919091179055610aa943611ac3565b5060fc558015610af2575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b610b01611b53565b6107845f611bad565b60655433906001600160a01b03168114610b785760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016106de565b61076381611bad565b610b89611bc6565b610784336001611a81565b5f610b9d611812565b905090565b5f5f5f610bad610c2d565b9050610c0c816020015160ff16825f015163ffffffff16610bce9190612c62565b60fd5483516001600160401b038083169263ffffffff90921691610bfb91600160401b909104168a612c79565b610c059190612c98565b875f611c37565b90969095509350505050565b5f610c2446848461199f565b90505b92915050565b604080518082019091525f8082526020820152610b9d60408051808201909152630393870081526008602082015290565b825f819003610c805760405163ec73295960e01b815260040160405180910390fd5b826001600160401b0316805f03610caa5760405163ec73295960e01b815260040160405180910390fd5b3371777735367b36bc9b61c50022d9d0700db4ec14610cdc57604051636494e9f760e01b815260040160405180910390fd5b6002610cea60c95460ff1690565b60ff1603610d0b5760405163dfc60d8560e01b815260040160405180910390fd5b610d156002611cc0565b620cd3404310610d3857604051631799c89b60e01b815260040160405180910390fd5b5f610d44600143612c4f565b90505f5f610d5183611ac3565b915091508160fc5414610d775760405163d719258d60e01b815260040160405180910390fd5b5f5f610d838989610ba2565b91509150610d8e5f90565b158015610d9b5750814814155b15610db9576040516336d54d4f60e11b815260040160405180910390fd5b60fd546001600160401b03600160401b9091048116908a161115610ec457610df26d7369676e616c5f7365727669636560901b5f610c18565b60fe546040516313e4299d60e21b81526001600160401b0391821660048201527f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da1696024820152908b166044820152606481018c90526001600160a01b039190911690634f90a674906084016020604051808303815f875af1158015610e79573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e9d9190612cc1565b5060fd805467ffffffffffffffff60401b1916600160401b6001600160401b038c16021790555b5f85815260fb60205260409081902086409081905560fc85905560fd8054426001600160401b03908116600160801b0277ffffffffffffffff0000000000000000ffffffffffffffff199092169086161717905590517f41c3f410f5c8ac36bb46b1dccef0de0f964087c9e688795fa02ecfa2c20b3fe490610f5b90839085909182526001600160401b0316602082015260400190565b60405180910390a1505050505050610f736001611cc0565b505050505050565b5f8080610f8e6060880160408901612cd8565b610f9e9063ffffffff1687612c98565b9050610fb060a0880160808901612cd8565b63ffffffff1615801590610fe15750610fcf60a0880160808901612cd8565b63ffffffff16816001600160401b0316115b15610fff57610ff660a0880160808901612cd8565b63ffffffff1690505b5f61100d6020890189612cf1565b60ff1661102060608a0160408b01612cd8565b63ffffffff166110309190612c62565b905061104e8187848861104960808e0160608f01612d11565b611c37565b93509350505094509492505050565b5f43821061106c57505f919050565b4361107983610100612d2a565b1061108357504090565b505f90815260fb602052604090205490565b61109d611b53565b606580546001600160a01b0383166001600160a01b031990911681179091556110ce6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b61111a60c954610100900460ff1660021490565b156111385760405163bae6e2a960e01b815260040160405180910390fd5b693bb4ba34323930bbb2b960b11b6111586033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614158015611195575061117f816001610c18565b6001600160a01b0316336001600160a01b031614155b156111b357604051630d85cccf60e11b815260040160405180910390fd5b60026111c160c95460ff1690565b60ff16036111e25760405163dfc60d8560e01b815260040160405180910390fd5b6111ec6002611cc0565b6001600160a01b0382166112135760405163053fd54760e01b815260040160405180910390fd5b6001600160a01b038316611239576112346001600160a01b03831647611cd6565b6112b6565b6040516370a0823160e01b81523060048201526112b69083906001600160a01b038616906370a0823190602401602060405180830381865afa158015611281573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112a59190612cc1565b6001600160a01b0386169190611ce1565b6112c06001611cc0565b505050565b825f8190036112e75760405163ec73295960e01b815260040160405180910390fd5b846001600160401b0316805f036113115760405163ec73295960e01b815260040160405180910390fd5b6113216060840160408501612cd8565b63ffffffff16805f036113475760405163ec73295960e01b815260040160405180910390fd5b6113546020850185612cf1565b60ff16805f036113775760405163ec73295960e01b815260040160405180910390fd5b3371777735367b36bc9b61c50022d9d0700db4ec146113a957604051636494e9f760e01b815260040160405180910390fd5b60026113b760c95460ff1690565b60ff16036113d85760405163dfc60d8560e01b815260040160405180910390fd5b6113e26002611cc0565b620cd34043101561140657604051631799c89b60e01b815260040160405180910390fd5b5f611412600143612c4f565b90505f5f61141f83611ac3565b915091508160fc54146114455760405163d719258d60e01b815260040160405180910390fd5b60fc55505f6114576020880188612cf1565b60ff1661146a6060890160408a01612cd8565b63ffffffff1661147a9190612c98565b60fd549091506001600160401b03808316600160c01b90920416146115155760fd54600160c01b90046001600160401b0316156114f45760fd546114d2906001600160401b0380821691600160c01b90041683610668565b60fd805467ffffffffffffffff19166001600160401b03929092169190911790555b60fd80546001600160c01b0316600160c01b6001600160401b038416021790555b5060fd545f90819061154f90899061153d90600160801b90046001600160401b031642612c4f565b60fd546001600160401b03168c610f7b565b9150915061155a5f90565b1580156115675750814814155b15611585576040516336d54d4f60e11b815260040160405180910390fd5b60fd805467ffffffffffffffff19166001600160401b039283161790819055600160401b90048116908b16111590506116a5576115d36d7369676e616c5f7365727669636560901b5f610c18565b60fe546040516313e4299d60e21b81526001600160401b0391821660048201527f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da1696024820152908b166044820152606481018a90526001600160a01b039190911690634f90a674906084016020604051808303815f875af115801561165a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061167e9190612cc1565b5060fd805467ffffffffffffffff60401b1916600160401b6001600160401b038c16021790555b5f81815260fb60205260409081902082409081905560fd80546001600160401b03428116600160801b0267ffffffffffffffff60801b1983168117909355935192937f41c3f410f5c8ac36bb46b1dccef0de0f964087c9e688795fa02ecfa2c20b3fe493611730938693908316921691909117909182526001600160401b0316602082015260400190565b60405180910390a150506117446001611cc0565b5050505050505050565b5f826001600160401b03165f03611766575080610677565b670de0b6b3a76400005f6001600160401b038086169061178890861684612c62565b6117929190612d51565b90508015806117a757506001600160ff1b0381115b156117c557604051636296f1b960e11b815260040160405180910390fd5b5f6117cf82611d33565b90505f828802828702015f8112600181146117ee5785820492506117f2565b5f92505b506118069050816001600160401b03611f50565b98975050505050505050565b5f516020612e7c5f395f51905f52546001600160a01b031690565b610763611b53565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611868576112c083611f64565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156118c2575060408051601f3d908101601f191682019092526118bf91810190612cc1565b60015b6119255760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016106de565b5f516020612e7c5f395f51905f5281146119935760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016106de565b506112c0838383611fff565b5f6119aa8484612029565b9050811580156119c157506001600160a01b038116155b1561067757604051632b0d65db60e01b81526001600160401b0385166004820152602481018490526044016106de565b611a0560c954610100900460ff1660021490565b611a225760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461010069ffffffffffffffffff001990911662010000426001600160401b031602171790556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b61083b611b53565b806001600160a01b038116611ab15760405163538ba4f960e01b815260040160405180910390fd5b611aba836120d3565b6112c082612131565b5f5f611acd6127fd565b5f5b60ff81108015611ae25750806001018510155b15611b13575f198186030180408360ff83066101008110611b0557611b05612d64565b602002015250600101611acf565b5046611fe082015261200081209250834081611b3060ff87612d78565b6101008110611b4157611b41612d64565b60200201526120009020919391925050565b6033546001600160a01b031633146107845760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106de565b606580546001600160a01b0319169055610763816121a1565b611bda60c954610100900460ff1660021490565b15611bf85760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001611a77565b5f8080611c5363ffffffff86166001600160401b038916612d2a565b9050856001600160401b03168111611c6c576001611c7f565b611c7f6001600160401b03871682612c4f565b9050611c9e6001600160401b03611c98838783166121f2565b90611f50565b9150611cb3826001600160401b031689612207565b9250509550959350505050565b60c9805460ff191660ff92909216919091179055565b61083b82825a612236565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526112c0908490612279565b6fffffffffffffffffffffffffffffffff811160071b81811c6001600160401b031060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b175f8213611d8f57631615e6385f526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd1901909102780a09507084cc699bb0e71ea869ffffffffffffffffffffffff190105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b5f818311611f5e5782610c24565b50919050565b6001600160a01b0381163b611fd15760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016106de565b5f516020612e7c5f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b6120088361234c565b5f825111806120145750805b156112c057612023838361238b565b50505050565b6097545f906001600160a01b03168061205557604051638ed88b2560e01b815260040160405180910390fd5b604051630a3dc4f360e21b81526001600160401b0385166004820152602481018490526001600160a01b038216906328f713cc90604401602060405180830381865afa1580156120a7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120cb9190612d8b565b949350505050565b5f54610100900460ff166120f95760405162461bcd60e51b81526004016106de90612da6565b6121016123b0565b61211f6001600160a01b038216156121195781611bad565b33611bad565b5060c9805461ff001916610100179055565b5f54610100900460ff166121575760405162461bcd60e51b81526004016106de90612da6565b6001600160401b0346111561217f5760405163a12e8fa960e01b815260040160405180910390fd5b609780546001600160a01b0319166001600160a01b0392909216919091179055565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f8183116122005781610c24565b5090919050565b5f5f8261221485856123d6565b61221e9190612d51565b9050801561222c57806120cb565b5060019392505050565b815f0361224257505050565b61225c83838360405180602001604052805f815250612450565b6112c057604051634c67134d60e11b815260040160405180910390fd5b5f6122cd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661248d9092919063ffffffff16565b905080515f14806122ed5750808060200190518101906122ed9190612df1565b6112c05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016106de565b61235581611f64565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b6060610c248383604051806060016040528060278152602001612e9c6027913961249b565b5f54610100900460ff166107845760405162461bcd60e51b81526004016106de90612da6565b5f815f036123f757604051636296f1b960e11b815260040160405180910390fd5b5f8261240b85670de0b6b3a7640000612c62565b6124159190612d51565b9050680755bf798b4a1bf1e48111156124345750680755bf798b4a1bf1e45b670de0b6b3a76400006124468261250f565b6120cb9190612d51565b5f6001600160a01b03851661247857604051634c67134d60e11b815260040160405180910390fd5b5f5f835160208501878988f195945050505050565b606061067484845f85612689565b60605f5f856001600160a01b0316856040516124b79190612e2e565b5f60405180830381855af49150503d805f81146124ef576040519150601f19603f3d011682016040523d82523d5f602084013e6124f4565b606091505b509150915061250586838387612760565b9695505050505050565b5f68023f2fa8f6da5b9d2819821361252657919050565b680755bf798b4a1bf1e582126125435763a37bfec95f526004601cfd5b6503782dace9d9604e83901b0591505f60606bb17217f7d1cf79abc9e3b39884821b056001605f1b01901d6bb17217f7d1cf79abc9e3b39881029093036c240c330e9fb2d9cbaf0fd5aafb1981018102606090811d6d0277594991cfc85f6e2461837cd9018202811d6d1a521255e34f6a5061b25ef1c9c319018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d6e02c72388d9f74f51a9331fed693f1419018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084016d01d3967ed30fc4f89c02bab5708119010290911d6e0587f503bb6ea29d25fcb740196450019091026d360d7aeea093263ecc6e0ecb291760621b010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6060824710156126ea5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016106de565b5f5f866001600160a01b031685876040516127059190612e2e565b5f6040518083038185875af1925050503d805f811461273f576040519150601f19603f3d011682016040523d82523d5f602084013e612744565b606091505b509150915061275587838387612760565b979650505050505050565b606083156127ce5782515f036127c7576001600160a01b0385163b6127c75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106de565b50816120cb565b6120cb83838151156127e35781518083602001fd5b8060405162461bcd60e51b81526004016106de9190612e49565b604051806120000160405280610100906020820280368337509192915050565b80356001600160401b0381168114612833575f5ffd5b919050565b5f5f5f6060848603121561284a575f5ffd5b6128538461281d565b92506128616020850161281d565b915061286f6040850161281d565b90509250925092565b6001600160a01b0381168114610763575f5ffd5b5f6020828403121561289c575f5ffd5b813561067781612878565b8015158114610763575f5ffd5b5f5f5f606084860312156128c6575f5ffd5b6128cf8461281d565b92506020840135915060408401356128e6816128a7565b809150509250925092565b634e487b7160e01b5f52604160045260245ffd5b5f5f60408385031215612916575f5ffd5b823561292181612878565b915060208301356001600160401b0381111561293b575f5ffd5b8301601f8101851361294b575f5ffd5b80356001600160401b03811115612964576129646128f1565b604051601f8201601f19908116603f011681016001600160401b0381118282101715612992576129926128f1565b6040528181528282016020018710156129a9575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f5f5f5f608085870312156129db575f5ffd5b84356129e681612878565b935060208501356129f681612878565b9250612a046040860161281d565b9150612a126060860161281d565b905092959194509250565b803563ffffffff81168114612833575f5ffd5b5f5f60408385031215612a41575f5ffd5b612a4a8361281d565b9150612a5860208401612a1d565b90509250929050565b5f5f60408385031215612a72575f5ffd5b823591506020830135612a84816128a7565b809150509250929050565b5f5f5f5f60808587031215612aa2575f5ffd5b8435935060208501359250612ab96040860161281d565b9150612a1260608601612a1d565b5f60a08284031215611f5e575f5ffd5b5f5f5f5f6101008587031215612aeb575f5ffd5b612af58686612ac7565b9350612b0360a0860161281d565b9250612b1160c0860161281d565b9150612a1260e08601612a1d565b5f60208284031215612b2f575f5ffd5b5035919050565b5f5f60408385031215612b47575f5ffd5b8235612b5281612878565b91506020830135612a8481612878565b5f5f5f5f6101008587031215612b76575f5ffd5b612b7f8561281d565b935060208501359250612b9460408601612a1d565b9150612a128660608701612ac7565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610c2757610c27612c3b565b8082028115828204841417610c2757610c27612c3b565b6001600160401b038281168282160390811115610c2757610c27612c3b565b6001600160401b038181168382160290811690818114612cba57612cba612c3b565b5092915050565b5f60208284031215612cd1575f5ffd5b5051919050565b5f60208284031215612ce8575f5ffd5b610c2482612a1d565b5f60208284031215612d01575f5ffd5b813560ff81168114610677575f5ffd5b5f60208284031215612d21575f5ffd5b610c248261281d565b80820180821115610c2757610c27612c3b565b634e487b7160e01b5f52601260045260245ffd5b5f82612d5f57612d5f612d3d565b500490565b634e487b7160e01b5f52603260045260245ffd5b5f82612d8657612d86612d3d565b500690565b5f60208284031215612d9b575f5ffd5b815161067781612878565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b5f60208284031215612e01575f5ffd5b8151610677816128a7565b5f5b83811015612e26578181015183820152602001612e0e565b50505f910152565b5f8251612e3f818460208701612e0c565b9190910192915050565b602081525f8251806020840152612e67816040850160208701612e0c565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212207dcc14406ad6bb9af012ee74a455a42f3f2d8bfc77c9b7eed1da1bc3075314ce64736f6c634300081b0033
Deployed ByteCode
0x6080604052600436106101fc575f3560e01c80638456cb5911610113578063da69d3db1161009d578063e902461a1161006d578063e902461a146105cd578063ee82ac5e146105ec578063f2fde38b1461060b578063f940e3851461062a578063fd85eb2d14610649575f5ffd5b8063da69d3db14610557578063dac5df7814610576578063e07baba61461058b578063e30c3978146105b0575f5ffd5b8063a7137c0f116100e3578063a7137c0f1461047f578063a7e022d1146104a5578063a86f9d9e146104e1578063b8c7b30c14610500578063c3f909d41461051f575f5ffd5b80638456cb59146104155780638abf6077146104295780638da5cb5b1461043d5780639ee512f21461045a575f5ffd5b80633eb6b8cf11610194578063539b8ade11610164578063539b8ade146103885780635950f9f1146103ae5780635c975abb146103cd578063715018a6146103ed57806379ba509714610401575f5ffd5b80633eb6b8cf146103205780633f4ba83a1461033f5780634f1ef2861461035357806352d1902d14610366575f5ffd5b806333d5ac9b116101cf57806333d5ac9b1461028d578063356aec04146102b35780633659cfe6146102c85780633ab76e9f146102e9575f5ffd5b806312622e5b14610200578063136dc4a81461023c5780632f9804731461025b5780633075db5614610279575b5f5ffd5b34801561020b575f5ffd5b5060fe5461021f906001600160401b031681565b6040516001600160401b0390911681526020015b60405180910390f35b348015610247575f5ffd5b5061021f610256366004612838565b610668565b348015610266575f5ffd5b505f5b6040519015158152602001610233565b348015610284575f5ffd5b5061026961067e565b348015610298575f5ffd5b5060fd5461021f90600160401b90046001600160401b031681565b3480156102be575f5ffd5b50620cd34061021f565b3480156102d3575f5ffd5b506102e76102e236600461288c565b610696565b005b3480156102f4575f5ffd5b50609754610308906001600160a01b031681565b6040516001600160a01b039091168152602001610233565b34801561032b575f5ffd5b5061030861033a3660046128b4565b610766565b34801561034a575f5ffd5b506102e7610772565b6102e7610361366004612905565b610786565b348015610371575f5ffd5b5061037a61083f565b604051908152602001610233565b348015610393575f5ffd5b5060fd5461021f90600160801b90046001600160401b031681565b3480156103b9575f5ffd5b506102e76103c83660046129c8565b6108f0565b3480156103d8575f5ffd5b5061026960c954610100900460ff1660021490565b3480156103f8575f5ffd5b506102e7610af9565b34801561040c575f5ffd5b506102e7610b0a565b348015610420575f5ffd5b506102e7610b81565b348015610434575f5ffd5b50610308610b94565b348015610448575f5ffd5b506033546001600160a01b0316610308565b348015610465575f5ffd5b5061030871777735367b36bc9b61c50022d9d0700db4ec81565b34801561048a575f5ffd5b5060fd5461021f90600160c01b90046001600160401b031681565b3480156104b0575f5ffd5b506104c46104bf366004612a30565b610ba2565b604080519283526001600160401b03909116602083015201610233565b3480156104ec575f5ffd5b506103086104fb366004612a61565b610c18565b34801561050b575f5ffd5b5060fd5461021f906001600160401b031681565b34801561052a575f5ffd5b50610533610c2d565b60408051825163ffffffff16815260209283015160ff169281019290925201610233565b348015610562575f5ffd5b506102e7610571366004612a8f565b610c5e565b348015610581575f5ffd5b5061037a60fc5481565b348015610596575f5ffd5b5060c95461021f906201000090046001600160401b031681565b3480156105bb575f5ffd5b506065546001600160a01b0316610308565b3480156105d8575f5ffd5b506104c46105e7366004612ad7565b610f7b565b3480156105f7575f5ffd5b5061037a610606366004612b1f565b61105d565b348015610616575f5ffd5b506102e761062536600461288c565b611095565b348015610635575f5ffd5b506102e7610644366004612b36565b611106565b348015610654575f5ffd5b506102e7610663366004612b62565b6112c5565b5f61067484848461174e565b90505b9392505050565b5f600261068d60c95460ff1690565b60ff1614905090565b6001600160a01b037f000000000000000000000000637b1e6e71007d033b5d4385179037c90665a2031630036106e75760405162461bcd60e51b81526004016106de90612ba3565b60405180910390fd5b7f000000000000000000000000637b1e6e71007d033b5d4385179037c90665a2036001600160a01b0316610719611812565b6001600160a01b03161461073f5760405162461bcd60e51b81526004016106de90612bef565b6107488161182d565b604080515f8082526020820190925261076391839190611835565b50565b5f61067484848461199f565b61077a6119f1565b610784335f611a81565b565b6001600160a01b037f000000000000000000000000637b1e6e71007d033b5d4385179037c90665a2031630036107ce5760405162461bcd60e51b81526004016106de90612ba3565b7f000000000000000000000000637b1e6e71007d033b5d4385179037c90665a2036001600160a01b0316610800611812565b6001600160a01b0316146108265760405162461bcd60e51b81526004016106de90612bef565b61082f8261182d565b61083b82826001611835565b5050565b5f306001600160a01b037f000000000000000000000000637b1e6e71007d033b5d4385179037c90665a20316146108de5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016106de565b505f516020612e7c5f395f51905f5290565b5f54610100900460ff161580801561090e57505f54600160ff909116105b806109275750303b15801561092757505f5460ff166001145b61098a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106de565b5f805460ff1916600117905580156109ab575f805461ff0019166101001790555b6109b58585611a89565b6001600160401b03831615806109d3575046836001600160401b0316145b156109f1576040516308279a2560e31b815260040160405180910390fd5b600146111580610a0757506001600160401b0346115b15610a2557604051638f972ecb60e01b815260040160405180910390fd5b4315610a6f5743600103610a56575f610a3f600143612c4f565b5f81815260fb602052604090209040905550610a6f565b604051635a0f9e4160e11b815260040160405180910390fd5b60fe80546001600160401b0380861667ffffffffffffffff199283161790925560fd805492851692909116919091179055610aa943611ac3565b5060fc558015610af2575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b610b01611b53565b6107845f611bad565b60655433906001600160a01b03168114610b785760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016106de565b61076381611bad565b610b89611bc6565b610784336001611a81565b5f610b9d611812565b905090565b5f5f5f610bad610c2d565b9050610c0c816020015160ff16825f015163ffffffff16610bce9190612c62565b60fd5483516001600160401b038083169263ffffffff90921691610bfb91600160401b909104168a612c79565b610c059190612c98565b875f611c37565b90969095509350505050565b5f610c2446848461199f565b90505b92915050565b604080518082019091525f8082526020820152610b9d60408051808201909152630393870081526008602082015290565b825f819003610c805760405163ec73295960e01b815260040160405180910390fd5b826001600160401b0316805f03610caa5760405163ec73295960e01b815260040160405180910390fd5b3371777735367b36bc9b61c50022d9d0700db4ec14610cdc57604051636494e9f760e01b815260040160405180910390fd5b6002610cea60c95460ff1690565b60ff1603610d0b5760405163dfc60d8560e01b815260040160405180910390fd5b610d156002611cc0565b620cd3404310610d3857604051631799c89b60e01b815260040160405180910390fd5b5f610d44600143612c4f565b90505f5f610d5183611ac3565b915091508160fc5414610d775760405163d719258d60e01b815260040160405180910390fd5b5f5f610d838989610ba2565b91509150610d8e5f90565b158015610d9b5750814814155b15610db9576040516336d54d4f60e11b815260040160405180910390fd5b60fd546001600160401b03600160401b9091048116908a161115610ec457610df26d7369676e616c5f7365727669636560901b5f610c18565b60fe546040516313e4299d60e21b81526001600160401b0391821660048201527f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da1696024820152908b166044820152606481018c90526001600160a01b039190911690634f90a674906084016020604051808303815f875af1158015610e79573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e9d9190612cc1565b5060fd805467ffffffffffffffff60401b1916600160401b6001600160401b038c16021790555b5f85815260fb60205260409081902086409081905560fc85905560fd8054426001600160401b03908116600160801b0277ffffffffffffffff0000000000000000ffffffffffffffff199092169086161717905590517f41c3f410f5c8ac36bb46b1dccef0de0f964087c9e688795fa02ecfa2c20b3fe490610f5b90839085909182526001600160401b0316602082015260400190565b60405180910390a1505050505050610f736001611cc0565b505050505050565b5f8080610f8e6060880160408901612cd8565b610f9e9063ffffffff1687612c98565b9050610fb060a0880160808901612cd8565b63ffffffff1615801590610fe15750610fcf60a0880160808901612cd8565b63ffffffff16816001600160401b0316115b15610fff57610ff660a0880160808901612cd8565b63ffffffff1690505b5f61100d6020890189612cf1565b60ff1661102060608a0160408b01612cd8565b63ffffffff166110309190612c62565b905061104e8187848861104960808e0160608f01612d11565b611c37565b93509350505094509492505050565b5f43821061106c57505f919050565b4361107983610100612d2a565b1061108357504090565b505f90815260fb602052604090205490565b61109d611b53565b606580546001600160a01b0383166001600160a01b031990911681179091556110ce6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b61111a60c954610100900460ff1660021490565b156111385760405163bae6e2a960e01b815260040160405180910390fd5b693bb4ba34323930bbb2b960b11b6111586033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614158015611195575061117f816001610c18565b6001600160a01b0316336001600160a01b031614155b156111b357604051630d85cccf60e11b815260040160405180910390fd5b60026111c160c95460ff1690565b60ff16036111e25760405163dfc60d8560e01b815260040160405180910390fd5b6111ec6002611cc0565b6001600160a01b0382166112135760405163053fd54760e01b815260040160405180910390fd5b6001600160a01b038316611239576112346001600160a01b03831647611cd6565b6112b6565b6040516370a0823160e01b81523060048201526112b69083906001600160a01b038616906370a0823190602401602060405180830381865afa158015611281573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112a59190612cc1565b6001600160a01b0386169190611ce1565b6112c06001611cc0565b505050565b825f8190036112e75760405163ec73295960e01b815260040160405180910390fd5b846001600160401b0316805f036113115760405163ec73295960e01b815260040160405180910390fd5b6113216060840160408501612cd8565b63ffffffff16805f036113475760405163ec73295960e01b815260040160405180910390fd5b6113546020850185612cf1565b60ff16805f036113775760405163ec73295960e01b815260040160405180910390fd5b3371777735367b36bc9b61c50022d9d0700db4ec146113a957604051636494e9f760e01b815260040160405180910390fd5b60026113b760c95460ff1690565b60ff16036113d85760405163dfc60d8560e01b815260040160405180910390fd5b6113e26002611cc0565b620cd34043101561140657604051631799c89b60e01b815260040160405180910390fd5b5f611412600143612c4f565b90505f5f61141f83611ac3565b915091508160fc54146114455760405163d719258d60e01b815260040160405180910390fd5b60fc55505f6114576020880188612cf1565b60ff1661146a6060890160408a01612cd8565b63ffffffff1661147a9190612c98565b60fd549091506001600160401b03808316600160c01b90920416146115155760fd54600160c01b90046001600160401b0316156114f45760fd546114d2906001600160401b0380821691600160c01b90041683610668565b60fd805467ffffffffffffffff19166001600160401b03929092169190911790555b60fd80546001600160c01b0316600160c01b6001600160401b038416021790555b5060fd545f90819061154f90899061153d90600160801b90046001600160401b031642612c4f565b60fd546001600160401b03168c610f7b565b9150915061155a5f90565b1580156115675750814814155b15611585576040516336d54d4f60e11b815260040160405180910390fd5b60fd805467ffffffffffffffff19166001600160401b039283161790819055600160401b90048116908b16111590506116a5576115d36d7369676e616c5f7365727669636560901b5f610c18565b60fe546040516313e4299d60e21b81526001600160401b0391821660048201527f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da1696024820152908b166044820152606481018a90526001600160a01b039190911690634f90a674906084016020604051808303815f875af115801561165a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061167e9190612cc1565b5060fd805467ffffffffffffffff60401b1916600160401b6001600160401b038c16021790555b5f81815260fb60205260409081902082409081905560fd80546001600160401b03428116600160801b0267ffffffffffffffff60801b1983168117909355935192937f41c3f410f5c8ac36bb46b1dccef0de0f964087c9e688795fa02ecfa2c20b3fe493611730938693908316921691909117909182526001600160401b0316602082015260400190565b60405180910390a150506117446001611cc0565b5050505050505050565b5f826001600160401b03165f03611766575080610677565b670de0b6b3a76400005f6001600160401b038086169061178890861684612c62565b6117929190612d51565b90508015806117a757506001600160ff1b0381115b156117c557604051636296f1b960e11b815260040160405180910390fd5b5f6117cf82611d33565b90505f828802828702015f8112600181146117ee5785820492506117f2565b5f92505b506118069050816001600160401b03611f50565b98975050505050505050565b5f516020612e7c5f395f51905f52546001600160a01b031690565b610763611b53565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611868576112c083611f64565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156118c2575060408051601f3d908101601f191682019092526118bf91810190612cc1565b60015b6119255760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016106de565b5f516020612e7c5f395f51905f5281146119935760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016106de565b506112c0838383611fff565b5f6119aa8484612029565b9050811580156119c157506001600160a01b038116155b1561067757604051632b0d65db60e01b81526001600160401b0385166004820152602481018490526044016106de565b611a0560c954610100900460ff1660021490565b611a225760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461010069ffffffffffffffffff001990911662010000426001600160401b031602171790556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b61083b611b53565b806001600160a01b038116611ab15760405163538ba4f960e01b815260040160405180910390fd5b611aba836120d3565b6112c082612131565b5f5f611acd6127fd565b5f5b60ff81108015611ae25750806001018510155b15611b13575f198186030180408360ff83066101008110611b0557611b05612d64565b602002015250600101611acf565b5046611fe082015261200081209250834081611b3060ff87612d78565b6101008110611b4157611b41612d64565b60200201526120009020919391925050565b6033546001600160a01b031633146107845760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106de565b606580546001600160a01b0319169055610763816121a1565b611bda60c954610100900460ff1660021490565b15611bf85760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001611a77565b5f8080611c5363ffffffff86166001600160401b038916612d2a565b9050856001600160401b03168111611c6c576001611c7f565b611c7f6001600160401b03871682612c4f565b9050611c9e6001600160401b03611c98838783166121f2565b90611f50565b9150611cb3826001600160401b031689612207565b9250509550959350505050565b60c9805460ff191660ff92909216919091179055565b61083b82825a612236565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526112c0908490612279565b6fffffffffffffffffffffffffffffffff811160071b81811c6001600160401b031060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b175f8213611d8f57631615e6385f526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd1901909102780a09507084cc699bb0e71ea869ffffffffffffffffffffffff190105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b5f818311611f5e5782610c24565b50919050565b6001600160a01b0381163b611fd15760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016106de565b5f516020612e7c5f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b6120088361234c565b5f825111806120145750805b156112c057612023838361238b565b50505050565b6097545f906001600160a01b03168061205557604051638ed88b2560e01b815260040160405180910390fd5b604051630a3dc4f360e21b81526001600160401b0385166004820152602481018490526001600160a01b038216906328f713cc90604401602060405180830381865afa1580156120a7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120cb9190612d8b565b949350505050565b5f54610100900460ff166120f95760405162461bcd60e51b81526004016106de90612da6565b6121016123b0565b61211f6001600160a01b038216156121195781611bad565b33611bad565b5060c9805461ff001916610100179055565b5f54610100900460ff166121575760405162461bcd60e51b81526004016106de90612da6565b6001600160401b0346111561217f5760405163a12e8fa960e01b815260040160405180910390fd5b609780546001600160a01b0319166001600160a01b0392909216919091179055565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f8183116122005781610c24565b5090919050565b5f5f8261221485856123d6565b61221e9190612d51565b9050801561222c57806120cb565b5060019392505050565b815f0361224257505050565b61225c83838360405180602001604052805f815250612450565b6112c057604051634c67134d60e11b815260040160405180910390fd5b5f6122cd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661248d9092919063ffffffff16565b905080515f14806122ed5750808060200190518101906122ed9190612df1565b6112c05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016106de565b61235581611f64565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b6060610c248383604051806060016040528060278152602001612e9c6027913961249b565b5f54610100900460ff166107845760405162461bcd60e51b81526004016106de90612da6565b5f815f036123f757604051636296f1b960e11b815260040160405180910390fd5b5f8261240b85670de0b6b3a7640000612c62565b6124159190612d51565b9050680755bf798b4a1bf1e48111156124345750680755bf798b4a1bf1e45b670de0b6b3a76400006124468261250f565b6120cb9190612d51565b5f6001600160a01b03851661247857604051634c67134d60e11b815260040160405180910390fd5b5f5f835160208501878988f195945050505050565b606061067484845f85612689565b60605f5f856001600160a01b0316856040516124b79190612e2e565b5f60405180830381855af49150503d805f81146124ef576040519150601f19603f3d011682016040523d82523d5f602084013e6124f4565b606091505b509150915061250586838387612760565b9695505050505050565b5f68023f2fa8f6da5b9d2819821361252657919050565b680755bf798b4a1bf1e582126125435763a37bfec95f526004601cfd5b6503782dace9d9604e83901b0591505f60606bb17217f7d1cf79abc9e3b39884821b056001605f1b01901d6bb17217f7d1cf79abc9e3b39881029093036c240c330e9fb2d9cbaf0fd5aafb1981018102606090811d6d0277594991cfc85f6e2461837cd9018202811d6d1a521255e34f6a5061b25ef1c9c319018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d6e02c72388d9f74f51a9331fed693f1419018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084016d01d3967ed30fc4f89c02bab5708119010290911d6e0587f503bb6ea29d25fcb740196450019091026d360d7aeea093263ecc6e0ecb291760621b010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6060824710156126ea5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016106de565b5f5f866001600160a01b031685876040516127059190612e2e565b5f6040518083038185875af1925050503d805f811461273f576040519150601f19603f3d011682016040523d82523d5f602084013e612744565b606091505b509150915061275587838387612760565b979650505050505050565b606083156127ce5782515f036127c7576001600160a01b0385163b6127c75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106de565b50816120cb565b6120cb83838151156127e35781518083602001fd5b8060405162461bcd60e51b81526004016106de9190612e49565b604051806120000160405280610100906020820280368337509192915050565b80356001600160401b0381168114612833575f5ffd5b919050565b5f5f5f6060848603121561284a575f5ffd5b6128538461281d565b92506128616020850161281d565b915061286f6040850161281d565b90509250925092565b6001600160a01b0381168114610763575f5ffd5b5f6020828403121561289c575f5ffd5b813561067781612878565b8015158114610763575f5ffd5b5f5f5f606084860312156128c6575f5ffd5b6128cf8461281d565b92506020840135915060408401356128e6816128a7565b809150509250925092565b634e487b7160e01b5f52604160045260245ffd5b5f5f60408385031215612916575f5ffd5b823561292181612878565b915060208301356001600160401b0381111561293b575f5ffd5b8301601f8101851361294b575f5ffd5b80356001600160401b03811115612964576129646128f1565b604051601f8201601f19908116603f011681016001600160401b0381118282101715612992576129926128f1565b6040528181528282016020018710156129a9575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f5f5f5f608085870312156129db575f5ffd5b84356129e681612878565b935060208501356129f681612878565b9250612a046040860161281d565b9150612a126060860161281d565b905092959194509250565b803563ffffffff81168114612833575f5ffd5b5f5f60408385031215612a41575f5ffd5b612a4a8361281d565b9150612a5860208401612a1d565b90509250929050565b5f5f60408385031215612a72575f5ffd5b823591506020830135612a84816128a7565b809150509250929050565b5f5f5f5f60808587031215612aa2575f5ffd5b8435935060208501359250612ab96040860161281d565b9150612a1260608601612a1d565b5f60a08284031215611f5e575f5ffd5b5f5f5f5f6101008587031215612aeb575f5ffd5b612af58686612ac7565b9350612b0360a0860161281d565b9250612b1160c0860161281d565b9150612a1260e08601612a1d565b5f60208284031215612b2f575f5ffd5b5035919050565b5f5f60408385031215612b47575f5ffd5b8235612b5281612878565b91506020830135612a8481612878565b5f5f5f5f6101008587031215612b76575f5ffd5b612b7f8561281d565b935060208501359250612b9460408601612a1d565b9150612a128660608701612ac7565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610c2757610c27612c3b565b8082028115828204841417610c2757610c27612c3b565b6001600160401b038281168282160390811115610c2757610c27612c3b565b6001600160401b038181168382160290811690818114612cba57612cba612c3b565b5092915050565b5f60208284031215612cd1575f5ffd5b5051919050565b5f60208284031215612ce8575f5ffd5b610c2482612a1d565b5f60208284031215612d01575f5ffd5b813560ff81168114610677575f5ffd5b5f60208284031215612d21575f5ffd5b610c248261281d565b80820180821115610c2757610c27612c3b565b634e487b7160e01b5f52601260045260245ffd5b5f82612d5f57612d5f612d3d565b500490565b634e487b7160e01b5f52603260045260245ffd5b5f82612d8657612d86612d3d565b500690565b5f60208284031215612d9b575f5ffd5b815161067781612878565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b5f60208284031215612e01575f5ffd5b8151610677816128a7565b5f5b83811015612e26578181015183820152602001612e0e565b50505f910152565b5f8251612e3f818460208701612e0c565b9190910192915050565b602081525f8251806020840152612e67816040850160208701612e0c565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212207dcc14406ad6bb9af012ee74a455a42f3f2d8bfc77c9b7eed1da1bc3075314ce64736f6c634300081b0033