Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x1c359d3954812E39489eb0D887757aDaBb12E6D8
Balance 0 ETH
Nonce 1
Code Size 4633 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

4633 bytes
0x608060405234801561001057600080fd5b50600436106100df5760003560e01c80636e773eb81161008c578063c3c9f76f11610066578063c3c9f76f14610200578063cf517f6414610213578063e2c345e214610233578063f2fde38b1461024e57600080fd5b80636e773eb8146101c7578063715018a6146101da5780638da5cb5b146101e257600080fd5b8063482eea7b116100bd578063482eea7b1461017f578063517e809e1461019257806365771c61146101a757600080fd5b80632d47c3da146100e457806340a653dc1461010057806347ccca0214610133575b600080fd5b6100ed60025481565b6040519081526020015b60405180910390f35b61012361010e366004610bbb565b60036020526000908152604090205460ff1681565b60405190151581526020016100f7565b61015a7f000000000000000000000000960b7a6bcd451c9968473f7bbfd9be826efd549a81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f7565b6100ed61018d366004610bbb565b610261565b6101a56101a0366004610bfd565b610294565b005b60015461015a9073ffffffffffffffffffffffffffffffffffffffff1681565b6101a56101d5366004610c6b565b6102e3565b6101a56103bc565b60005473ffffffffffffffffffffffffffffffffffffffff1661015a565b6101a561020e366004610d9e565b6103d0565b610226610221366004610e52565b61042e565b6040516100f79190610e74565b61015a7327cb33476bf69e025927a07b6732cdfd8f7618e481565b6101a561025c366004610bfd565b610501565b60008181526003602052604081205460ff1661027f57506000919050565b61028e82640a7b451d40610ee7565b92915050565b61029c61056a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8860005b818110156103ae5761039e8c8c8381811061030457610304610efa565b905060200201358b8b8481811061031d5761031d610efa565b90506020020160208101906103329190610bfd565b8a8a8581811061034457610344610efa565b90506020028101906103569190610f29565b8a8a8781811061036857610368610efa565b905060200281019061037a9190610f29565b8a8a8981811061038c5761038c610efa565b905060200281019061020e9190610f29565b6103a781610f8e565b90506102e7565b505050505050505050505050565b6103c461056a565b6103ce60006105bd565b565b6103e08888888888888888610632565b610416576040517f41abc80100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610424888888888888610768565b5050505050505050565b600254606090600081900361045357505060408051600081526020810190915261028e565b60008167ffffffffffffffff81111561046e5761046e610fc6565b604051908082528060200260200182016040528015610497578160200160208202803683370190505b5090506000855b8581116104f65760008181526003602052604090205460ff16156104e657808383815181106104cf576104cf610efa565b60209081029190910101526104e382610f8e565b91505b6104ef81610f8e565b905061049e565b509095945050505050565b61050961056a565b73ffffffffffffffffffffffffffffffffffffffff811661055e576040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600060048201526024015b60405180910390fd5b610567816105bd565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103ce576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610555565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000807f000000000000000000000000960b7a6bcd451c9968473f7bbfd9be826efd549a8a8a8a8a8a8a6040516020016106729796959493929190610ff5565b6040516020818303038152906040528051906020012090506000816040516020016106c991907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282526001548151602080840191909120601f8a018290048202860182019094528885529194506107599373ffffffffffffffffffffffffffffffffffffffff909116929189908990819084018382808284376000920191909152506108ab92505050565b9b9a5050505050505050505050565b600086815260036020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055600280549091906107af90610f8e565b909155506040517f42842e0e00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8681166024830152604482018890527f000000000000000000000000960b7a6bcd451c9968473f7bbfd9be826efd549a16906342842e0e90606401600060405180830381600087803b15801561084957600080fd5b505af115801561085d573d6000803e3d6000fd5b50505050857fc05eba7c5eeb227a4a8f4cfa3302be3ec8ff2d5a33962794b2c80008e030d6b333878787878760405161089b969594939291906110a9565b60405180910390a2505050505050565b60008060006108ba8585610927565b50909250905060008160038111156108d4576108d4611103565b14801561090c57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b8061091d575061091d868686610974565b9695505050505050565b600080600083516041036109615760208401516040850151606086015160001a61095388828585610ac1565b95509550955050505061096d565b50508151600091506002905b9250925092565b60008060008573ffffffffffffffffffffffffffffffffffffffff1685856040516024016109a3929190611156565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1626ba7e0000000000000000000000000000000000000000000000000000000017905251610a2491906111ae565b600060405180830381855afa9150503d8060008114610a5f576040519150601f19603f3d011682016040523d82523d6000602084013e610a64565b606091505b5091509150818015610a7857506020815110155b801561091d575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090610ab690830160209081019084016111ca565b149695505050505050565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610afc5750600091506003905082610bb1565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610b50573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610ba757506000925060019150829050610bb1565b9250600091508190505b9450945094915050565b600060208284031215610bcd57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610bf857600080fd5b919050565b600060208284031215610c0f57600080fd5b610c1882610bd4565b9392505050565b60008083601f840112610c3157600080fd5b50813567ffffffffffffffff811115610c4957600080fd5b6020830191508360208260051b8501011115610c6457600080fd5b9250929050565b60008060008060008060008060008060a08b8d031215610c8a57600080fd5b8a3567ffffffffffffffff80821115610ca257600080fd5b610cae8e838f01610c1f565b909c509a5060208d0135915080821115610cc757600080fd5b610cd38e838f01610c1f565b909a50985060408d0135915080821115610cec57600080fd5b610cf88e838f01610c1f565b909850965060608d0135915080821115610d1157600080fd5b610d1d8e838f01610c1f565b909650945060808d0135915080821115610d3657600080fd5b50610d438d828e01610c1f565b915080935050809150509295989b9194979a5092959850565b60008083601f840112610d6e57600080fd5b50813567ffffffffffffffff811115610d8657600080fd5b602083019150836020828501011115610c6457600080fd5b60008060008060008060008060a0898b031215610dba57600080fd5b88359750610dca60208a01610bd4565b9650604089013567ffffffffffffffff80821115610de757600080fd5b610df38c838d01610d5c565b909850965060608b0135915080821115610e0c57600080fd5b610e188c838d01610d5c565b909650945060808b0135915080821115610e3157600080fd5b50610e3e8b828c01610d5c565b999c989b5096995094979396929594505050565b60008060408385031215610e6557600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015610eac57835183529284019291840191600101610e90565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561028e5761028e610eb8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610f5e57600080fd5b83018035915067ffffffffffffffff821115610f7957600080fd5b602001915036819003821315610c6457600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610fbf57610fbf610eb8565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808a60601b168352886014840152808860601b166034840152508486604884013784820160488101600081528486823750600093016048019283525090979650505050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600073ffffffffffffffffffffffffffffffffffffffff8089168352808816602084015250608060408301526110e3608083018688611060565b82810360608401526110f6818587611060565b9998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60005b8381101561114d578181015183820152602001611135565b50506000910152565b828152604060208201526000825180604084015261117b816060850160208701611132565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b600082516111c0818460208701611132565b9190910192915050565b6000602082840312156111dc57600080fd5b505191905056fea26469706673582212200094b011080e86e4ed7c11b689fc331a466356481348f92b1476177c03dcbb6164736f6c63430008150033

