// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (utils/Arrays.sol)pragmasolidity ^0.8.20;import {StorageSlot} from"./StorageSlot.sol";
import {Math} from"./math/Math.sol";
/**
* @dev Collection of functions related to array types.
*/libraryArrays{
usingStorageSlotforbytes32;
/**
* @dev Searches a sorted `array` and returns the first index that contains
* a value greater or equal to `element`. If no such index exists (i.e. all
* values in the array are strictly less than `element`), the array length is
* returned. Time complexity O(log n).
*
* `array` is expected to be sorted in ascending order, and to contain no
* repeated elements.
*/functionfindUpperBound(uint256[] storage array, uint256 element) internalviewreturns (uint256) {
uint256 low =0;
uint256 high = array.length;
if (high ==0) {
return0;
}
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)// because Math.average rounds towards zero (it does integer division with truncation).if (unsafeAccess(array, mid).value> element) {
high = mid;
} else {
low = mid +1;
}
}
// At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.if (low >0&& unsafeAccess(array, low -1).value== element) {
return low -1;
} else {
return low;
}
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/functionunsafeAccess(address[] storage arr, uint256 pos) internalpurereturns (StorageSlot.AddressSlot storage) {
bytes32 slot;
// We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`// following https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays./// @solidity memory-safe-assemblyassembly {
mstore(0, arr.slot)
slot :=add(keccak256(0, 0x20), pos)
}
return slot.getAddressSlot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/functionunsafeAccess(bytes32[] storage arr, uint256 pos) internalpurereturns (StorageSlot.Bytes32Slot storage) {
bytes32 slot;
// We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`// following https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays./// @solidity memory-safe-assemblyassembly {
mstore(0, arr.slot)
slot :=add(keccak256(0, 0x20), pos)
}
return slot.getBytes32Slot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/functionunsafeAccess(uint256[] storage arr, uint256 pos) internalpurereturns (StorageSlot.Uint256Slot storage) {
bytes32 slot;
// We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`// following https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays./// @solidity memory-safe-assemblyassembly {
mstore(0, arr.slot)
slot :=add(keccak256(0, 0x20), pos)
}
return slot.getUint256Slot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/functionunsafeMemoryAccess(uint256[] memory arr, uint256 pos) internalpurereturns (uint256 res) {
assembly {
res :=mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/functionunsafeMemoryAccess(address[] memory arr, uint256 pos) internalpurereturns (address res) {
assembly {
res :=mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
}
Contract Source Code
File 2 of 13: Context.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)pragmasolidity ^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.
*/abstractcontractContext{
function_msgSender() internalviewvirtualreturns (address) {
returnmsg.sender;
}
function_msgData() internalviewvirtualreturns (bytescalldata) {
returnmsg.data;
}
}
Contract Source Code
File 3 of 13: ERC1155.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/ERC1155.sol)pragmasolidity ^0.8.20;import {IERC1155} from"./IERC1155.sol";
import {IERC1155Receiver} from"./IERC1155Receiver.sol";
import {IERC1155MetadataURI} from"./extensions/IERC1155MetadataURI.sol";
import {Context} from"../../utils/Context.sol";
import {IERC165, ERC165} from"../../utils/introspection/ERC165.sol";
import {Arrays} from"../../utils/Arrays.sol";
import {IERC1155Errors} from"../../interfaces/draft-IERC6093.sol";
/**
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*/abstractcontractERC1155isContext, ERC165, IERC1155, IERC1155MetadataURI, IERC1155Errors{
usingArraysforuint256[];
usingArraysforaddress[];
mapping(uint256 id =>mapping(address account =>uint256)) private _balances;
mapping(address account =>mapping(address operator =>bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.jsonstringprivate _uri;
/**
* @dev See {_setURI}.
*/constructor(stringmemory uri_) {
_setURI(uri_);
}
/**
* @dev See {IERC165-supportsInterface}.
*/functionsupportsInterface(bytes4 interfaceId) publicviewvirtualoverride(ERC165, IERC165) returns (bool) {
return
interfaceId ==type(IERC1155).interfaceId||
interfaceId ==type(IERC1155MetadataURI).interfaceId||super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/functionuri(uint256/* id */) publicviewvirtualreturns (stringmemory) {
return _uri;
}
/**
* @dev See {IERC1155-balanceOf}.
*/functionbalanceOf(address account, uint256 id) publicviewvirtualreturns (uint256) {
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/functionbalanceOfBatch(address[] memory accounts,
uint256[] memory ids
) publicviewvirtualreturns (uint256[] memory) {
if (accounts.length!= ids.length) {
revert ERC1155InvalidArrayLength(ids.length, accounts.length);
}
uint256[] memory batchBalances =newuint256[](accounts.length);
for (uint256 i =0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts.unsafeMemoryAccess(i), ids.unsafeMemoryAccess(i));
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/functionsetApprovalForAll(address operator, bool approved) publicvirtual{
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/functionisApprovedForAll(address account, address operator) publicviewvirtualreturns (bool) {
return _operatorApprovals[account][operator];
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/functionsafeTransferFrom(addressfrom, address to, uint256 id, uint256 value, bytesmemory data) publicvirtual{
address sender = _msgSender();
if (from!= sender &&!isApprovedForAll(from, sender)) {
revert ERC1155MissingApprovalForAll(sender, from);
}
_safeTransferFrom(from, to, id, value, data);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/functionsafeBatchTransferFrom(addressfrom,
address to,
uint256[] memory ids,
uint256[] memory values,
bytesmemory data
) publicvirtual{
address sender = _msgSender();
if (from!= sender &&!isApprovedForAll(from, sender)) {
revert ERC1155MissingApprovalForAll(sender, from);
}
_safeBatchTransferFrom(from, to, ids, values, data);
}
/**
* @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`. Will mint (or burn) if `from`
* (or `to`) is the zero address.
*
* Emits a {TransferSingle} event if the arrays contain one element, and {TransferBatch} otherwise.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement either {IERC1155Receiver-onERC1155Received}
* or {IERC1155Receiver-onERC1155BatchReceived} and return the acceptance magic value.
* - `ids` and `values` must have the same length.
*
* NOTE: The ERC-1155 acceptance check is not performed in this function. See {_updateWithAcceptanceCheck} instead.
*/function_update(addressfrom, address to, uint256[] memory ids, uint256[] memory values) internalvirtual{
if (ids.length!= values.length) {
revert ERC1155InvalidArrayLength(ids.length, values.length);
}
address operator = _msgSender();
for (uint256 i =0; i < ids.length; ++i) {
uint256 id = ids.unsafeMemoryAccess(i);
uint256 value = values.unsafeMemoryAccess(i);
if (from!=address(0)) {
uint256 fromBalance = _balances[id][from];
if (fromBalance < value) {
revert ERC1155InsufficientBalance(from, fromBalance, value, id);
}
unchecked {
// Overflow not possible: value <= fromBalance
_balances[id][from] = fromBalance - value;
}
}
if (to !=address(0)) {
_balances[id][to] += value;
}
}
if (ids.length==1) {
uint256 id = ids.unsafeMemoryAccess(0);
uint256 value = values.unsafeMemoryAccess(0);
emit TransferSingle(operator, from, to, id, value);
} else {
emit TransferBatch(operator, from, to, ids, values);
}
}
/**
* @dev Version of {_update} that performs the token acceptance check by calling
* {IERC1155Receiver-onERC1155Received} or {IERC1155Receiver-onERC1155BatchReceived} on the receiver address if it
* contains code (eg. is a smart contract at the moment of execution).
*
* IMPORTANT: Overriding this function is discouraged because it poses a reentrancy risk from the receiver. So any
* update to the contract state after this function would break the check-effect-interaction pattern. Consider
* overriding {_update} instead.
*/function_updateWithAcceptanceCheck(addressfrom,
address to,
uint256[] memory ids,
uint256[] memory values,
bytesmemory data
) internalvirtual{
_update(from, to, ids, values);
if (to !=address(0)) {
address operator = _msgSender();
if (ids.length==1) {
uint256 id = ids.unsafeMemoryAccess(0);
uint256 value = values.unsafeMemoryAccess(0);
_doSafeTransferAcceptanceCheck(operator, from, to, id, value, data);
} else {
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, values, data);
}
}
}
/**
* @dev Transfers a `value` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `from` must have a balance of tokens of type `id` of at least `value` amount.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/function_safeTransferFrom(addressfrom, address to, uint256 id, uint256 value, bytesmemory data) internal{
if (to ==address(0)) {
revert ERC1155InvalidReceiver(address(0));
}
if (from==address(0)) {
revert ERC1155InvalidSender(address(0));
}
(uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value);
_updateWithAcceptanceCheck(from, to, ids, values, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
* - `ids` and `values` must have the same length.
*/function_safeBatchTransferFrom(addressfrom,
address to,
uint256[] memory ids,
uint256[] memory values,
bytesmemory data
) internal{
if (to ==address(0)) {
revert ERC1155InvalidReceiver(address(0));
}
if (from==address(0)) {
revert ERC1155InvalidSender(address(0));
}
_updateWithAcceptanceCheck(from, to, ids, values, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the values in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/function_setURI(stringmemory newuri) internalvirtual{
_uri = newuri;
}
/**
* @dev Creates a `value` amount of tokens of type `id`, and assigns them to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/function_mint(address to, uint256 id, uint256 value, bytesmemory data) internal{
if (to ==address(0)) {
revert ERC1155InvalidReceiver(address(0));
}
(uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value);
_updateWithAcceptanceCheck(address(0), to, ids, values, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `values` must have the same length.
* - `to` cannot be the zero address.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/function_mintBatch(address to, uint256[] memory ids, uint256[] memory values, bytesmemory data) internal{
if (to ==address(0)) {
revert ERC1155InvalidReceiver(address(0));
}
_updateWithAcceptanceCheck(address(0), to, ids, values, data);
}
/**
* @dev Destroys a `value` amount of tokens of type `id` from `from`
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `from` must have at least `value` amount of tokens of type `id`.
*/function_burn(addressfrom, uint256 id, uint256 value) internal{
if (from==address(0)) {
revert ERC1155InvalidSender(address(0));
}
(uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value);
_updateWithAcceptanceCheck(from, address(0), ids, values, "");
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `from` must have at least `value` amount of tokens of type `id`.
* - `ids` and `values` must have the same length.
*/function_burnBatch(addressfrom, uint256[] memory ids, uint256[] memory values) internal{
if (from==address(0)) {
revert ERC1155InvalidSender(address(0));
}
_updateWithAcceptanceCheck(from, address(0), ids, values, "");
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the zero address.
*/function_setApprovalForAll(address owner, address operator, bool approved) internalvirtual{
if (operator ==address(0)) {
revert ERC1155InvalidOperator(address(0));
}
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Performs an acceptance check by calling {IERC1155-onERC1155Received} on the `to` address
* if it contains code at the moment of execution.
*/function_doSafeTransferAcceptanceCheck(address operator,
addressfrom,
address to,
uint256 id,
uint256 value,
bytesmemory data
) private{
if (to.code.length>0) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, value, data) returns (bytes4 response) {
if (response != IERC1155Receiver.onERC1155Received.selector) {
// Tokens rejectedrevert ERC1155InvalidReceiver(to);
}
} catch (bytesmemory reason) {
if (reason.length==0) {
// non-ERC1155Receiver implementerrevert ERC1155InvalidReceiver(to);
} else {
/// @solidity memory-safe-assemblyassembly {
revert(add(32, reason), mload(reason))
}
}
}
}
}
/**
* @dev Performs a batch acceptance check by calling {IERC1155-onERC1155BatchReceived} on the `to` address
* if it contains code at the moment of execution.
*/function_doSafeBatchTransferAcceptanceCheck(address operator,
addressfrom,
address to,
uint256[] memory ids,
uint256[] memory values,
bytesmemory data
) private{
if (to.code.length>0) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, values, data) returns (
bytes4 response
) {
if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
// Tokens rejectedrevert ERC1155InvalidReceiver(to);
}
} catch (bytesmemory reason) {
if (reason.length==0) {
// non-ERC1155Receiver implementerrevert ERC1155InvalidReceiver(to);
} else {
/// @solidity memory-safe-assemblyassembly {
revert(add(32, reason), mload(reason))
}
}
}
}
}
/**
* @dev Creates an array in memory with only one value for each of the elements provided.
*/function_asSingletonArrays(uint256 element1,
uint256 element2
) privatepurereturns (uint256[] memory array1, uint256[] memory array2) {
/// @solidity memory-safe-assemblyassembly {
// Load the free memory pointer
array1 :=mload(0x40)
// Set array length to 1mstore(array1, 1)
// Store the single element at the next word after the length (where content starts)mstore(add(array1, 0x20), element1)
// Repeat for next array locating it right after the first array
array2 :=add(array1, 0x40)
mstore(array2, 1)
mstore(add(array2, 0x20), element2)
// Update the free memory pointer by pointing after the second arraymstore(0x40, add(array2, 0x40))
}
}
}
Contract Source Code
File 4 of 13: ERC165.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)pragmasolidity ^0.8.20;import {IERC165} from"./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/abstractcontractERC165isIERC165{
/**
* @dev See {IERC165-supportsInterface}.
*/functionsupportsInterface(bytes4 interfaceId) publicviewvirtualreturns (bool) {
return interfaceId ==type(IERC165).interfaceId;
}
}
Contract Source Code
File 5 of 13: F1337Token.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.8.0;import {ERC1155} from"@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import {Ownable} from"@openzeppelin/contracts/access/Ownable.sol";
contractF1337TokenisERC1155, Ownable{
eventLotteried(uint lotteryNumber);
string name0 ="You are not Farcaster 1337";
string name1 ="You are Farcaster 1337";
string description0 ="Are you 1337? F1337 is a fully onchain game for only Farcaster users. Play it here! https://f1337.vercel.app/";
string description1 ="Are you 1337? F1337 is a fully onchain game for only Farcaster users. Play it here! https://f1337.vercel.app/";
stringpublic imageURI0 ="data:image/gif;base64,R0lGODlhiAKIAvftAIRey4Vfy4ZhzIdizYplzpJw0p1/1Z6A15+C1qOH16+W3rii4NPF7Pf1/fj2+/j2/fn4/Pv5//v6/fz8/v38/v79//7+///+/41qzqWJ2beh4fHt+vn3/fz7/v39/ohjzItmz4tnzIxozpFu0JNy0ZRz0Zd306GD16KF2KqP3KuS262U27Sd4L+r48a058a06Mu76cy86s296dDB7N/W8eLZ9OTb8+Xd9eXe8+bf9Orj9+vk9/Dr+fDt+PHs+vPv+vTy+v37/4lkzYllzJZ105l61LKb3rOb4L6p5NfJ79jM79rN8e3m+Pr5/YJbybCY3se1586+6+ji9vbz/ayS3Lul49XI7Jl51aiN26mP2rum48Ct5Mi36dfK7/b0+55/16mP3L2o5MGu5cSx5tLE7NzR8eDW8uvl9+vm9u/r9/Ds+fv7/YNdypFu0pt81KaK2qeM2q6U3u3n9/38/5l41KSH2rmj4rmk4MGv5NjM8N3S8ejh9YpmzY1qz49r0JVz05x91q+X3Lae4cOv58Wy58Wz59HD7NTG7dnN7+HX8+Tb9Obe9ezm9+7o+O/p+fXy+vby/Pv5/otozp6A1q6V3bWe4Lef4Leg4r2o48Sy5sm46c/A69nN8NzR8N/V8eni9fr4/q2T3bGY3sKu5tDC69TH7NrO7+rl9ZNx0auQ27qk4rum4ryo4/v6/vz7//7+/o5szpp71Zx+1bOc3rql4ryn5L2p476q48Kw5si36Mi46M6/6tbJ7dfL7trP79vP8N7U8N/U8ufg9e/q+PTw+vf1+/n4/f79/v///49sz5p51aCC16OH2KSI2aWI2aiN2q6V3K+W3bGY3bGZ3rag4Leh4rih4byn4byn47+r5MCs5cKv5cKv5sOw5sOx5s296tXI7tfK7tvQ8N3T8N7T8eHY8uLZ8uff9erk9erk9/Hs+fLt+ff0/AD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFHgDtACwAAAAAiAKIAgAI/wDXIBNIcKDBgggPKkzIcKHDhhAfSoxIcaLFihgvaszIcaPHjiA/igxJcqTJkihPqkzJcqXLljBfypxJ81XNmx5w6rSZk+fOnz6DAh3ak6jRokiPKhWalOnSp06jQp1KtWrMq1azYt2qtSvXr17Dgh0rtanYs2bTol1blq3btnDfylUbl+7cu3jzkt2rty/fv34DAx4s2K7hwnURK07MeLHjw40hP55MuTLhy5YzY96subPnz5JDgx4dmbTp0qhPc16tmrXr1rBfy46dWnRt2rdz495tm7fv38BnCw9OfLjx4r2TI1eum/ny586jQz9OfXr169azY98uvbn2797Dg/8f35089/Pm0atPz769e/Hl47+fD5/++vv28evPz7+/f/n1BfjfgAQWuN+BBiao4IICAsjggw5CKCGCFE5o4YUYNpjhhhx2WOGHHoYo4ogRkmjiiSiCqGKKGrbIYokuwvjijDTWuOKNNsaYo4w87ujjj0DiKGSQOhZJZI9GInnkkkw2OeSTTiYZpZJUTmnllVhCqaWUXGbpZZVdgvnllmSOWeaZYqZp5pphsonmm27CKWecbdZJp5p24nnnnHzu2eefegbq56B5EgrooYYiqmihjCbqqKCNQrropI9WSqmlmEaa6aWbcuppp5KGCqqmpI766ammoprqqqKW2iqrqsL/Guusr9Yq662u0qorrrz26muuwP6667DCElvssbYGm6yxyDbLrLPQKhvts9NSa+2y2Far7bbcXuuttOB2K+645H5rbrbholvuuuy2e6678KYb77vz0lvvvermay++/Pbrr7wA7yvwvwQXbLC+Byc8sMIMB4zwwg1HLPHED1cM8cUUZ6zxxhx3jLHHIDv8ccgkl2yyyCenPLLKLLfs8soovyzzzDTDXPPNOOdss8Ux86zzz0AHLfTQRBdt9NE+I6300kwnvfPTTUct9dRUV2311VhnrfXWXHft9ddghy322GSXbfbZaKet9tpst+3223DHLffcdNdt991456333nz3/+031ID/LfjghBdu+OGIJ6744ow73XPjj0ce+OSQO1655JZfrvnmnHfu+eegh4656KOXTvnppGeeuuqmr+7667DHLvvsqNdO++2456777rb3zvvvwAffuvDDF+/78cSznrzxyzfv/PPQMx+99NQjb/30ymeP/fbcd+/999VrHz745Jdv/vXon6/++uyL377778cvf/r0z2///fiPr3/+/Pfvf/0A/J8AB0jA/cGvgAhMoAIDyMAFOrCBEHygBCdIQQNW8IIYzGAEN6jBDnLwgx4MoQhH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";
stringpublic imageURI1 ="data:image/gif;base64,R0lGODlhiAKIAvfRAIZgzYhizoNdyolkz4VfzIdhzoJbyoRezIReyoVfyoZhy4dhzYdjzIhjzo1qzpV00pZ11Jd305l606eN2KyS3Mi26dHC7NPG7efe9erj9+zn9/Xx+/j2/Pv5/fz6/f38/v///4tn0I5q0Zp61r+q5N/V8efg9Ma159fK8MCs5YVgy5Bu0KqQ2quQ3bCX3bKZ38Gt5su66c/A6+7p9/f0+v7+/qiN3MOw5sOx5sy868296tnO79vQ8cKv5sq66Yxn0JFv0aaL26eL3LWe4My86odizYlkzollzYplzopmzYtnzo1p0JJw0Zx91p+B2KmO266U3Leh4bii4Lum4r2o5M2+69LD7dvP8ODW8+HY8+Xd9Ojh9uvk9u7p+fDr+fHt+fbz+/j0/vj1/Pr3/oZhzZFu0px+1aSI2KyT27ii4ci26NzR8OHX8/Tx+fr4/ohkzIxozo9sz5h41KCC16KF2KSG2aWI2rKb3bqk472p47+q5sWy593R8/z7/si3582+6dnM8I5r0I9s0pJw05Nx05Rz0ph51Jp71J6A1qCD2KGE2KOF2qWJ2aiM2q+W3rOc37Wd4Lyn48Cs5MOx58a06Mq469jM797T8t7U8ePa8+Pb9PPv+vXy+Yljzoxoz5Bu0ZFu1JVz1Jh31Zl51Z+B17Ka3raf4Lql4si36cm46Mm46dXI7eni9oBayYdizpt71px91b6q5cWz58m46sq56dbJ7vLv+Pn2/oVezIZfzYlkzI5q0JBt0JFt05Z1051+155/1qKG2KOF2KaL2aeM26uR2rCX3rGZ3beg37mj4rul4su668y86dLE7N3R8uff9fn3/gD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFHgDRACwAAAAAiAKIAgAI/wANBBAwQCBBgwUHJjyoEKHDhhAZSlxI8eFEixUjZryoEaPHjiA5itxI8uNIkyVDpjypEqXLljBZylxJ8+VMmzVj5rypE6fPnkB5Ct1J9OdQAAcKEECqlOnSpE+bQnVKdapVqVijaq2alevWq1+7gvVKdqxZsWjDqi2blu3as2/bwnVLd65duXjj6q2bl+/eu3/7AvZLeLBhwYgDKy6c+GjQoo+NQnZMebJlyZgja66cmfPmy587g/ZMerRp0ahDq258eHFrxq5Zy45NG7bt17hn39adu3bv3b55Cw9OHLjx38hTl1Z+enXz5c6ZS49OHbr159inX9eevXr37cmLh/8/Ppy8+PLj06Nff769+ffq3ceHz56+fO74vecHz/+7//3/6SdgfwAWOGCABB5o34LzNVifg/dFyOCDFEoI4YQWVojhhhci6KGBCYb4oYIkigjiiCaWiOKKJ7bYoYYvZigjhzDWOGOMNN5oY4484uijiykGyaKKQA4pZJFIEqnkkUsa6WSPO/6o45RQUilllVheqWWUXFqZJJNgPtnkl2KGSeaZY6Zppppetplll2+6uaWccM4Z55125onmmnyW6eeef7IJ6KCCFtonnnUmSueiiDKqp6OKNirpo4caGmilmF6qKaGZcrqppZ5OGimlpI5qKqSoippqqauGCuqrncL/+mmstM5qq6u1qqorq7ue2murwP4qLK+3yoprsbkaq2yyzCLr7LC+EhvttMFKWy210F6rbbPHdrvss996y2245GJrbbbonquuuexuu6674oI77rzy1hvvveXa+2667fIL77/+BrzvwPjSW7C+Bud78MIKN9wvwQBDLPDDFEdc8cQOI6wxwwl3vHHGHFssMsYkS2zyxSePnLLHIbcM8sssw/xxzCjXrLLNJeO88s46u0zzzED7HLTMQhfN881I55z00Uo3zfTQPxsdNdFUT2310j1jrbXTWXO99dNSQy122GRXPbbZXqcN9tddr61223CjLffVZdM999l2x/0223zv/+2324DXjffgghd+t+F59x244nov/nfjkB8ueeKIEz655ZQ7rnnkjzPueeegYy565aRfXnrmnG/+ueqhp+766qePbvrsqMtee+uw54777qz3HvvvtNsuPPC3B8/768fr7rvyyA9v/PPFR++89MlXv7z1zWfPPPTTd0+899x/j/3245d//fnaUx/++uq3D7775qePPvnzx0+/+Oy/rz/+8Odv///1C6D8Bui/AvbvgPszYAIJCEAGCvB+EGygAvm3wApS8IIPlKAGM8hBB2IQgR+04ARHCMIORtCEG/TgCUPIQhKKsIQwfOEKZ5hCGqLwhi2MYQ5luMMe4tCGKqyhEP9/qEMX+rCISOQhEZcYRCYC8YlJPKISo2jEKjbxilB04hCxuEUrTvGLUgyjF7tIRi2akYtgHKMaqcjGNKLxjVmEYxnleMY1uvGOYmzjHOPIxz36sY56tGMe8SjIQtLxkH0EpCIRGchGEtKRg/wjIxeZyEla0pCPzGQkMbnJS0qykqD8JCQ5ScpRmlKTlBRlKlfpSVSespOujCUsVdnKWoaSlaWUZS5nucte2pKWt/wlLl/pS10S85jBTCYwlznMZvISmc80pjSZKcxqKtOZxYymNrPJTWtS85rexOY3odnNaZZzm+FMJzjXOU5zkvOd7oxnO9U5T3aKU57nzCc80Wn/T3re058A7ac+8bnPgfKzngj9p0ALylCCOvSgCk1oQCW60Ica9KINhehEI8rRjXoUoxbNKEg1WtGPUvSkHR2pSkXK0pCW9KUoNWlKW0rSmq4UpjPNqUx3elOb0rSnQOVpTHEqVJ0G1aU+RapRh8rUpTo1qVA9alR/WtSqEvWqTZ2qUqm6Vaw+1atWzapUx8pVrYr1rF9Fa1i7alaysjWtcF2rXMHq1raWta5xpata9ZrXu/r1rX+1K1/nutfCAvawgk1sXxdLWMYOFq+BhSxiHWvYxlr2sZHN7GQ1W1nMUvaziuWsZEO7Wc9etrOoLS1pVzva1p4WtKaNrWhnq1rX/8oWtql9LWtpu9va8ha3wNXtbXtLXNsWV7i5Ha5yk/vb5vr2ucwN7nKl69zjQte41M0ucrWL3ep297rbDe90xRtd65r3u+clL3fLO170ute78G0ve+e7XvDaN733ra969yvf/MYXvwDWb3/5S98A//e9/h2wggu84AQb2MEIZrCEBTzhB1s4whgmMIU3rOELH/jDEO5wg0Vc4QyH+MQeHrGKS8xiFJs4xTDm8IplDOIY1/jFNM4xiXWM4xv72MU7DvKMhfxjGwP5yC0mMo+T3GMkN5nJUF6ylI1M5SdbWclYHrKWi3xlJ3M5y1EGs5fHXOUvb3nKZxZzmcnc5TWHOf/NcDazm9tMZzXHGc1vlnOd2WznPOP5z3PWs6D5fOc+A3rPgSZ0ov1s6EYXGtGQHjSjHz3pSis60peW9KEt7WhNezrToOY0pTcdakwv2tSk7nSqUf3pU7d61aKOdalfTetZj1rVuL41q23tal3LOte/3nWvhw3rYgPb2MJOdq2DzWxkN5vYy1a2r51NbWjzWtrWfva0j51tbHs72tzetrjBfW1ydzvc2k53udd9bnZXe9zvNve33Y3ueNu73u3O97zVjW9491veAKe3vwfO730bPOD6/ve9CS7whDd84QWPOMQfjvCDM1zhGLe4wzeu8YlnXOIcr7jIL05ykJec4ij/D/nJP+7xjo9c5SaPectlDnOXp3zmOGd5zV9uc5qv/Oc+57nQb65zoOe850gfetCPvvSdE/3pTm+60Yuu9KRDnelYp/rVq871qXtd6mDfutijnvWvl73rZEf72deu9bSP3ephb7vZ3U53uNtd7nGf+93frna8s13vfee74PNO+L8Hvu6HN7zi/Y74we+98IwHvOMTT/nJSz7ykH+85iuf+c4vfvOWb7znMf95zoNe9KVPPelRb/rWX/71oz+97F0f+9qrfvahx73tVw/73NNe97fffe9Z7/viC//4wTc+8H/Pe+Q3X/nMh/7wp+/85Uu/+thPPvG3b/3sP//73Q9///S9T33ti//65ye/+s0//vS7H/zr5377519++LMf/fSXf/33H//34//mIWAESNAAATiAaWGAAngWZjAEJ2ABDhgJT8AErmAXBUiACXiAFoiAthEBS6AYGpiBgwGCFTiCF+iBIliCHygXZSAHOoGCJ8gYTPAEJCADDigLkAALStAaI3AEjeELNnAMj/AEv9CBSbELOZgVKeiCJJiETPiCRbCETlgeDvACEuAXEeACFaADVSAJUCCBFCiDMSADlPAIHPgXUAiFliUBFsAGa8CGWdCGOzAJDNAQTtAMWACHb4gFOAAKFvECq7AJrMAGNLgKWzADGZACO6gRJHAJeIiHc/+QEYzABzvghnBoCgmgGU+gAU9AE8nAiJT4iZYACDb4AD9gEZMwiY14h56Iinm4BpYIE4WAAqyYirPYio+oEnmwBWUYEhFQBasIind4AXnQAg5QE7+AAxrgBRmwA7VghybwBavgCG/wAy6wCDKBBhlAAULRAhfwBYaoBV3ABZkwBa8AB1ZQDAkhCa2oirXYjpAgALBwAey4ju34hihQCAnhADJQj6xoAXswDKGAAJ+xAkJAAhiwASwwE4WACoVYAm+4AZzABWnAhyDhAJGQBYCYCZjgBZywCSfAghsR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";
boolpublic paused =true;
uintpublic counter; //For capconstructor() ERC1155("") Ownable(msg.sender) {}
functionsetMeta0(stringmemory _name0,
stringmemory _description0
) externalonlyOwner{
name0 = _name0;
description0 = _description0;
}
functionsetMeta1(stringmemory _name1,
stringmemory _description1
) externalonlyOwner{
name1 = _name1;
description1 = _description1;
}
functionsetImgURI0(stringmemory _imageURI0) externalonlyOwner{
imageURI0 = _imageURI0;
}
functionsetImgURI1(stringmemory _imageURI1) externalonlyOwner{
imageURI1 = _imageURI1;
}
functiontogglePaused() externalonlyOwner{
paused =!paused;
}
functionuri(uint256 _id) publicviewoverridereturns (stringmemory) {
(
stringmemory _name,
stringmemory _description,
stringmemory _imageURI
) = (_id ==1)
? (name1, description1, imageURI1)
: (name0, description0, imageURI0);
returnstring(
abi.encodePacked(
"data:application/json;utf8,",
"{",
'"name":"',
_name,
'",',
'"description":"',
_description,
'",',
'"image": "',
_imageURI,
'"}'
)
);
}
functionmint() externalreturns (uint lotteryNumber_) {
require(paused ==false, "Paused");
lotteryNumber_ = lotteryNumber(block.number-1);
uint _id;
if (lotteryNumber_ ==1337) {
_id =1;
counter++;
//if msg.sender has already token id 1, revertrequire(balanceOf(msg.sender, _id) ==0, "Already minted");
require(counter <=1337, "Cap reached");
}
emit Lotteried(lotteryNumber_);
_mint(msg.sender, _id, 1, "");
}
functionlotteryNumber(uint _blockNumber) publicviewreturns (uint) {
returnuint(blockhash(_blockNumber)) %10000;
}
// View function to get the lottery number of a specific blockfunctiongetLotteryNumber() externalviewreturns (uint) {
return lotteryNumber(block.number-1);
}
// get latest 8 numbersfunctiongetLotteryNumbers()
externalviewreturns (uint[10] memory lotteryNumbers_)
{
for (uint i =0; i <10; i++) {
lotteryNumbers_[i] = lotteryNumber(block.number- i -1);
}
}
}
Contract Source Code
File 6 of 13: IERC1155.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/IERC1155.sol)pragmasolidity ^0.8.20;import {IERC165} from"../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*/interfaceIERC1155isIERC165{
/**
* @dev Emitted when `value` amount of tokens of type `id` are transferred from `from` to `to` by `operator`.
*/eventTransferSingle(addressindexed operator, addressindexedfrom, addressindexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/eventTransferBatch(addressindexed operator,
addressindexedfrom,
addressindexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/eventApprovalForAll(addressindexed account, addressindexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/eventURI(string value, uint256indexed id);
/**
* @dev Returns the value of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/functionbalanceOf(address account, uint256 id) externalviewreturns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/functionbalanceOfBatch(address[] calldata accounts,
uint256[] calldata ids
) externalviewreturns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/functionsetApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/functionisApprovedForAll(address account, address operator) externalviewreturns (bool);
/**
* @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`.
*
* WARNING: This function can potentially allow a reentrancy attack when transferring tokens
* to an untrusted contract, when invoking {onERC1155Received} on the receiver.
* Ensure to follow the checks-effects-interactions pattern and consider employing
* reentrancy guards when interacting with untrusted contracts.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `value` amount.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/functionsafeTransferFrom(addressfrom, address to, uint256 id, uint256 value, bytescalldata data) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
*
* WARNING: This function can potentially allow a reentrancy attack when transferring tokens
* to an untrusted contract, when invoking {onERC1155BatchReceived} on the receiver.
* Ensure to follow the checks-effects-interactions pattern and consider employing
* reentrancy guards when interacting with untrusted contracts.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `values` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/functionsafeBatchTransferFrom(addressfrom,
address to,
uint256[] calldata ids,
uint256[] calldata values,
bytescalldata data
) external;
}
Contract Source Code
File 7 of 13: IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/extensions/IERC1155MetadataURI.sol)pragmasolidity ^0.8.20;import {IERC1155} from"../IERC1155.sol";
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
*/interfaceIERC1155MetadataURIisIERC1155{
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/functionuri(uint256 id) externalviewreturns (stringmemory);
}
Contract Source Code
File 8 of 13: IERC1155Receiver.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/IERC1155Receiver.sol)pragmasolidity ^0.8.20;import {IERC165} from"../../utils/introspection/IERC165.sol";
/**
* @dev Interface that must be implemented by smart contracts in order to receive
* ERC-1155 token transfers.
*/interfaceIERC1155ReceiverisIERC165{
/**
* @dev Handles the receipt of a single ERC1155 token type. This function is
* called at the end of a `safeTransferFrom` after the balance has been updated.
*
* NOTE: To accept the transfer, this must return
* `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* (i.e. 0xf23a6e61, or its own function selector).
*
* @param operator The address which initiated the transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param id The ID of the token being transferred
* @param value The amount of tokens being transferred
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/functiononERC1155Received(address operator,
addressfrom,
uint256 id,
uint256 value,
bytescalldata data
) externalreturns (bytes4);
/**
* @dev Handles the receipt of a multiple ERC1155 token types. This function
* is called at the end of a `safeBatchTransferFrom` after the balances have
* been updated.
*
* NOTE: To accept the transfer(s), this must return
* `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* (i.e. 0xbc197c81, or its own function selector).
*
* @param operator The address which initiated the batch transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param ids An array containing ids of each token being transferred (order and length must match values array)
* @param values An array containing amounts of each token being transferred (order and length must match ids array)
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/functiononERC1155BatchReceived(address operator,
addressfrom,
uint256[] calldata ids,
uint256[] calldata values,
bytescalldata data
) externalreturns (bytes4);
}
Contract Source Code
File 9 of 13: IERC165.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)pragmasolidity ^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}.
*/interfaceIERC165{
/**
* @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.
*/functionsupportsInterface(bytes4 interfaceId) externalviewreturns (bool);
}
Contract Source Code
File 10 of 13: Math.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)pragmasolidity ^0.8.20;/**
* @dev Standard math utilities missing in the Solidity language.
*/libraryMath{
/**
* @dev Muldiv operation overflow.
*/errorMathOverflowedMulDiv();
enumRounding {
Floor, // Toward negative infinity
Ceil, // Toward positive infinity
Trunc, // Toward zero
Expand // Away from zero
}
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*/functiontryAdd(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*/functiontrySub(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*/functiontryMul(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522if (a ==0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*/functiontryDiv(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
unchecked {
if (b ==0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*/functiontryMod(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
unchecked {
if (b ==0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the largest of two numbers.
*/functionmax(uint256 a, uint256 b) internalpurereturns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/functionmin(uint256 a, uint256 b) internalpurereturns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/functionaverage(uint256 a, uint256 b) internalpurereturns (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.
*/functionceilDiv(uint256 a, uint256 b) internalpurereturns (uint256) {
if (b ==0) {
// Guarantee the same behavior as in a regular Solidity division.return a / b;
}
// (a + b - 1) / b can overflow on addition, so we distribute.return a ==0 ? 0 : (a -1) / b +1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
* denominator == 0.
* @dev 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.
*/functionmulDiv(uint256 x, uint256 y, uint256 denominator) internalpurereturns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256// variables such that product = prod1 * 2^256 + prod0.uint256 prod0 = x * y; // Least significant 256 bits of the productuint256 prod1; // Most significant 256 bits of the productassembly {
let mm :=mulmod(x, y, not(0))
prod1 :=sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.if (prod1 ==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 prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
///////////////////////////////////////////////// 512 by 256 division.///////////////////////////////////////////////// Make division exact by subtracting the remainder from [prod1 prod0].uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder :=mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 :=sub(prod1, gt(remainder, prod0))
prod0 :=sub(prod0, 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 {
// Divide denominator by twos.
denominator :=div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 :=div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos :=add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for// four bits. That is, denominator * inv = 1 mod 2^4.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^8
inverse *=2- denominator * inverse; // inverse mod 2^16
inverse *=2- denominator * inverse; // inverse mod 2^32
inverse *=2- denominator * inverse; // inverse mod 2^64
inverse *=2- denominator * inverse; // inverse mod 2^128
inverse *=2- denominator * inverse; // inverse mod 2^256// 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^256. Since the preconditions guarantee that the outcome is// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/functionmulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internalpurereturns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (unsignedRoundsUp(rounding) &&mulmod(x, y, denominator) >0) {
result +=1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
* towards zero.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/functionsqrt(uint256 a) internalpurereturns (uint256) {
if (a ==0) {
return0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.//// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.//// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`//// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.uint256 result =1<< (log2(a) >>1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision// into the expected uint128 result.unchecked {
result = (result + a / result) >>1;
result = (result + a / result) >>1;
result = (result + a / result) >>1;
result = (result + a / result) >>1;
result = (result + a / result) >>1;
result = (result + a / result) >>1;
result = (result + a / result) >>1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/functionsqrt(uint256 a, Rounding rounding) internalpurereturns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/functionlog2(uint256 value) internalpurereturns (uint256) {
uint256 result =0;
unchecked {
if (value >>128>0) {
value >>=128;
result +=128;
}
if (value >>64>0) {
value >>=64;
result +=64;
}
if (value >>32>0) {
value >>=32;
result +=32;
}
if (value >>16>0) {
value >>=16;
result +=16;
}
if (value >>8>0) {
value >>=8;
result +=8;
}
if (value >>4>0) {
value >>=4;
result +=4;
}
if (value >>2>0) {
value >>=2;
result +=2;
}
if (value >>1>0) {
result +=1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/functionlog2(uint256 value, Rounding rounding) internalpurereturns (uint256) {
unchecked {
uint256 result =log2(value);
return result + (unsignedRoundsUp(rounding) &&1<< result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/functionlog10(uint256 value) internalpurereturns (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.
*/functionlog10(uint256 value, Rounding rounding) internalpurereturns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (unsignedRoundsUp(rounding) &&10** result < value ? 1 : 0);
}
}
/**
* @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.
*/functionlog256(uint256 value) internalpurereturns (uint256) {
uint256 result =0;
unchecked {
if (value >>128>0) {
value >>=128;
result +=16;
}
if (value >>64>0) {
value >>=64;
result +=8;
}
if (value >>32>0) {
value >>=32;
result +=4;
}
if (value >>16>0) {
value >>=16;
result +=2;
}
if (value >>8>0) {
result +=1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/functionlog256(uint256 value, Rounding rounding) internalpurereturns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (unsignedRoundsUp(rounding) &&1<< (result <<3) < value ? 1 : 0);
}
}
/**
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
*/functionunsignedRoundsUp(Rounding rounding) internalpurereturns (bool) {
returnuint8(rounding) %2==1;
}
}
Contract Source Code
File 11 of 13: Ownable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)pragmasolidity ^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.
*/abstractcontractOwnableisContext{
addressprivate _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/errorOwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/errorOwnableInvalidOwner(address owner);
eventOwnershipTransferred(addressindexed previousOwner, addressindexed 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.
*/modifieronlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/functionowner() publicviewvirtualreturns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/function_checkOwner() internalviewvirtual{
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.
*/functionrenounceOwnership() publicvirtualonlyOwner{
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/functiontransferOwnership(address newOwner) publicvirtualonlyOwner{
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) internalvirtual{
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
Contract Source Code
File 12 of 13: StorageSlot.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.pragmasolidity ^0.8.20;/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```solidity
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(newImplementation.code.length > 0);
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*/libraryStorageSlot{
structAddressSlot {
address value;
}
structBooleanSlot {
bool value;
}
structBytes32Slot {
bytes32 value;
}
structUint256Slot {
uint256 value;
}
structStringSlot {
string value;
}
structBytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/functiongetAddressSlot(bytes32 slot) internalpurereturns (AddressSlot storage r) {
/// @solidity memory-safe-assemblyassembly {
r.slot:= slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/functiongetBooleanSlot(bytes32 slot) internalpurereturns (BooleanSlot storage r) {
/// @solidity memory-safe-assemblyassembly {
r.slot:= slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/functiongetBytes32Slot(bytes32 slot) internalpurereturns (Bytes32Slot storage r) {
/// @solidity memory-safe-assemblyassembly {
r.slot:= slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/functiongetUint256Slot(bytes32 slot) internalpurereturns (Uint256Slot storage r) {
/// @solidity memory-safe-assemblyassembly {
r.slot:= slot
}
}
/**
* @dev Returns an `StringSlot` with member `value` located at `slot`.
*/functiongetStringSlot(bytes32 slot) internalpurereturns (StringSlot storage r) {
/// @solidity memory-safe-assemblyassembly {
r.slot:= slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/functiongetStringSlot(stringstorage store) internalpurereturns (StringSlot storage r) {
/// @solidity memory-safe-assemblyassembly {
r.slot:= store.slot
}
}
/**
* @dev Returns an `BytesSlot` with member `value` located at `slot`.
*/functiongetBytesSlot(bytes32 slot) internalpurereturns (BytesSlot storage r) {
/// @solidity memory-safe-assemblyassembly {
r.slot:= slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/functiongetBytesSlot(bytesstorage store) internalpurereturns (BytesSlot storage r) {
/// @solidity memory-safe-assemblyassembly {
r.slot:= store.slot
}
}
}
Contract Source Code
File 13 of 13: draft-IERC6093.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)pragmasolidity ^0.8.20;/**
* @dev Standard ERC20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
*/interfaceIERC20Errors{
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/errorERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/errorERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/errorERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/errorERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/errorERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/errorERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
*/interfaceIERC721Errors{
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/errorERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/errorERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/errorERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/errorERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/errorERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/errorERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/errorERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/errorERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
*/interfaceIERC1155Errors{
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/errorERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/errorERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/errorERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/errorERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/errorERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/errorERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/errorERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}