Source Code
Overview
S Balance
S Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SmartAccount
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2025-11-23 */ // Sources flattened with hardhat v2.26.0 https://hardhat.org // SPDX-License-Identifier: MIT // File @openzeppelin/contracts/utils/introspection/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol) pragma solidity >=0.4.16; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * 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[ERC 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); } // File @openzeppelin/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol) pragma solidity >=0.4.16; // File @openzeppelin/contracts/token/ERC20/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol) pragma solidity >=0.4.16; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ 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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); } // File @openzeppelin/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol) pragma solidity >=0.4.16; // File @openzeppelin/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol) pragma solidity >=0.6.2; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); } // File @openzeppelin/contracts/token/ERC20/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; /** * @title SafeERC20 * @dev Wrappers around ERC-20 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 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @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.encodeCall(token.transfer, (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.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful. */ function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) { return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful. */ function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) { return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, 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. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @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. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @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 {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @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 silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } } // File @openzeppelin/contracts/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol) pragma solidity ^0.8.20; /** * @dev Helper library for emitting standardized panic codes. * * ```solidity * contract Example { * using Panic for uint256; * * // Use any of the declared internal constants * function foo() { Panic.GENERIC.panic(); } * * // Alternatively * function foo() { Panic.panic(Panic.GENERIC); } * } * ``` * * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil]. * * _Available since v5.1._ */ // slither-disable-next-line unused-state library Panic { /// @dev generic / unspecified error uint256 internal constant GENERIC = 0x00; /// @dev used by the assert() builtin uint256 internal constant ASSERT = 0x01; /// @dev arithmetic underflow or overflow uint256 internal constant UNDER_OVERFLOW = 0x11; /// @dev division or modulo by zero uint256 internal constant DIVISION_BY_ZERO = 0x12; /// @dev enum conversion error uint256 internal constant ENUM_CONVERSION_ERROR = 0x21; /// @dev invalid encoding in storage uint256 internal constant STORAGE_ENCODING_ERROR = 0x22; /// @dev empty array pop uint256 internal constant EMPTY_ARRAY_POP = 0x31; /// @dev array out of bounds access uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32; /// @dev resource error (too large allocation or too large array) uint256 internal constant RESOURCE_ERROR = 0x41; /// @dev calling invalid internal function uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51; /// @dev Reverts with a panic code. Recommended to use with /// the internal constants with predefined codes. function panic(uint256 code) internal pure { assembly ("memory-safe") { mstore(0x00, 0x4e487b71) mstore(0x20, code) revert(0x1c, 0x24) } } } // File @openzeppelin/contracts/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.3.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Return the 512-bit addition of two uint256. * * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low. */ function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) { assembly ("memory-safe") { low := add(a, b) high := lt(low, a) } } /** * @dev Return the 512-bit multiplication of two uint256. * * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low. */ function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) { // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = high * 2²⁵⁶ + low. assembly ("memory-safe") { let mm := mulmod(a, b, not(0)) low := mul(a, b) high := sub(sub(mm, low), lt(mm, low)) } } /** * @dev Returns the addition of two unsigned integers, with a success flag (no overflow). */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a + b; success = c >= a; result = c * SafeCast.toUint(success); } } /** * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow). */ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a - b; success = c <= a; result = c * SafeCast.toUint(success); } } /** * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow). */ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a * b; assembly ("memory-safe") { // Only true when the multiplication doesn't overflow // (c / a == b) || (a == 0) success := or(eq(div(c, a), b), iszero(a)) } // equivalent to: success ? c : 0 result = c * SafeCast.toUint(success); } } /** * @dev Returns the division of two unsigned integers, with a success flag (no division by zero). */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { success = b > 0; assembly ("memory-safe") { // The `DIV` opcode returns zero when the denominator is 0. result := div(a, b) } } } /** * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero). */ function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { success = b > 0; assembly ("memory-safe") { // The `MOD` opcode returns zero when the denominator is 0. result := mod(a, b) } } } /** * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing. */ function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) { (bool success, uint256 result) = tryAdd(a, b); return ternary(success, result, type(uint256).max); } /** * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing. */ function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) { (, uint256 result) = trySub(a, b); return result; } /** * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing. */ function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) { (bool success, uint256 result) = tryMul(a, b); return ternary(success, result, type(uint256).max); } /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * SafeCast.toUint(condition)); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. Panic.panic(Panic.DIVISION_BY_ZERO); } // The following calculation ensures accurate ceiling division without overflow. // Since a is non-zero, (a - 1) / b will not overflow. // The largest possible result occurs when (a - 1) / b is type(uint256).max, // but the largest value we can obtain is type(uint256).max - 1, which happens // when a = type(uint256).max and b = 1. unchecked { return SafeCast.toUint(a > 0) * ((a - 1) / b + 1); } } /** * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { (uint256 high, uint256 low) = mul512(x, y); // Handle non-overflow cases, 256 by 256 division. if (high == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return low / denominator; } // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0. if (denominator <= high) { Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW)); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [high low]. uint256 remainder; assembly ("memory-safe") { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. high := sub(high, gt(remainder, low)) low := sub(low, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly ("memory-safe") { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [high low] by twos. low := div(low, twos) // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from high into low. low |= high * twos; // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv ≡ 1 mod 2⁴. uint256 inverse = (3 * denominator) ^ 2; // Use the 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. inverse *= 2 - denominator * inverse; // inverse mod 2⁸ inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶ inverse *= 2 - denominator * inverse; // inverse mod 2³² inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴ inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸ inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶ // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high // is no longer required. result = low * inverse; return result; } } /** * @dev Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0); } /** * @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256. */ function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) { unchecked { (uint256 high, uint256 low) = mul512(x, y); if (high >= 1 << n) { Panic.panic(Panic.UNDER_OVERFLOW); } return (high << (256 - n)) | (low >> n); } } /** * @dev Calculates x * y >> n with full precision, following the selected rounding direction. */ function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) { return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0); } /** * @dev Calculate the modular multiplicative inverse of a number in Z/nZ. * * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0. * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible. * * If the input value is not inversible, 0 is returned. * * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}. */ function invMod(uint256 a, uint256 n) internal pure returns (uint256) { unchecked { if (n == 0) return 0; // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version) // Used to compute integers x and y such that: ax + ny = gcd(a, n). // When the gcd is 1, then the inverse of a modulo n exists and it's x. // ax + ny = 1 // ax = 1 + (-y)n // ax ≡ 1 (mod n) # x is the inverse of a modulo n // If the remainder is 0 the gcd is n right away. uint256 remainder = a % n; uint256 gcd = n; // Therefore the initial coefficients are: // ax + ny = gcd(a, n) = n // 0a + 1n = n int256 x = 0; int256 y = 1; while (remainder != 0) { uint256 quotient = gcd / remainder; (gcd, remainder) = ( // The old remainder is the next gcd to try. remainder, // Compute the next remainder. // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd // where gcd is at most n (capped to type(uint256).max) gcd - remainder * quotient ); (x, y) = ( // Increment the coefficient of a. y, // Decrement the coefficient of n. // Can overflow, but the result is casted to uint256 so that the // next value of y is "wrapped around" to a value between 0 and n - 1. x - y * int256(quotient) ); } if (gcd != 1) return 0; // No inverse exists. return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative. } } /** * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`. * * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that * `a**(p-2)` is the modular multiplicative inverse of a in Fp. * * NOTE: this function does NOT check that `p` is a prime greater than `2`. */ function invModPrime(uint256 a, uint256 p) internal view returns (uint256) { unchecked { return Math.modExp(a, p - 2, p); } } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m) * * Requirements: * - modulus can't be zero * - underlying staticcall to precompile must succeed * * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make * sure the chain you're using it on supports the precompiled contract for modular exponentiation * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, * the underlying function will succeed given the lack of a revert, but the result may be incorrectly * interpreted as 0. */ function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) { (bool success, uint256 result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m). * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying * to operate modulo 0 or if the underlying precompile reverted. * * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack * of a revert, but the result may be incorrectly interpreted as 0. */ function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) { if (m == 0) return (false, 0); assembly ("memory-safe") { let ptr := mload(0x40) // | Offset | Content | Content (Hex) | // |-----------|------------|--------------------------------------------------------------------| // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x60:0x7f | value of b | 0x<.............................................................b> | // | 0x80:0x9f | value of e | 0x<.............................................................e> | // | 0xa0:0xbf | value of m | 0x<.............................................................m> | mstore(ptr, 0x20) mstore(add(ptr, 0x20), 0x20) mstore(add(ptr, 0x40), 0x20) mstore(add(ptr, 0x60), b) mstore(add(ptr, 0x80), e) mstore(add(ptr, 0xa0), m) // Given the result < m, it's guaranteed to fit in 32 bytes, // so we can use the memory scratch space located at offset 0. success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20) result := mload(0x00) } } /** * @dev Variant of {modExp} that supports inputs of arbitrary length. */ function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) { (bool success, bytes memory result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Variant of {tryModExp} that supports inputs of arbitrary length. */ function tryModExp( bytes memory b, bytes memory e, bytes memory m ) internal view returns (bool success, bytes memory result) { if (_zeroBytes(m)) return (false, new bytes(0)); uint256 mLen = m.length; // Encode call args in result and move the free memory pointer result = abi.encodePacked(b.length, e.length, mLen, b, e, m); assembly ("memory-safe") { let dataPtr := add(result, 0x20) // Write result on top of args to avoid allocating extra memory. success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen) // Overwrite the length. // result.length > returndatasize() is guaranteed because returndatasize() == m.length mstore(result, mLen) // Set the memory pointer after the returned data. mstore(0x40, add(dataPtr, mLen)) } } /** * @dev Returns whether the provided byte array is zero. */ function _zeroBytes(bytes memory byteArray) private pure returns (bool) { for (uint256 i = 0; i < byteArray.length; ++i) { if (byteArray[i] != 0) { return false; } } return true; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * This method is based on Newton's method for computing square roots; the algorithm is restricted to only * using integer operations. */ function sqrt(uint256 a) internal pure returns (uint256) { unchecked { // Take care of easy edge cases when a == 0 or a == 1 if (a <= 1) { return a; } // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between // the current value as `ε_n = | x_n - sqrt(a) |`. // // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is // bigger than any uint256. // // By noticing that // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)` // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar // to the msb function. uint256 aa = a; uint256 xn = 1; if (aa >= (1 << 128)) { aa >>= 128; xn <<= 64; } if (aa >= (1 << 64)) { aa >>= 64; xn <<= 32; } if (aa >= (1 << 32)) { aa >>= 32; xn <<= 16; } if (aa >= (1 << 16)) { aa >>= 16; xn <<= 8; } if (aa >= (1 << 8)) { aa >>= 8; xn <<= 4; } if (aa >= (1 << 4)) { aa >>= 4; xn <<= 2; } if (aa >= (1 << 2)) { xn <<= 1; } // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1). // // We can refine our estimation by noticing that the middle of that interval minimizes the error. // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2). // This is going to be our x_0 (and ε_0) xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2) // From here, Newton's method give us: // x_{n+1} = (x_n + a / x_n) / 2 // // One should note that: // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a // = ((x_n² + a) / (2 * x_n))² - a // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²) // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²) // = (x_n² - a)² / (2 * x_n)² // = ((x_n² - a) / (2 * x_n))² // ≥ 0 // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n // // This gives us the proof of quadratic convergence of the sequence: // ε_{n+1} = | x_{n+1} - sqrt(a) | // = | (x_n + a / x_n) / 2 - sqrt(a) | // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) | // = | (x_n - sqrt(a))² / (2 * x_n) | // = | ε_n² / (2 * x_n) | // = ε_n² / | (2 * x_n) | // // For the first iteration, we have a special case where x_0 is known: // ε_1 = ε_0² / | (2 * x_0) | // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2))) // ≤ 2**(2*e-4) / (3 * 2**(e-1)) // ≤ 2**(e-3) / 3 // ≤ 2**(e-3-log2(3)) // ≤ 2**(e-4.5) // // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n: // ε_{n+1} = ε_n² / | (2 * x_n) | // ≤ (2**(e-k))² / (2 * 2**(e-1)) // ≤ 2**(2*e-2*k) / 2**e // ≤ 2**(e-2*k) xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5 xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9 xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18 xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36 xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72 // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either // sqrt(a) or sqrt(a) + 1. return xn - SafeCast.toUint(xn > a / xn); } } /** * @dev Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 x) internal pure returns (uint256 r) { // If value has upper 128 bits set, log2 result is at least 128 r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7; // If upper 64 bits of 128-bit half set, add 64 to result r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6; // If upper 32 bits of 64-bit half set, add 32 to result r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5; // If upper 16 bits of 32-bit half set, add 16 to result r |= SafeCast.toUint((x >> r) > 0xffff) << 4; // If upper 8 bits of 16-bit half set, add 8 to result r |= SafeCast.toUint((x >> r) > 0xff) << 3; // If upper 4 bits of 8-bit half set, add 4 to result r |= SafeCast.toUint((x >> r) > 0xf) << 2; // Shifts value right by the current result and use it as an index into this lookup table: // // | x (4 bits) | index | table[index] = MSB position | // |------------|---------|-----------------------------| // | 0000 | 0 | table[0] = 0 | // | 0001 | 1 | table[1] = 0 | // | 0010 | 2 | table[2] = 1 | // | 0011 | 3 | table[3] = 1 | // | 0100 | 4 | table[4] = 2 | // | 0101 | 5 | table[5] = 2 | // | 0110 | 6 | table[6] = 2 | // | 0111 | 7 | table[7] = 2 | // | 1000 | 8 | table[8] = 3 | // | 1001 | 9 | table[9] = 3 | // | 1010 | 10 | table[10] = 3 | // | 1011 | 11 | table[11] = 3 | // | 1100 | 12 | table[12] = 3 | // | 1101 | 13 | table[13] = 3 | // | 1110 | 14 | table[14] = 3 | // | 1111 | 15 | table[15] = 3 | // // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the last 16 bytes. assembly ("memory-safe") { r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000)) } } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 x) internal pure returns (uint256 r) { // If value has upper 128 bits set, log2 result is at least 128 r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7; // If upper 64 bits of 128-bit half set, add 64 to result r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6; // If upper 32 bits of 64-bit half set, add 32 to result r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5; // If upper 16 bits of 32-bit half set, add 16 to result r |= SafeCast.toUint((x >> r) > 0xffff) << 4; // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8 return (r >> 3) | SafeCast.toUint((x >> r) > 0xff); } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } // File @openzeppelin/contracts/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * int256(SafeCast.toUint(condition))); } } /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson. // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift, // taking advantage of the most significant (or "sign" bit) in two's complement representation. // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result, // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative). int256 mask = n >> 255; // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it. return uint256((n + mask) ^ mask); } } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (utils/Strings.sol) pragma solidity ^0.8.20; /** * @dev String operations. */ library Strings { using SafeCast for *; bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; uint256 private constant SPECIAL_CHARS_LOOKUP = (1 << 0x08) | // backspace (1 << 0x09) | // tab (1 << 0x0a) | // newline (1 << 0x0c) | // form feed (1 << 0x0d) | // carriage return (1 << 0x22) | // double quote (1 << 0x5c); // backslash /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev The string being parsed contains characters that are not in scope of the given base. */ error StringsInvalidChar(); /** * @dev The string being parsed is not a properly formatted address. */ error StringsInvalidAddressFormat(); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; assembly ("memory-safe") { ptr := add(add(buffer, 0x20), length) } while (true) { ptr--; assembly ("memory-safe") { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal * representation, according to EIP-55. */ function toChecksumHexString(address addr) internal pure returns (string memory) { bytes memory buffer = bytes(toHexString(addr)); // hash the hex part of buffer (skip length + 2 bytes, length 40) uint256 hashValue; assembly ("memory-safe") { hashValue := shr(96, keccak256(add(buffer, 0x22), 40)) } for (uint256 i = 41; i > 1; --i) { // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f) if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) { // case shift by xoring with 0x20 buffer[i] ^= 0x20; } hashValue >>= 4; } return string(buffer); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } /** * @dev Parse a decimal string and returns the value as a `uint256`. * * Requirements: * - The string must be formatted as `[0-9]*` * - The result must fit into an `uint256` type */ function parseUint(string memory input) internal pure returns (uint256) { return parseUint(input, 0, bytes(input).length); } /** * @dev Variant of {parseUint-string} that parses a substring of `input` located between position `begin` (included) and * `end` (excluded). * * Requirements: * - The substring must be formatted as `[0-9]*` * - The result must fit into an `uint256` type */ function parseUint(string memory input, uint256 begin, uint256 end) internal pure returns (uint256) { (bool success, uint256 value) = tryParseUint(input, begin, end); if (!success) revert StringsInvalidChar(); return value; } /** * @dev Variant of {parseUint-string} that returns false if the parsing fails because of an invalid character. * * NOTE: This function will revert if the result does not fit in a `uint256`. */ function tryParseUint(string memory input) internal pure returns (bool success, uint256 value) { return _tryParseUintUncheckedBounds(input, 0, bytes(input).length); } /** * @dev Variant of {parseUint-string-uint256-uint256} that returns false if the parsing fails because of an invalid * character. * * NOTE: This function will revert if the result does not fit in a `uint256`. */ function tryParseUint( string memory input, uint256 begin, uint256 end ) internal pure returns (bool success, uint256 value) { if (end > bytes(input).length || begin > end) return (false, 0); return _tryParseUintUncheckedBounds(input, begin, end); } /** * @dev Implementation of {tryParseUint-string-uint256-uint256} that does not check bounds. Caller should make sure that * `begin <= end <= input.length`. Other inputs would result in undefined behavior. */ function _tryParseUintUncheckedBounds( string memory input, uint256 begin, uint256 end ) private pure returns (bool success, uint256 value) { bytes memory buffer = bytes(input); uint256 result = 0; for (uint256 i = begin; i < end; ++i) { uint8 chr = _tryParseChr(bytes1(_unsafeReadBytesOffset(buffer, i))); if (chr > 9) return (false, 0); result *= 10; result += chr; } return (true, result); } /** * @dev Parse a decimal string and returns the value as a `int256`. * * Requirements: * - The string must be formatted as `[-+]?[0-9]*` * - The result must fit in an `int256` type. */ function parseInt(string memory input) internal pure returns (int256) { return parseInt(input, 0, bytes(input).length); } /** * @dev Variant of {parseInt-string} that parses a substring of `input` located between position `begin` (included) and * `end` (excluded). * * Requirements: * - The substring must be formatted as `[-+]?[0-9]*` * - The result must fit in an `int256` type. */ function parseInt(string memory input, uint256 begin, uint256 end) internal pure returns (int256) { (bool success, int256 value) = tryParseInt(input, begin, end); if (!success) revert StringsInvalidChar(); return value; } /** * @dev Variant of {parseInt-string} that returns false if the parsing fails because of an invalid character or if * the result does not fit in a `int256`. * * NOTE: This function will revert if the absolute value of the result does not fit in a `uint256`. */ function tryParseInt(string memory input) internal pure returns (bool success, int256 value) { return _tryParseIntUncheckedBounds(input, 0, bytes(input).length); } uint256 private constant ABS_MIN_INT256 = 2 ** 255; /** * @dev Variant of {parseInt-string-uint256-uint256} that returns false if the parsing fails because of an invalid * character or if the result does not fit in a `int256`. * * NOTE: This function will revert if the absolute value of the result does not fit in a `uint256`. */ function tryParseInt( string memory input, uint256 begin, uint256 end ) internal pure returns (bool success, int256 value) { if (end > bytes(input).length || begin > end) return (false, 0); return _tryParseIntUncheckedBounds(input, begin, end); } /** * @dev Implementation of {tryParseInt-string-uint256-uint256} that does not check bounds. Caller should make sure that * `begin <= end <= input.length`. Other inputs would result in undefined behavior. */ function _tryParseIntUncheckedBounds( string memory input, uint256 begin, uint256 end ) private pure returns (bool success, int256 value) { bytes memory buffer = bytes(input); // Check presence of a negative sign. bytes1 sign = begin == end ? bytes1(0) : bytes1(_unsafeReadBytesOffset(buffer, begin)); // don't do out-of-bound (possibly unsafe) read if sub-string is empty bool positiveSign = sign == bytes1("+"); bool negativeSign = sign == bytes1("-"); uint256 offset = (positiveSign || negativeSign).toUint(); (bool absSuccess, uint256 absValue) = tryParseUint(input, begin + offset, end); if (absSuccess && absValue < ABS_MIN_INT256) { return (true, negativeSign ? -int256(absValue) : int256(absValue)); } else if (absSuccess && negativeSign && absValue == ABS_MIN_INT256) { return (true, type(int256).min); } else return (false, 0); } /** * @dev Parse a hexadecimal string (with or without "0x" prefix), and returns the value as a `uint256`. * * Requirements: * - The string must be formatted as `(0x)?[0-9a-fA-F]*` * - The result must fit in an `uint256` type. */ function parseHexUint(string memory input) internal pure returns (uint256) { return parseHexUint(input, 0, bytes(input).length); } /** * @dev Variant of {parseHexUint-string} that parses a substring of `input` located between position `begin` (included) and * `end` (excluded). * * Requirements: * - The substring must be formatted as `(0x)?[0-9a-fA-F]*` * - The result must fit in an `uint256` type. */ function parseHexUint(string memory input, uint256 begin, uint256 end) internal pure returns (uint256) { (bool success, uint256 value) = tryParseHexUint(input, begin, end); if (!success) revert StringsInvalidChar(); return value; } /** * @dev Variant of {parseHexUint-string} that returns false if the parsing fails because of an invalid character. * * NOTE: This function will revert if the result does not fit in a `uint256`. */ function tryParseHexUint(string memory input) internal pure returns (bool success, uint256 value) { return _tryParseHexUintUncheckedBounds(input, 0, bytes(input).length); } /** * @dev Variant of {parseHexUint-string-uint256-uint256} that returns false if the parsing fails because of an * invalid character. * * NOTE: This function will revert if the result does not fit in a `uint256`. */ function tryParseHexUint( string memory input, uint256 begin, uint256 end ) internal pure returns (bool success, uint256 value) { if (end > bytes(input).length || begin > end) return (false, 0); return _tryParseHexUintUncheckedBounds(input, begin, end); } /** * @dev Implementation of {tryParseHexUint-string-uint256-uint256} that does not check bounds. Caller should make sure that * `begin <= end <= input.length`. Other inputs would result in undefined behavior. */ function _tryParseHexUintUncheckedBounds( string memory input, uint256 begin, uint256 end ) private pure returns (bool success, uint256 value) { bytes memory buffer = bytes(input); // skip 0x prefix if present bool hasPrefix = (end > begin + 1) && bytes2(_unsafeReadBytesOffset(buffer, begin)) == bytes2("0x"); // don't do out-of-bound (possibly unsafe) read if sub-string is empty uint256 offset = hasPrefix.toUint() * 2; uint256 result = 0; for (uint256 i = begin + offset; i < end; ++i) { uint8 chr = _tryParseChr(bytes1(_unsafeReadBytesOffset(buffer, i))); if (chr > 15) return (false, 0); result *= 16; unchecked { // Multiplying by 16 is equivalent to a shift of 4 bits (with additional overflow check). // This guarantees that adding a value < 16 will not cause an overflow, hence the unchecked. result += chr; } } return (true, result); } /** * @dev Parse a hexadecimal string (with or without "0x" prefix), and returns the value as an `address`. * * Requirements: * - The string must be formatted as `(0x)?[0-9a-fA-F]{40}` */ function parseAddress(string memory input) internal pure returns (address) { return parseAddress(input, 0, bytes(input).length); } /** * @dev Variant of {parseAddress-string} that parses a substring of `input` located between position `begin` (included) and * `end` (excluded). * * Requirements: * - The substring must be formatted as `(0x)?[0-9a-fA-F]{40}` */ function parseAddress(string memory input, uint256 begin, uint256 end) internal pure returns (address) { (bool success, address value) = tryParseAddress(input, begin, end); if (!success) revert StringsInvalidAddressFormat(); return value; } /** * @dev Variant of {parseAddress-string} that returns false if the parsing fails because the input is not a properly * formatted address. See {parseAddress-string} requirements. */ function tryParseAddress(string memory input) internal pure returns (bool success, address value) { return tryParseAddress(input, 0, bytes(input).length); } /** * @dev Variant of {parseAddress-string-uint256-uint256} that returns false if the parsing fails because input is not a properly * formatted address. See {parseAddress-string-uint256-uint256} requirements. */ function tryParseAddress( string memory input, uint256 begin, uint256 end ) internal pure returns (bool success, address value) { if (end > bytes(input).length || begin > end) return (false, address(0)); bool hasPrefix = (end > begin + 1) && bytes2(_unsafeReadBytesOffset(bytes(input), begin)) == bytes2("0x"); // don't do out-of-bound (possibly unsafe) read if sub-string is empty uint256 expectedLength = 40 + hasPrefix.toUint() * 2; // check that input is the correct length if (end - begin == expectedLength) { // length guarantees that this does not overflow, and value is at most type(uint160).max (bool s, uint256 v) = _tryParseHexUintUncheckedBounds(input, begin, end); return (s, address(uint160(v))); } else { return (false, address(0)); } } function _tryParseChr(bytes1 chr) private pure returns (uint8) { uint8 value = uint8(chr); // Try to parse `chr`: // - Case 1: [0-9] // - Case 2: [a-f] // - Case 3: [A-F] // - otherwise not supported unchecked { if (value > 47 && value < 58) value -= 48; else if (value > 96 && value < 103) value -= 87; else if (value > 64 && value < 71) value -= 55; else return type(uint8).max; } return value; } /** * @dev Escape special characters in JSON strings. This can be useful to prevent JSON injection in NFT metadata. * * WARNING: This function should only be used in double quoted JSON strings. Single quotes are not escaped. * * NOTE: This function escapes all unicode characters, and not just the ones in ranges defined in section 2.5 of * RFC-4627 (U+0000 to U+001F, U+0022 and U+005C). ECMAScript's `JSON.parse` does recover escaped unicode * characters that are not in this range, but other tooling may provide different results. */ function escapeJSON(string memory input) internal pure returns (string memory) { bytes memory buffer = bytes(input); bytes memory output = new bytes(2 * buffer.length); // worst case scenario uint256 outputLength = 0; for (uint256 i; i < buffer.length; ++i) { bytes1 char = bytes1(_unsafeReadBytesOffset(buffer, i)); if (((SPECIAL_CHARS_LOOKUP & (1 << uint8(char))) != 0)) { output[outputLength++] = "\\"; if (char == 0x08) output[outputLength++] = "b"; else if (char == 0x09) output[outputLength++] = "t"; else if (char == 0x0a) output[outputLength++] = "n"; else if (char == 0x0c) output[outputLength++] = "f"; else if (char == 0x0d) output[outputLength++] = "r"; else if (char == 0x5c) output[outputLength++] = "\\"; else if (char == 0x22) { // solhint-disable-next-line quotes output[outputLength++] = '"'; } } else { output[outputLength++] = char; } } // write the actual length and deallocate unused memory assembly ("memory-safe") { mstore(output, outputLength) mstore(0x40, add(output, shl(5, shr(5, add(outputLength, 63))))) } return string(output); } /** * @dev Reads a bytes32 from a bytes array without bounds checking. * * NOTE: making this function internal would mean it could be used with memory unsafe offset, and marking the * assembly block as such would prevent some optimizations. */ function _unsafeReadBytesOffset(bytes memory buffer, uint256 offset) private pure returns (bytes32 value) { // This is not memory safe in the general case, but all calls to this private function are within bounds. assembly ("memory-safe") { value := mload(add(add(buffer, 0x20), offset)) } } } // File @openzeppelin/contracts/utils/cryptography/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.3.0) (utils/cryptography/MessageHashUtils.sol) pragma solidity ^0.8.20; /** * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing. * * The library provides methods for generating a hash of a message that conforms to the * https://eips.ethereum.org/EIPS/eip-191[ERC-191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712] * specifications. */ library MessageHashUtils { /** * @dev Returns the keccak256 digest of an ERC-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing a bytes32 `messageHash` with * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the * hash signed when using the https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign[`eth_sign`] JSON-RPC method. * * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with * keccak256, although any bytes32 value can be safely used because the final digest will * be re-hashed. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) { assembly ("memory-safe") { mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20) } } /** * @dev Returns the keccak256 digest of an ERC-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing an arbitrary `message` with * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the * hash signed when using the https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign[`eth_sign`] JSON-RPC method. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) { return keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message)); } /** * @dev Returns the keccak256 digest of an ERC-191 signed data with version * `0x00` (data with intended validator). * * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended * `validator` address. Then hashing the result. * * See {ECDSA-recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked(hex"19_00", validator, data)); } /** * @dev Variant of {toDataWithIntendedValidatorHash-address-bytes} optimized for cases where `data` is a bytes32. */ function toDataWithIntendedValidatorHash( address validator, bytes32 messageHash ) internal pure returns (bytes32 digest) { assembly ("memory-safe") { mstore(0x00, hex"19_00") mstore(0x02, shl(96, validator)) mstore(0x16, messageHash) digest := keccak256(0x00, 0x36) } } /** * @dev Returns the keccak256 digest of an EIP-712 typed data (ERC-191 version `0x01`). * * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with * `\x19\x01` and hashing the result. It corresponds to the hash signed by the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712. * * See {ECDSA-recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { assembly ("memory-safe") { let ptr := mload(0x40) mstore(ptr, hex"19_01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) digest := keccak256(ptr, 0x42) } } } // File @openzeppelin/contracts/proxy/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.3.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; /** * @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 Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 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 in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reinitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._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 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._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() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @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 { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Pointer to storage slot. Allows integrators to override it with a custom storage location. * * NOTE: Consider following the ERC-7201 formula to derive storage locations. */ function _initializableStorageSlot() internal pure virtual returns (bytes32) { return INITIALIZABLE_STORAGE; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { bytes32 slot = _initializableStorageSlot(); assembly { $.slot := slot } } } // File @openzeppelin/contracts/utils/cryptography/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.20; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS } /** * @dev The signature derives the `address(0)`. */ error ECDSAInvalidSignature(); /** * @dev The signature has an invalid length. */ error ECDSAInvalidSignatureLength(uint256 length); /** * @dev The signature has an S value that is in the upper half order. */ error ECDSAInvalidSignatureS(bytes32 s); /** * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not * return address(0) without also returning an error description. Errors are documented using an enum (error type) * and a bytes32 providing additional information about the error. * * If no error is returned, then the address can be used for verification purposes. * * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] */ function tryRecover( bytes32 hash, bytes memory signature ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly ("memory-safe") { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length)); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[ERC-2098 short signatures] */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) { unchecked { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); // We do not check for an overflow here since the shift operation results in 0 or 1. uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS, s); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature, bytes32(0)); } return (signer, RecoverError.NoError, bytes32(0)); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s); _throwError(error, errorArg); return recovered; } /** * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. */ function _throwError(RecoverError error, bytes32 errorArg) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert ECDSAInvalidSignature(); } else if (error == RecoverError.InvalidSignatureLength) { revert ECDSAInvalidSignatureLength(uint256(errorArg)); } else if (error == RecoverError.InvalidSignatureS) { revert ECDSAInvalidSignatureS(errorArg); } } } // File contracts/SmartAccount.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.8.20; /** * @title SmartAccount * @notice Account abstraction contract with meta-transaction support * @dev Owned by an EOA, enables gasless transactions via meta-tx relay * Compatible with EIP-1167 minimal proxy pattern for gas-efficient deployment */ contract SmartAccount is Initializable { using ECDSA for bytes32; using MessageHashUtils for bytes32; using SafeERC20 for IERC20; address public owner; uint256 public nonce; event MetaTransactionExecuted( address indexed target, uint256 value, bytes data, uint256 nonce ); event USDCSent(address indexed token, address indexed to, uint256 amount); event VaultDeposit(address indexed vault, address indexed token, uint256 amount); event VaultWithdrawal(address indexed vault, uint256 shares); modifier onlySelfOrOwner() { require( msg.sender == owner || msg.sender == address(this), "SmartAccount: caller is not owner or self" ); _; } /** * @notice Initialize the SmartAccount (replaces constructor for clones) * @param _owner The EOA that will own this SmartAccount * @dev Can only be called once. Protected by OpenZeppelin's Initializable * Gas fees are automatically attributed to the SmartAccountFactory (FeeM Project ID: 237) */ function initialize(address _owner) external initializer { require(_owner != address(0), "SmartAccount: owner cannot be zero address"); owner = _owner; } /** * @notice Execute a meta-transaction signed by the owner * @param target The contract to call * @param value The ETH value to send * @param data The calldata * @param _nonce The transaction nonce * @param signature The owner's signature */ function executeMetaTransaction( address target, uint256 value, bytes calldata data, uint256 _nonce, bytes calldata signature ) external returns (bytes memory) { require(_nonce == nonce, "SmartAccount: invalid nonce"); // Use abi.encode (not encodePacked) to prevent collision attacks bytes32 metaHash = keccak256( abi.encode(block.chainid, address(this), target, value, data, _nonce) ); // Recover signer from signature bytes32 ethSignedHash = metaHash.toEthSignedMessageHash(); address signer = ethSignedHash.recover(signature); require(signer == owner, "SmartAccount: invalid signature"); // Increment nonce to prevent replay nonce++; // Execute the call (bool success, bytes memory returnData) = target.call{value: value}(data); require(success, "SmartAccount: execution failed"); emit MetaTransactionExecuted(target, value, data, _nonce); return returnData; } /** * @notice Send USDC to another address * @param token The USDC token address * @param to The recipient address * @param amount The amount to send */ function sendUSDC(address token, address to, uint256 amount) external onlySelfOrOwner { require(to != address(0), "SmartAccount: recipient cannot be zero address"); require(amount > 0, "SmartAccount: amount must be greater than zero"); IERC20(token).safeTransfer(to, amount); emit USDCSent(token, to, amount); } /** * @notice Deposit USDC into personal yield vault * @param vault The PersonalVault contract address * @param token The USDC token address * @param amount The amount to deposit */ function depositToVault(address vault, address token, uint256 amount) external onlySelfOrOwner { require(vault != address(0), "SmartAccount: vault cannot be zero address"); require(amount > 0, "SmartAccount: amount must be greater than zero"); // Use SafeERC20 for approval IERC20(token).safeIncreaseAllowance(vault, amount); // Call PersonalVault.deposit(uint256) - no receiver param needed (bool success, ) = vault.call( abi.encodeWithSignature("deposit(uint256)", amount) ); require(success, "SmartAccount: vault deposit failed"); emit VaultDeposit(vault, token, amount); } /** * @notice Withdraw from personal yield vault * @param vault The PersonalVault contract address * @param assets The amount of USDC to withdraw */ function withdrawFromVault(address vault, uint256 assets) external onlySelfOrOwner { require(vault != address(0), "SmartAccount: vault cannot be zero address"); require(assets > 0, "SmartAccount: assets must be greater than zero"); // Call PersonalVault.withdraw(uint256) - returns to owner automatically (bool success, ) = vault.call( abi.encodeWithSignature("withdraw(uint256)", assets) ); require(success, "SmartAccount: vault withdrawal failed"); emit VaultWithdrawal(vault, assets); } /** * @notice Allow receiving ETH (for gas refunds if needed) */ receive() external payable {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"MetaTransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"USDCSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"VaultDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"VaultWithdrawal","type":"event"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositToVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"executeMetaTransaction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sendUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"withdrawFromVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
608060405234801561001057600080fd5b50611333806100206000396000f3fe6080604052600436106100745760003560e01c80635fd1c4791161004e5780635fd1c479146100e25780638da5cb5b14610118578063affed0e014610150578063c4d66de81461017457600080fd5b806312e8a7d11461008057806317536c06146100a257806321116f4e146100c257600080fd5b3661007b57005b600080fd5b34801561008c57600080fd5b506100a061009b366004610f21565b610194565b005b3480156100ae57600080fd5b506100a06100bd366004610f21565b6102c4565b3480156100ce57600080fd5b506100a06100dd366004610f5d565b610497565b3480156100ee57600080fd5b506101026100fd366004610fd0565b610695565b60405161010f9190611088565b60405180910390f35b34801561012457600080fd5b50600054610138906001600160a01b031681565b6040516001600160a01b03909116815260200161010f565b34801561015c57600080fd5b5061016660015481565b60405190815260200161010f565b34801561018057600080fd5b506100a061018f3660046110bb565b61091c565b6000546001600160a01b03163314806101ac57503330145b6101d15760405162461bcd60e51b81526004016101c8906110dd565b60405180910390fd5b6001600160a01b03821661023e5760405162461bcd60e51b815260206004820152602e60248201527f536d6172744163636f756e743a20726563697069656e742063616e6e6f74206260448201526d65207a65726f206164647265737360901b60648201526084016101c8565b6000811161025e5760405162461bcd60e51b81526004016101c890611126565b6102726001600160a01b0384168383610a93565b816001600160a01b0316836001600160a01b03167f76e661a0800dc2b12fd758ee382f17fc185be09116169277c1db96695ff6b60c836040516102b791815260200190565b60405180910390a3505050565b6000546001600160a01b03163314806102dc57503330145b6102f85760405162461bcd60e51b81526004016101c8906110dd565b6001600160a01b03831661031e5760405162461bcd60e51b81526004016101c890611174565b6000811161033e5760405162461bcd60e51b81526004016101c890611126565b6103526001600160a01b0383168483610af7565b6000836001600160a01b03168260405160240161037191815260200190565b60408051601f198184030181529181526020820180516001600160e01b031663b6b55f2560e01b179052516103a691906111be565b6000604051808303816000865af19150503d80600081146103e3576040519150601f19603f3d011682016040523d82523d6000602084013e6103e8565b606091505b50509050806104445760405162461bcd60e51b815260206004820152602260248201527f536d6172744163636f756e743a207661756c74206465706f736974206661696c604482015261195960f21b60648201526084016101c8565b826001600160a01b0316846001600160a01b03167f2790b90165fd3973ad7edde4eca71b4f8808dd4857a2a3a3e8ae5642a5cb196e8460405161048991815260200190565b60405180910390a350505050565b6000546001600160a01b03163314806104af57503330145b6104cb5760405162461bcd60e51b81526004016101c8906110dd565b6001600160a01b0382166104f15760405162461bcd60e51b81526004016101c890611174565b600081116105585760405162461bcd60e51b815260206004820152602e60248201527f536d6172744163636f756e743a20617373657473206d7573742062652067726560448201526d61746572207468616e207a65726f60901b60648201526084016101c8565b6000826001600160a01b03168260405160240161057791815260200190565b60408051601f198184030181529181526020820180516001600160e01b0316632e1a7d4d60e01b179052516105ac91906111be565b6000604051808303816000865af19150503d80600081146105e9576040519150601f19603f3d011682016040523d82523d6000602084013e6105ee565b606091505b505090508061064d5760405162461bcd60e51b815260206004820152602560248201527f536d6172744163636f756e743a207661756c74207769746864726177616c2066604482015264185a5b195960da1b60648201526084016101c8565b826001600160a01b03167f26bdf3842d5a4f022330c79f37ffefb624f92f807079cd0324ca8e186a46401a8360405161068891815260200190565b60405180910390a2505050565b606060015484146106e85760405162461bcd60e51b815260206004820152601b60248201527f536d6172744163636f756e743a20696e76616c6964206e6f6e6365000000000060448201526064016101c8565b600046308a8a8a8a8a6040516020016107079796959493929190611203565b6040516020818303038152906040528051906020012090506000610758827f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b9050600061079e86868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508693925050610b879050565b6000549091506001600160a01b038083169116146107fe5760405162461bcd60e51b815260206004820152601f60248201527f536d6172744163636f756e743a20696e76616c6964207369676e61747572650060448201526064016101c8565b6001805490600061080e83611267565b91905055506000808c6001600160a01b03168c8c8c604051610831929190611280565b60006040518083038185875af1925050503d806000811461086e576040519150601f19603f3d011682016040523d82523d6000602084013e610873565b606091505b5091509150816108c55760405162461bcd60e51b815260206004820152601e60248201527f536d6172744163636f756e743a20657865637574696f6e206661696c6564000060448201526064016101c8565b8c6001600160a01b03167f0cd3c523ff1d2e61faa984c46db61c16fa7cd69c429baee4cfd8570685627c778d8d8d8d6040516109049493929190611290565b60405180910390a29c9b505050505050505050505050565b6000610926610bb3565b805490915060ff600160401b820416159067ffffffffffffffff1660008115801561094e5750825b905060008267ffffffffffffffff16600114801561096b5750303b155b905081158015610979575080155b156109975760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156109c157845460ff60401b1916600160401b1785555b6001600160a01b038616610a2a5760405162461bcd60e51b815260206004820152602a60248201527f536d6172744163636f756e743a206f776e65722063616e6e6f74206265207a65604482015269726f206164647265737360b01b60648201526084016101c8565b600080546001600160a01b0319166001600160a01b0388161790558315610a8b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b6040516001600160a01b03838116602483015260448201839052610af291859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050610bdc565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015610b47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6b91906112bb565b9050610b818484610b7c85856112d4565b610c4d565b50505050565b600080600080610b978686610cdd565b925092509250610ba78282610d2a565b50909150505b92915050565b6000807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610bad565b600080602060008451602086016000885af180610bff576040513d6000823e3d81fd5b50506000513d91508115610c17578060011415610c24565b6001600160a01b0384163b155b15610b8157604051635274afe760e01b81526001600160a01b03851660048201526024016101c8565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052610c9e8482610de7565b610b81576040516001600160a01b03848116602483015260006044830152610cd391869182169063095ea7b390606401610ac0565b610b818482610bdc565b60008060008351604103610d175760208401516040850151606086015160001a610d0988828585610e36565b955095509550505050610d23565b50508151600091506002905b9250925092565b6000826003811115610d3e57610d3e6112e7565b03610d47575050565b6001826003811115610d5b57610d5b6112e7565b03610d795760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610d8d57610d8d6112e7565b03610dae5760405163fce698f760e01b8152600481018290526024016101c8565b6003826003811115610dc257610dc26112e7565b03610de3576040516335e2f38360e21b8152600481018290526024016101c8565b5050565b6000806000806020600086516020880160008a5af192503d91506000519050828015610e2c57508115610e1d5780600114610e2c565b6000866001600160a01b03163b115b9695505050505050565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610e715750600091506003905082610efb565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610ec5573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610ef157506000925060019150829050610efb565b9250600091508190505b9450945094915050565b80356001600160a01b0381168114610f1c57600080fd5b919050565b600080600060608486031215610f3657600080fd5b610f3f84610f05565b9250610f4d60208501610f05565b9150604084013590509250925092565b60008060408385031215610f7057600080fd5b610f7983610f05565b946020939093013593505050565b60008083601f840112610f9957600080fd5b50813567ffffffffffffffff811115610fb157600080fd5b602083019150836020828501011115610fc957600080fd5b9250929050565b600080600080600080600060a0888a031215610feb57600080fd5b610ff488610f05565b965060208801359550604088013567ffffffffffffffff8082111561101857600080fd5b6110248b838c01610f87565b909750955060608a0135945060808a013591508082111561104457600080fd5b506110518a828b01610f87565b989b979a50959850939692959293505050565b60005b8381101561107f578181015183820152602001611067565b50506000910152565b60208152600082518060208401526110a7816040850160208701611064565b601f01601f19169190910160400192915050565b6000602082840312156110cd57600080fd5b6110d682610f05565b9392505050565b60208082526029908201527f536d6172744163636f756e743a2063616c6c6572206973206e6f74206f776e65604082015268391037b91039b2b63360b91b606082015260800190565b6020808252602e908201527f536d6172744163636f756e743a20616d6f756e74206d7573742062652067726560408201526d61746572207468616e207a65726f60901b606082015260800190565b6020808252602a908201527f536d6172744163636f756e743a207661756c742063616e6e6f74206265207a65604082015269726f206164647265737360b01b606082015260800190565b600082516111d0818460208701611064565b9190910192915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8781526001600160a01b038781166020830152861660408201526060810185905260c06080820181905260009061123d90830185876111da565b90508260a083015298975050505050505050565b634e487b7160e01b600052601160045260246000fd5b60006001820161127957611279611251565b5060010190565b8183823760009101908152919050565b8481526060602082015260006112aa6060830185876111da565b905082604083015295945050505050565b6000602082840312156112cd57600080fd5b5051919050565b80820180821115610bad57610bad611251565b634e487b7160e01b600052602160045260246000fdfea264697066735822122060486fe5138e683b6a5360eb50340e2b42e3d93655747d4b86e15f4310c92fdb64736f6c63430008140033
Deployed Bytecode
0x6080604052600436106100745760003560e01c80635fd1c4791161004e5780635fd1c479146100e25780638da5cb5b14610118578063affed0e014610150578063c4d66de81461017457600080fd5b806312e8a7d11461008057806317536c06146100a257806321116f4e146100c257600080fd5b3661007b57005b600080fd5b34801561008c57600080fd5b506100a061009b366004610f21565b610194565b005b3480156100ae57600080fd5b506100a06100bd366004610f21565b6102c4565b3480156100ce57600080fd5b506100a06100dd366004610f5d565b610497565b3480156100ee57600080fd5b506101026100fd366004610fd0565b610695565b60405161010f9190611088565b60405180910390f35b34801561012457600080fd5b50600054610138906001600160a01b031681565b6040516001600160a01b03909116815260200161010f565b34801561015c57600080fd5b5061016660015481565b60405190815260200161010f565b34801561018057600080fd5b506100a061018f3660046110bb565b61091c565b6000546001600160a01b03163314806101ac57503330145b6101d15760405162461bcd60e51b81526004016101c8906110dd565b60405180910390fd5b6001600160a01b03821661023e5760405162461bcd60e51b815260206004820152602e60248201527f536d6172744163636f756e743a20726563697069656e742063616e6e6f74206260448201526d65207a65726f206164647265737360901b60648201526084016101c8565b6000811161025e5760405162461bcd60e51b81526004016101c890611126565b6102726001600160a01b0384168383610a93565b816001600160a01b0316836001600160a01b03167f76e661a0800dc2b12fd758ee382f17fc185be09116169277c1db96695ff6b60c836040516102b791815260200190565b60405180910390a3505050565b6000546001600160a01b03163314806102dc57503330145b6102f85760405162461bcd60e51b81526004016101c8906110dd565b6001600160a01b03831661031e5760405162461bcd60e51b81526004016101c890611174565b6000811161033e5760405162461bcd60e51b81526004016101c890611126565b6103526001600160a01b0383168483610af7565b6000836001600160a01b03168260405160240161037191815260200190565b60408051601f198184030181529181526020820180516001600160e01b031663b6b55f2560e01b179052516103a691906111be565b6000604051808303816000865af19150503d80600081146103e3576040519150601f19603f3d011682016040523d82523d6000602084013e6103e8565b606091505b50509050806104445760405162461bcd60e51b815260206004820152602260248201527f536d6172744163636f756e743a207661756c74206465706f736974206661696c604482015261195960f21b60648201526084016101c8565b826001600160a01b0316846001600160a01b03167f2790b90165fd3973ad7edde4eca71b4f8808dd4857a2a3a3e8ae5642a5cb196e8460405161048991815260200190565b60405180910390a350505050565b6000546001600160a01b03163314806104af57503330145b6104cb5760405162461bcd60e51b81526004016101c8906110dd565b6001600160a01b0382166104f15760405162461bcd60e51b81526004016101c890611174565b600081116105585760405162461bcd60e51b815260206004820152602e60248201527f536d6172744163636f756e743a20617373657473206d7573742062652067726560448201526d61746572207468616e207a65726f60901b60648201526084016101c8565b6000826001600160a01b03168260405160240161057791815260200190565b60408051601f198184030181529181526020820180516001600160e01b0316632e1a7d4d60e01b179052516105ac91906111be565b6000604051808303816000865af19150503d80600081146105e9576040519150601f19603f3d011682016040523d82523d6000602084013e6105ee565b606091505b505090508061064d5760405162461bcd60e51b815260206004820152602560248201527f536d6172744163636f756e743a207661756c74207769746864726177616c2066604482015264185a5b195960da1b60648201526084016101c8565b826001600160a01b03167f26bdf3842d5a4f022330c79f37ffefb624f92f807079cd0324ca8e186a46401a8360405161068891815260200190565b60405180910390a2505050565b606060015484146106e85760405162461bcd60e51b815260206004820152601b60248201527f536d6172744163636f756e743a20696e76616c6964206e6f6e6365000000000060448201526064016101c8565b600046308a8a8a8a8a6040516020016107079796959493929190611203565b6040516020818303038152906040528051906020012090506000610758827f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b9050600061079e86868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508693925050610b879050565b6000549091506001600160a01b038083169116146107fe5760405162461bcd60e51b815260206004820152601f60248201527f536d6172744163636f756e743a20696e76616c6964207369676e61747572650060448201526064016101c8565b6001805490600061080e83611267565b91905055506000808c6001600160a01b03168c8c8c604051610831929190611280565b60006040518083038185875af1925050503d806000811461086e576040519150601f19603f3d011682016040523d82523d6000602084013e610873565b606091505b5091509150816108c55760405162461bcd60e51b815260206004820152601e60248201527f536d6172744163636f756e743a20657865637574696f6e206661696c6564000060448201526064016101c8565b8c6001600160a01b03167f0cd3c523ff1d2e61faa984c46db61c16fa7cd69c429baee4cfd8570685627c778d8d8d8d6040516109049493929190611290565b60405180910390a29c9b505050505050505050505050565b6000610926610bb3565b805490915060ff600160401b820416159067ffffffffffffffff1660008115801561094e5750825b905060008267ffffffffffffffff16600114801561096b5750303b155b905081158015610979575080155b156109975760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156109c157845460ff60401b1916600160401b1785555b6001600160a01b038616610a2a5760405162461bcd60e51b815260206004820152602a60248201527f536d6172744163636f756e743a206f776e65722063616e6e6f74206265207a65604482015269726f206164647265737360b01b60648201526084016101c8565b600080546001600160a01b0319166001600160a01b0388161790558315610a8b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b6040516001600160a01b03838116602483015260448201839052610af291859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050610bdc565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015610b47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6b91906112bb565b9050610b818484610b7c85856112d4565b610c4d565b50505050565b600080600080610b978686610cdd565b925092509250610ba78282610d2a565b50909150505b92915050565b6000807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610bad565b600080602060008451602086016000885af180610bff576040513d6000823e3d81fd5b50506000513d91508115610c17578060011415610c24565b6001600160a01b0384163b155b15610b8157604051635274afe760e01b81526001600160a01b03851660048201526024016101c8565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052610c9e8482610de7565b610b81576040516001600160a01b03848116602483015260006044830152610cd391869182169063095ea7b390606401610ac0565b610b818482610bdc565b60008060008351604103610d175760208401516040850151606086015160001a610d0988828585610e36565b955095509550505050610d23565b50508151600091506002905b9250925092565b6000826003811115610d3e57610d3e6112e7565b03610d47575050565b6001826003811115610d5b57610d5b6112e7565b03610d795760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610d8d57610d8d6112e7565b03610dae5760405163fce698f760e01b8152600481018290526024016101c8565b6003826003811115610dc257610dc26112e7565b03610de3576040516335e2f38360e21b8152600481018290526024016101c8565b5050565b6000806000806020600086516020880160008a5af192503d91506000519050828015610e2c57508115610e1d5780600114610e2c565b6000866001600160a01b03163b115b9695505050505050565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610e715750600091506003905082610efb565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610ec5573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610ef157506000925060019150829050610efb565b9250600091508190505b9450945094915050565b80356001600160a01b0381168114610f1c57600080fd5b919050565b600080600060608486031215610f3657600080fd5b610f3f84610f05565b9250610f4d60208501610f05565b9150604084013590509250925092565b60008060408385031215610f7057600080fd5b610f7983610f05565b946020939093013593505050565b60008083601f840112610f9957600080fd5b50813567ffffffffffffffff811115610fb157600080fd5b602083019150836020828501011115610fc957600080fd5b9250929050565b600080600080600080600060a0888a031215610feb57600080fd5b610ff488610f05565b965060208801359550604088013567ffffffffffffffff8082111561101857600080fd5b6110248b838c01610f87565b909750955060608a0135945060808a013591508082111561104457600080fd5b506110518a828b01610f87565b989b979a50959850939692959293505050565b60005b8381101561107f578181015183820152602001611067565b50506000910152565b60208152600082518060208401526110a7816040850160208701611064565b601f01601f19169190910160400192915050565b6000602082840312156110cd57600080fd5b6110d682610f05565b9392505050565b60208082526029908201527f536d6172744163636f756e743a2063616c6c6572206973206e6f74206f776e65604082015268391037b91039b2b63360b91b606082015260800190565b6020808252602e908201527f536d6172744163636f756e743a20616d6f756e74206d7573742062652067726560408201526d61746572207468616e207a65726f60901b606082015260800190565b6020808252602a908201527f536d6172744163636f756e743a207661756c742063616e6e6f74206265207a65604082015269726f206164647265737360b01b606082015260800190565b600082516111d0818460208701611064565b9190910192915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8781526001600160a01b038781166020830152861660408201526060810185905260c06080820181905260009061123d90830185876111da565b90508260a083015298975050505050505050565b634e487b7160e01b600052601160045260246000fd5b60006001820161127957611279611251565b5060010190565b8183823760009101908152919050565b8481526060602082015260006112aa6060830185876111da565b905082604083015295945050505050565b6000602082840312156112cd57600080fd5b5051919050565b80820180821115610bad57610bad611251565b634e487b7160e01b600052602160045260246000fdfea264697066735822122060486fe5138e683b6a5360eb50340e2b42e3d93655747d4b86e15f4310c92fdb64736f6c63430008140033
Deployed Bytecode Sourcemap
135460:5043:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;138359:356;;;;;;;;;;-1:-1:-1;138359:356:0;;;;;:::i;:::-;;:::i;:::-;;138940:681;;;;;;;;;;-1:-1:-1;138940:681:0;;;;;:::i;:::-;;:::i;139807:574::-;;;;;;;;;;-1:-1:-1;139807:574:0;;;;;:::i;:::-;;:::i;137082:1081::-;;;;;;;;;;-1:-1:-1;137082:1081:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135612:20;;;;;;;;;;-1:-1:-1;135612:20:0;;;;-1:-1:-1;;;;;135612:20:0;;;;;;-1:-1:-1;;;;;2888:32:1;;;2870:51;;2858:2;2843:18;135612:20:0;2724:203:1;135639:20:0;;;;;;;;;;;;;;;;;;;3078:25:1;;;3066:2;3051:18;135639:20:0;2932:177:1;136597:186:0;;;;;;;;;;-1:-1:-1;136597:186:0;;;;;:::i;:::-;;:::i;138359:356::-;136125:5;;-1:-1:-1;;;;;136125:5:0;136111:10;:19;;:50;;-1:-1:-1;136134:10:0;136156:4;136134:27;136111:50;136089:141;;;;-1:-1:-1;;;136089:141:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;138464:16:0;::::1;138456:75;;;::::0;-1:-1:-1;;;138456:75:0;;3917:2:1;138456:75:0::1;::::0;::::1;3899:21:1::0;3956:2;3936:18;;;3929:30;3995:34;3975:18;;;3968:62;-1:-1:-1;;;4046:18:1;;;4039:44;4100:19;;138456:75:0::1;3715:410:1::0;138456:75:0::1;138559:1;138550:6;:10;138542:69;;;;-1:-1:-1::0;;;138542:69:0::1;;;;;;;:::i;:::-;138624:38;-1:-1:-1::0;;;;;138624:26:0;::::1;138651:2:::0;138655:6;138624:26:::1;:38::i;:::-;138696:2;-1:-1:-1::0;;;;;138680:27:0::1;138689:5;-1:-1:-1::0;;;;;138680:27:0::1;;138700:6;138680:27;;;;3078:25:1::0;;3066:2;3051:18;;2932:177;138680:27:0::1;;;;;;;;138359:356:::0;;;:::o;138940:681::-;136125:5;;-1:-1:-1;;;;;136125:5:0;136111:10;:19;;:50;;-1:-1:-1;136134:10:0;136156:4;136134:27;136111:50;136089:141;;;;-1:-1:-1;;;136089:141:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;139054:19:0;::::1;139046:74;;;;-1:-1:-1::0;;;139046:74:0::1;;;;;;;:::i;:::-;139148:1;139139:6;:10;139131:69;;;;-1:-1:-1::0;;;139131:69:0::1;;;;;;;:::i;:::-;139252:50;-1:-1:-1::0;;;;;139252:35:0;::::1;139288:5:::0;139295:6;139252:35:::1;:50::i;:::-;139391:12;139409:5;-1:-1:-1::0;;;;;139409:10:0::1;139478:6;139434:51;;;;;;3078:25:1::0;;3066:2;3051:18;;2932:177;139434:51:0::1;;::::0;;-1:-1:-1;;139434:51:0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;139434:51:0::1;-1:-1:-1::0;;;139434:51:0::1;::::0;;139409:87;::::1;::::0;139434:51;139409:87:::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;139390:106;;;139515:7;139507:54;;;::::0;-1:-1:-1;;;139507:54:0;;5450:2:1;139507:54:0::1;::::0;::::1;5432:21:1::0;5489:2;5469:18;;;5462:30;5528:34;5508:18;;;5501:62;-1:-1:-1;;;5579:18:1;;;5572:32;5621:19;;139507:54:0::1;5248:398:1::0;139507:54:0::1;139599:5;-1:-1:-1::0;;;;;139579:34:0::1;139592:5;-1:-1:-1::0;;;;;139579:34:0::1;;139606:6;139579:34;;;;3078:25:1::0;;3066:2;3051:18;;2932:177;139579:34:0::1;;;;;;;;139035:586;138940:681:::0;;;:::o;139807:574::-;136125:5;;-1:-1:-1;;;;;136125:5:0;136111:10;:19;;:50;;-1:-1:-1;136134:10:0;136156:4;136134:27;136111:50;136089:141;;;;-1:-1:-1;;;136089:141:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;139909:19:0;::::1;139901:74;;;;-1:-1:-1::0;;;139901:74:0::1;;;;;;;:::i;:::-;140003:1;139994:6;:10;139986:69;;;::::0;-1:-1:-1;;;139986:69:0;;5853:2:1;139986:69:0::1;::::0;::::1;5835:21:1::0;5892:2;5872:18;;;5865:30;5931:34;5911:18;;;5904:62;-1:-1:-1;;;5982:18:1;;;5975:44;6036:19;;139986:69:0::1;5651:410:1::0;139986:69:0::1;140151:12;140169:5;-1:-1:-1::0;;;;;140169:10:0::1;140239:6;140194:52;;;;;;3078:25:1::0;;3066:2;3051:18;;2932:177;140194:52:0::1;;::::0;;-1:-1:-1;;140194:52:0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;140194:52:0::1;-1:-1:-1::0;;;140194:52:0::1;::::0;;140169:88;::::1;::::0;140194:52;140169:88:::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;140150:107;;;140276:7;140268:57;;;::::0;-1:-1:-1;;;140268:57:0;;6268:2:1;140268:57:0::1;::::0;::::1;6250:21:1::0;6307:2;6287:18;;;6280:30;6346:34;6326:18;;;6319:62;-1:-1:-1;;;6397:18:1;;;6390:35;6442:19;;140268:57:0::1;6066:401:1::0;140268:57:0::1;140359:5;-1:-1:-1::0;;;;;140343:30:0::1;;140366:6;140343:30;;;;3078:25:1::0;;3066:2;3051:18;;2932:177;140343:30:0::1;;;;;;;;139890:491;139807:574:::0;;:::o;137082:1081::-;137278:12;137321:5;;137311:6;:15;137303:55;;;;-1:-1:-1;;;137303:55:0;;6674:2:1;137303:55:0;;;6656:21:1;6713:2;6693:18;;;6686:30;6752:29;6732:18;;;6725:57;6799:18;;137303:55:0;6472:351:1;137303:55:0;137446:16;137500:13;137523:4;137530:6;137538:5;137545:4;;137551:6;137489:69;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;137465:104;;;;;;137446:123;;137624:21;137648:33;:8;114452:34;114372:14;114439:48;;;114549:4;114542:25;;;;114648:4;114632:21;;;114296:439;137648:33;137624:57;;137692:14;137709:32;137731:9;;137709:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;137709:13:0;;:32;-1:-1:-1;;137709:21:0;:32;-1:-1:-1;137709:32:0:i;:::-;137772:5;;137692:49;;-1:-1:-1;;;;;;137762:15:0;;;137772:5;;137762:15;137754:59;;;;-1:-1:-1;;;137754:59:0;;7965:2:1;137754:59:0;;;7947:21:1;8004:2;7984:18;;;7977:30;8043:33;8023:18;;;8016:61;8094:18;;137754:59:0;7763:355:1;137754:59:0;137872:5;:7;;;:5;:7;;;:::i;:::-;;;;;;137922:12;137936:23;137963:6;-1:-1:-1;;;;;137963:11:0;137982:5;137989:4;;137963:31;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;137921:73;;;;138013:7;138005:50;;;;-1:-1:-1;;;138005:50:0;;8873:2:1;138005:50:0;;;8855:21:1;8912:2;8892:18;;;8885:30;8951:32;8931:18;;;8924:60;9001:18;;138005:50:0;8671:354:1;138005:50:0;138097:6;-1:-1:-1;;;;;138073:52:0;;138105:5;138112:4;;138118:6;138073:52;;;;;;;;;:::i;:::-;;;;;;;;138145:10;137082:1081;-1:-1:-1;;;;;;;;;;;;137082:1081:0:o;136597:186::-;121727:30;121760:26;:24;:26::i;:::-;121874:15;;121727:59;;-1:-1:-1;121874:15:0;-1:-1:-1;;;121874:15:0;;;121873:16;;121921:14;;121851:19;122304:16;;:34;;;;;122324:14;122304:34;122284:54;;122349:17;122369:11;:16;;122384:1;122369:16;:50;;;;-1:-1:-1;122397:4:0;122389:25;:30;122369:50;122349:70;;122437:12;122436:13;:30;;;;;122454:12;122453:13;122436:30;122432:93;;;122490:23;;-1:-1:-1;;;122490:23:0;;;;;;;;;;;122432:93;122535:18;;-1:-1:-1;;122535:18:0;122552:1;122535:18;;;122564:69;;;;122599:22;;-1:-1:-1;;;;122599:22:0;-1:-1:-1;;;122599:22:0;;;122564:69;-1:-1:-1;;;;;136673:20:0;::::1;136665:75;;;::::0;-1:-1:-1;;;136665:75:0;;9623:2:1;136665:75:0::1;::::0;::::1;9605:21:1::0;9662:2;9642:18;;;9635:30;9701:34;9681:18;;;9674:62;-1:-1:-1;;;9752:18:1;;;9745:40;9802:19;;136665:75:0::1;9421:406:1::0;136665:75:0::1;136761:5;:14:::0;;-1:-1:-1;;;;;;136761:14:0::1;-1:-1:-1::0;;;;;136761:14:0;::::1;;::::0;;122655:104;;;;122690:23;;-1:-1:-1;;;;122690:23:0;;;122733:14;;-1:-1:-1;9985:50:1;;122733:14:0;;9973:2:1;9958:18;122733:14:0;;;;;;;122655:104;121659:1107;;;;;136597:186;:::o;10277:162::-;10387:43;;-1:-1:-1;;;;;10238:32:1;;;10387:43:0;;;10220:51:1;10287:18;;;10280:34;;;10360:71:0;;10380:5;;10402:14;;;;;10193:18:1;;10387:43:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10387:43:0;;;;;;;;;;;10360:19;:71::i;:::-;10277:162;;;:::o;12239:228::-;12359:39;;-1:-1:-1;;;12359:39:0;;12383:4;12359:39;;;10537:34:1;-1:-1:-1;;;;;10607:15:1;;;10587:18;;;10580:43;12336:20:0;;12359:15;;;;;;10472:18:1;;12359:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12336:62;-1:-1:-1;12409:50:0;12422:5;12429:7;12438:20;12453:5;12336:62;12438:20;:::i;:::-;12409:12;:50::i;:::-;12325:142;12239:228;;;:::o;130878:259::-;130956:7;130977:17;130996:18;131016:16;131036:27;131047:4;131053:9;131036:10;:27::i;:::-;130976:87;;;;;;131074:28;131086:5;131093:8;131074:11;:28::i;:::-;-1:-1:-1;131120:9:0;;-1:-1:-1;;130878:259:0;;;;;:::o;126766:210::-;126824:30;;120687:66;126882:27;126506:124;17568:738;17649:18;17678:19;17818:4;17815:1;17808:4;17802:11;17795:4;17789;17785:15;17782:1;17775:5;17768;17763:60;17877:7;17867:180;;17922:4;17916:11;17968:16;17965:1;17960:3;17945:40;18015:16;18010:3;18003:29;17867:180;-1:-1:-1;;18126:1:0;18120:8;18075:16;;-1:-1:-1;18155:15:0;;:68;;18207:11;18222:1;18207:16;;18155:68;;;-1:-1:-1;;;;;18173:26:0;;;:31;18155:68;18151:148;;;18247:40;;-1:-1:-1;;;18247:40:0;;-1:-1:-1;;;;;2888:32:1;;18247:40:0;;;2870:51:1;2843:18;;18247:40:0;2724:203:1;14210:387:0;14326:47;;;-1:-1:-1;;;;;10238:32:1;;14326:47:0;;;10220:51:1;10287:18;;;;10280:34;;;14326:47:0;;;;;;;;;;10193:18:1;;;;14326:47:0;;;;;;;;-1:-1:-1;;;;;14326:47:0;-1:-1:-1;;;14326:47:0;;;14391:44;14341:13;14326:47;14391:23;:44::i;:::-;14386:204;;14479:43;;-1:-1:-1;;;;;10238:32:1;;;14479:43:0;;;10220:51:1;14519:1:0;10287:18:1;;;10280:34;14452:71:0;;14472:5;;14494:13;;;;;10193:18:1;;14479:43:0;10046:274:1;14452:71:0;14538:40;14558:5;14565:12;14538:19;:40::i;129258:797::-;129364:17;129383:16;129401:14;129432:9;:16;129452:2;129432:22;129428:620;;129744:4;129729:20;;129723:27;129794:4;129779:20;;129773:27;129852:4;129837:20;;129831:27;129471:9;129823:36;129895:25;129906:4;129823:36;129723:27;129773;129895:10;:25::i;:::-;129888:32;;;;;;;;;;;129428:620;-1:-1:-1;;130018:16:0;;129969:1;;-1:-1:-1;129973:35:0;;129428:620;129258:797;;;;;:::o;134522:542::-;134618:20;134609:5;:29;;;;;;;;:::i;:::-;;134605:452;;134522:542;;:::o;134605:452::-;134716:29;134707:5;:38;;;;;;;;:::i;:::-;;134703:354;;134769:23;;-1:-1:-1;;;134769:23:0;;;;;;;;;;;134703:354;134823:35;134814:5;:44;;;;;;;;:::i;:::-;;134810:247;;134882:46;;-1:-1:-1;;;134882:46:0;;;;;3078:25:1;;;3051:18;;134882:46:0;2932:177:1;134810:247:0;134959:30;134950:5;:39;;;;;;;;:::i;:::-;;134946:111;;135013:32;;-1:-1:-1;;;135013:32:0;;;;;3078:25:1;;;3051:18;;135013:32:0;2932:177:1;134946:111:0;134522:542;;:::o;18818:490::-;18901:4;18918:12;18941:18;18970:19;19106:4;19103:1;19096:4;19090:11;19083:4;19077;19073:15;19070:1;19063:5;19056;19051:60;19040:71;;19139:16;19125:30;;19190:1;19184:8;19169:23;;19220:7;:80;;;;-1:-1:-1;19232:15:0;;:67;;19283:11;19298:1;19283:16;19232:67;;;19279:1;19258:5;-1:-1:-1;;;;;19250:26:0;;:30;19232:67;19213:87;18818:490;-1:-1:-1;;;;;;18818:490:0:o;132404:1577::-;132535:17;;;133499:66;133486:79;;133482:166;;;-1:-1:-1;133598:1:0;;-1:-1:-1;133602:30:0;;-1:-1:-1;133634:1:0;133582:54;;133482:166;133762:24;;;133745:14;133762:24;;;;;;;;;11781:25:1;;;11854:4;11842:17;;11822:18;;;11815:45;;;;11876:18;;;11869:34;;;11919:18;;;11912:34;;;133762:24:0;;11753:19:1;;133762:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;133762:24:0;;-1:-1:-1;;133762:24:0;;;-1:-1:-1;;;;;;;133801:20:0;;133797:115;;-1:-1:-1;133854:1:0;;-1:-1:-1;133858:29:0;;-1:-1:-1;133854:1:0;;-1:-1:-1;133838:62:0;;133797:115;133932:6;-1:-1:-1;133940:20:0;;-1:-1:-1;133940:20:0;;-1:-1:-1;132404:1577:0;;;;;;;;;:::o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:328::-;269:6;277;285;338:2;326:9;317:7;313:23;309:32;306:52;;;354:1;351;344:12;306:52;377:29;396:9;377:29;:::i;:::-;367:39;;425:38;459:2;448:9;444:18;425:38;:::i;:::-;415:48;;510:2;499:9;495:18;482:32;472:42;;192:328;;;;;:::o;525:254::-;593:6;601;654:2;642:9;633:7;629:23;625:32;622:52;;;670:1;667;660:12;622:52;693:29;712:9;693:29;:::i;:::-;683:39;769:2;754:18;;;;741:32;;-1:-1:-1;;;525:254:1:o;784:347::-;835:8;845:6;899:3;892:4;884:6;880:17;876:27;866:55;;917:1;914;907:12;866:55;-1:-1:-1;940:20:1;;983:18;972:30;;969:50;;;1015:1;1012;1005:12;969:50;1052:4;1044:6;1040:17;1028:29;;1104:3;1097:4;1088:6;1080;1076:19;1072:30;1069:39;1066:59;;;1121:1;1118;1111:12;1066:59;784:347;;;;;:::o;1136:929::-;1253:6;1261;1269;1277;1285;1293;1301;1354:3;1342:9;1333:7;1329:23;1325:33;1322:53;;;1371:1;1368;1361:12;1322:53;1394:29;1413:9;1394:29;:::i;:::-;1384:39;;1470:2;1459:9;1455:18;1442:32;1432:42;;1525:2;1514:9;1510:18;1497:32;1548:18;1589:2;1581:6;1578:14;1575:34;;;1605:1;1602;1595:12;1575:34;1644:58;1694:7;1685:6;1674:9;1670:22;1644:58;:::i;:::-;1721:8;;-1:-1:-1;1618:84:1;-1:-1:-1;1803:2:1;1788:18;;1775:32;;-1:-1:-1;1860:3:1;1845:19;;1832:33;;-1:-1:-1;1877:16:1;;;1874:36;;;1906:1;1903;1896:12;1874:36;;1945:60;1997:7;1986:8;1975:9;1971:24;1945:60;:::i;:::-;1136:929;;;;-1:-1:-1;1136:929:1;;-1:-1:-1;1136:929:1;;;;1919:86;;-1:-1:-1;;;1136:929:1:o;2070:250::-;2155:1;2165:113;2179:6;2176:1;2173:13;2165:113;;;2255:11;;;2249:18;2236:11;;;2229:39;2201:2;2194:10;2165:113;;;-1:-1:-1;;2312:1:1;2294:16;;2287:27;2070:250::o;2325:394::-;2472:2;2461:9;2454:21;2435:4;2504:6;2498:13;2547:6;2542:2;2531:9;2527:18;2520:34;2563:79;2635:6;2630:2;2619:9;2615:18;2610:2;2602:6;2598:15;2563:79;:::i;:::-;2703:2;2682:15;-1:-1:-1;;2678:29:1;2663:45;;;;2710:2;2659:54;;2325:394;-1:-1:-1;;2325:394:1:o;3114:186::-;3173:6;3226:2;3214:9;3205:7;3201:23;3197:32;3194:52;;;3242:1;3239;3232:12;3194:52;3265:29;3284:9;3265:29;:::i;:::-;3255:39;3114:186;-1:-1:-1;;;3114:186:1:o;3305:405::-;3507:2;3489:21;;;3546:2;3526:18;;;3519:30;3585:34;3580:2;3565:18;;3558:62;-1:-1:-1;;;3651:2:1;3636:18;;3629:39;3700:3;3685:19;;3305:405::o;4130:410::-;4332:2;4314:21;;;4371:2;4351:18;;;4344:30;4410:34;4405:2;4390:18;;4383:62;-1:-1:-1;;;4476:2:1;4461:18;;4454:44;4530:3;4515:19;;4130:410::o;4545:406::-;4747:2;4729:21;;;4786:2;4766:18;;;4759:30;4825:34;4820:2;4805:18;;4798:62;-1:-1:-1;;;4891:2:1;4876:18;;4869:40;4941:3;4926:19;;4545:406::o;4956:287::-;5085:3;5123:6;5117:13;5139:66;5198:6;5193:3;5186:4;5178:6;5174:17;5139:66;:::i;:::-;5221:16;;;;;4956:287;-1:-1:-1;;4956:287:1:o;6828:266::-;6916:6;6911:3;6904:19;6968:6;6961:5;6954:4;6949:3;6945:14;6932:43;-1:-1:-1;7020:1:1;6995:16;;;7013:4;6991:27;;;6984:38;;;;7076:2;7055:15;;;-1:-1:-1;;7051:29:1;7042:39;;;7038:50;;6828:266::o;7099:659::-;7378:25;;;-1:-1:-1;;;;;7477:15:1;;;7472:2;7457:18;;7450:43;7529:15;;7524:2;7509:18;;7502:43;7576:2;7561:18;;7554:34;;;7625:3;7619;7604:19;;7597:32;;;7359:4;;7646:62;;7688:19;;7680:6;7672;7646:62;:::i;:::-;7638:70;;7745:6;7739:3;7728:9;7724:19;7717:35;7099:659;;;;;;;;;;:::o;8123:127::-;8184:10;8179:3;8175:20;8172:1;8165:31;8215:4;8212:1;8205:15;8239:4;8236:1;8229:15;8255:135;8294:3;8315:17;;;8312:43;;8335:18;;:::i;:::-;-1:-1:-1;8382:1:1;8371:13;;8255:135::o;8395:271::-;8578:6;8570;8565:3;8552:33;8534:3;8604:16;;8629:13;;;8604:16;8395:271;-1:-1:-1;8395:271:1:o;9030:386::-;9243:6;9232:9;9225:25;9286:2;9281;9270:9;9266:18;9259:30;9206:4;9306:61;9363:2;9352:9;9348:18;9340:6;9332;9306:61;:::i;:::-;9298:69;;9403:6;9398:2;9387:9;9383:18;9376:34;9030:386;;;;;;;:::o;10634:184::-;10704:6;10757:2;10745:9;10736:7;10732:23;10728:32;10725:52;;;10773:1;10770;10763:12;10725:52;-1:-1:-1;10796:16:1;;10634:184;-1:-1:-1;10634:184:1:o;10823:125::-;10888:9;;;10909:10;;;10906:36;;;10922:18;;:::i;11240:127::-;11301:10;11296:3;11292:20;11289:1;11282:31;11332:4;11329:1;11322:15;11356:4;11353:1;11346:15
Swarm Source
ipfs://60486fe5138e683b6a5360eb50340e2b42e3d93655747d4b86e15f4310c92fdb
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in S
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.