Verified Source Code Full Match

Compiler: v0.8.21+commit.d9974bed EVM: paris Optimization: Yes (9999999 runs)
BTCTeleburn.sol 101 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

abstract contract BTCTeleburn is Ownable {
    IERC721 public immutable nft;
    address public teleburnSigner;

    uint256 public teleburnedCount = 0;
    mapping(uint256 tokenId => bool) public isTokenTeleburned;

    event Teleburn(
        uint256 indexed tokenId, address sender, address teleburnAddress, string btcAddress, string inscriptionId
    );

    error InvalidRequest();

    constructor(address nft_, address teleburnSigner_) Ownable(msg.sender) {
        nft = IERC721(nft_);
        teleburnSigner = teleburnSigner_;
    }

    function teleburnedTokens(uint256 startTokenId, uint256 endTokenId) external view returns (uint256[] memory) {
        uint256 count = teleburnedCount;
        if (count == 0) return new uint256[](0);
        uint256[] memory tokens = new uint256[](count);

        uint256 index;
        for (uint256 i = startTokenId; i <= endTokenId; ++i) {
            if (isTokenTeleburned[i]) {
                tokens[index] = i;
                ++index;
            }
        }

        return tokens;
    }

    function getTokenSatNumber(uint256 tokenId) external view returns (uint256) {
        if (!isTokenTeleburned[tokenId]) return 0;

        return 45017800000 + tokenId;
    }

    function teleburnMultipleTokens(
        uint256[] calldata tokenIds,
        address[] calldata teleburnAddresses,
        string[] calldata btcAddresses,
        string[] calldata inscriptionIds,
        bytes[] calldata data
    ) external {
        uint256 count = tokenIds.length;

        for (uint256 i; i < count; ++i) {
            teleburnToken(tokenIds[i], teleburnAddresses[i], btcAddresses[i], inscriptionIds[i], data[i]);
        }
    }

    function teleburnToken(
        uint256 tokenId,
        address teleburnAddress,
        string calldata btcAddress,
        string calldata inscriptionId,
        bytes calldata data
    ) public {
        if (!_isValidRequest(tokenId, teleburnAddress, btcAddress, inscriptionId, data)) {
            revert InvalidRequest();
        }

        _teleburn(tokenId, teleburnAddress, btcAddress, inscriptionId);
    }

    function updateTeleburnSigner(address newTeleburnSigner) external onlyOwner {
        teleburnSigner = newTeleburnSigner;
    }

    function _teleburn(
        uint256 tokenId,
        address teleburnAddress,
        string calldata btcAddress,
        string calldata inscriptionId
    ) private {
        isTokenTeleburned[tokenId] = true;

        ++teleburnedCount;
        nft.safeTransferFrom(msg.sender, teleburnAddress, tokenId);
        emit Teleburn(tokenId, msg.sender, teleburnAddress, btcAddress, inscriptionId);
    }

    /// @dev args: tokenId, teleburnAddress, btcAddress, inscriptionId, data
    function _isValidRequest(uint256, address, string calldata, string calldata, bytes calldata)
        internal
        view
        virtual
        returns (bool)
    {
        return true;
    }
}
GenesisTeleburn.sol 29 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

import {BTCTeleburn} from "./BTCTeleburn.sol";
import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";

contract GenesisTeleburn is BTCTeleburn {
    address public constant originalContract = 0x27Cb33476bf69E025927a07b6732Cdfd8f7618E4;

    constructor(address nft, address teleburnSigner_) BTCTeleburn(nft, teleburnSigner_) {
        teleburnedCount = 3;
        isTokenTeleburned[1003] = true;
        isTokenTeleburned[1543] = true;
        isTokenTeleburned[1589] = true;
    }

    function _isValidRequest(
        uint256 tokenId,
        address burnAddress,
        string calldata btcAddress,
        string calldata inscriptionId,
        bytes calldata signature
    ) internal view override returns (bool) {
        bytes32 message = keccak256(abi.encodePacked(nft, tokenId, burnAddress, btcAddress, inscriptionId));
        bytes memory prefixedMessage = abi.encodePacked("\x19Ethereum Signed Message:\n32", message);

        return SignatureChecker.isValidSignatureNow(teleburnSigner, keccak256(prefixedMessage), signature);
    }
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
Ownable.sol 100 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
IERC1271.sol 17 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1271.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC1271 standard signature validation method for
 * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
 */
interface IERC1271 {
    /**
     * @dev Should return whether the signature provided is valid for the provided data
     * @param hash      Hash of the data to be signed
     * @param signature Signature byte array associated with _data
     */
    function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}
IERC721.sol 135 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.20;

import {IERC165} from "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
     *   a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or
     *   {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
     *   a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the address zero.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}
ECDSA.sol 174 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.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, RecoverError, bytes32) {
        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.
            /// @solidity memory-safe-assembly
            assembly {
                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[EIP-2098 short signatures]
     */
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {
        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, RecoverError, bytes32) {
        // 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);
        }
    }
}
IERC165.sol 25 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
SignatureChecker.sol 48 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/SignatureChecker.sol)

pragma solidity ^0.8.20;

import {ECDSA} from "./ECDSA.sol";
import {IERC1271} from "../../interfaces/IERC1271.sol";

/**
 * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA
 * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like
 * Argent and Safe Wallet (previously Gnosis Safe).
 */
library SignatureChecker {
    /**
     * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the
     * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.
     *
     * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
     * change through time. It could return true at block N and false at block N+1 (or the opposite).
     */
    function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {
        (address recovered, ECDSA.RecoverError error, ) = ECDSA.tryRecover(hash, signature);
        return
            (error == ECDSA.RecoverError.NoError && recovered == signer) ||
            isValidERC1271SignatureNow(signer, hash, signature);
    }

    /**
     * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated
     * against the signer smart contract using ERC1271.
     *
     * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
     * change through time. It could return true at block N and false at block N+1 (or the opposite).
     */
    function isValidERC1271SignatureNow(
        address signer,
        bytes32 hash,
        bytes memory signature
    ) internal view returns (bool) {
        (bool success, bytes memory result) = signer.staticcall(
            abi.encodeCall(IERC1271.isValidSignature, (hash, signature))
        );
        return (success &&
            result.length >= 32 &&
            abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));
    }
}

Read Contract

getTokenSatNumber 0x482eea7b → uint256
isTokenTeleburned 0x40a653dc → bool
nft 0x47ccca02 → address
originalContract 0xe2c345e2 → address
owner 0x8da5cb5b → address
teleburnSigner 0x65771c61 → address
teleburnedCount 0x2d47c3da → uint256
teleburnedTokens 0xcf517f64 → uint256[]

Write Contract 5 functions

These functions modify contract state and require a wallet transaction to execute.

renounceOwnership 0x715018a6
No parameters
teleburnMultipleTokens 0x6e773eb8
uint256[] tokenIds
address[] teleburnAddresses
string[] btcAddresses
string[] inscriptionIds
bytes[] data
teleburnToken 0xc3c9f76f
uint256 tokenId
address teleburnAddress
string btcAddress
string inscriptionId
bytes data
transferOwnership 0xf2fde38b
address newOwner
updateTeleburnSigner 0x517e809e
address newTeleburnSigner

Recent Transactions

No transactions found for this address