Feature Tip: Add private address tag to any address under My Name Tag !
Overview
TokenID
80
Total Transfers
-
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
MiladyStationRejects
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-05-15 */ // File: solady/utils/LibString.sol pragma solidity ^0.8.4; /// @notice Library for converting numbers into strings and other string operations. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) library LibString { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The `length` of the output is too small to contain all the hex digits. error HexLengthInsufficient(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The constant returned when the `search` is not found in the string. uint256 internal constant NOT_FOUND = type(uint256).max; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* DECIMAL OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the base 10 decimal representation of `value`. function toString(uint256 value) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* HEXADECIMAL OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the hexadecimal representation of `value`, /// left-padded to an input length of `length` bytes. /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte, /// giving a total length of `length * 2 + 2` bytes. /// Reverts if `length` is too small for the output to contain all the digits. function toHexString(uint256 value, uint256 length) internal pure returns (string memory str) { str = toHexStringNoPrefix(value, length); /// @solidity memory-safe-assembly assembly { let strLength := add(mload(str), 2) // Compute the length. mstore(str, 0x3078) // Write the "0x" prefix. str := sub(str, 2) // Move the pointer. mstore(str, strLength) // Write the length. } } /// @dev Returns the hexadecimal representation of `value`, /// left-padded to an input length of `length` bytes. /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte, /// giving a total length of `length * 2` bytes. /// Reverts if `length` is too small for the output to contain all the digits. function toHexStringNoPrefix(uint256 value, uint256 length) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { let start := mload(0x40) // We need 0x20 bytes for the trailing zeros padding, `length * 2` bytes // for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length. // We add 0x20 to the total and round down to a multiple of 0x20. // (0x20 + 0x20 + 0x02 + 0x20) = 0x62. let m := add(start, and(add(shl(1, length), 0x62), not(0x1f))) // Allocate the memory. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end to calculate the length later. let end := str // Store "0123456789abcdef" in scratch space. mstore(0x0f, 0x30313233343536373839616263646566) let temp := value // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for {} 1 {} { str := sub(str, 2) mstore8(add(str, 1), mload(and(temp, 15))) mstore8(str, mload(and(shr(4, temp), 15))) temp := shr(8, temp) length := sub(length, 1) if iszero(length) { break } } if temp { // Store the function selector of `HexLengthInsufficient()`. mstore(0x00, 0x2194895a) // Revert with (offset, size). revert(0x1c, 0x04) } // Compute the string's length. let strLength := sub(end, str) // Move the pointer and write the length. str := sub(str, 0x20) mstore(str, strLength) } } /// @dev Returns the hexadecimal representation of `value`. /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte. /// As address are 20 bytes long, the output will left-padded to have /// a length of `20 * 2 + 2` bytes. function toHexString(uint256 value) internal pure returns (string memory str) { str = toHexStringNoPrefix(value); /// @solidity memory-safe-assembly assembly { let strLength := add(mload(str), 2) // Compute the length. mstore(str, 0x3078) // Write the "0x" prefix. str := sub(str, 2) // Move the pointer. mstore(str, strLength) // Write the length. } } /// @dev Returns the hexadecimal representation of `value`. /// The output is encoded using 2 hexadecimal digits per byte. /// As address are 20 bytes long, the output will left-padded to have /// a length of `20 * 2` bytes. function toHexStringNoPrefix(uint256 value) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { let start := mload(0x40) // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length, // 0x02 bytes for the prefix, and 0x40 bytes for the digits. // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0. let m := add(start, 0xa0) // Allocate the memory. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end to calculate the length later. let end := str // Store "0123456789abcdef" in scratch space. mstore(0x0f, 0x30313233343536373839616263646566) // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for { let temp := value } 1 {} { str := sub(str, 2) mstore8(add(str, 1), mload(and(temp, 15))) mstore8(str, mload(and(shr(4, temp), 15))) temp := shr(8, temp) if iszero(temp) { break } } // Compute the string's length. let strLength := sub(end, str) // Move the pointer and write the length. str := sub(str, 0x20) mstore(str, strLength) } } /// @dev Returns the hexadecimal representation of `value`. /// The output is prefixed with "0x", encoded using 2 hexadecimal digits per byte, /// and the alphabets are capitalized conditionally according to /// https://eips.ethereum.org/EIPS/eip-55 function toHexStringChecksumed(address value) internal pure returns (string memory str) { str = toHexString(value); /// @solidity memory-safe-assembly assembly { let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...` let o := add(str, 0x22) let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... ` let t := shl(240, 136) // `0b10001000 << 240` for { let i := 0 } 1 {} { mstore(add(i, i), mul(t, byte(i, hashed))) i := add(i, 1) if eq(i, 20) { break } } mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask))))) o := add(o, 0x20) mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask))))) } } /// @dev Returns the hexadecimal representation of `value`. /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte. function toHexString(address value) internal pure returns (string memory str) { str = toHexStringNoPrefix(value); /// @solidity memory-safe-assembly assembly { let strLength := add(mload(str), 2) // Compute the length. mstore(str, 0x3078) // Write the "0x" prefix. str := sub(str, 2) // Move the pointer. mstore(str, strLength) // Write the length. } } /// @dev Returns the hexadecimal representation of `value`. /// The output is encoded using 2 hexadecimal digits per byte. function toHexStringNoPrefix(address value) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { str := mload(0x40) // Allocate the memory. // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length, // 0x02 bytes for the prefix, and 0x28 bytes for the digits. // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80. mstore(0x40, add(str, 0x80)) // Store "0123456789abcdef" in scratch space. mstore(0x0f, 0x30313233343536373839616263646566) str := add(str, 2) mstore(str, 40) let o := add(str, 0x20) mstore(add(o, 40), 0) value := shl(96, value) // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for { let i := 0 } 1 {} { let p := add(o, add(i, i)) let temp := byte(i, value) mstore8(add(p, 1), mload(and(temp, 15))) mstore8(p, mload(shr(4, temp))) i := add(i, 1) if eq(i, 20) { break } } } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* RUNE STRING OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the number of UTF characters in the string. function runeCount(string memory s) internal pure returns (uint256 result) { /// @solidity memory-safe-assembly assembly { if mload(s) { mstore(0x00, div(not(0), 255)) mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506) let o := add(s, 0x20) let end := add(o, mload(s)) for { result := 1 } 1 { result := add(result, 1) } { o := add(o, byte(0, mload(shr(250, mload(o))))) if iszero(lt(o, end)) { break } } } } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* BYTE STRING OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // For performance and bytecode compactness, all indices of the following operations // are byte (ASCII) offsets, not UTF character offsets. /// @dev Returns `subject` all occurrences of `search` replaced with `replacement`. function replace(string memory subject, string memory search, string memory replacement) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let subjectLength := mload(subject) let searchLength := mload(search) let replacementLength := mload(replacement) subject := add(subject, 0x20) search := add(search, 0x20) replacement := add(replacement, 0x20) result := add(mload(0x40), 0x20) let subjectEnd := add(subject, subjectLength) if iszero(gt(searchLength, subjectLength)) { let subjectSearchEnd := add(sub(subjectEnd, searchLength), 1) let h := 0 if iszero(lt(searchLength, 32)) { h := keccak256(search, searchLength) } let m := shl(3, sub(32, and(searchLength, 31))) let s := mload(search) for {} 1 {} { let t := mload(subject) // Whether the first `searchLength % 32` bytes of // `subject` and `search` matches. if iszero(shr(m, xor(t, s))) { if h { if iszero(eq(keccak256(subject, searchLength), h)) { mstore(result, t) result := add(result, 1) subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } continue } } // Copy the `replacement` one word at a time. for { let o := 0 } 1 {} { mstore(add(result, o), mload(add(replacement, o))) o := add(o, 0x20) if iszero(lt(o, replacementLength)) { break } } result := add(result, replacementLength) subject := add(subject, searchLength) if searchLength { if iszero(lt(subject, subjectSearchEnd)) { break } continue } } mstore(result, t) result := add(result, 1) subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } } } let resultRemainder := result result := add(mload(0x40), 0x20) let k := add(sub(resultRemainder, result), sub(subjectEnd, subject)) // Copy the rest of the string one word at a time. for {} lt(subject, subjectEnd) {} { mstore(resultRemainder, mload(subject)) resultRemainder := add(resultRemainder, 0x20) subject := add(subject, 0x20) } result := sub(result, 0x20) // Zeroize the slot after the string. let last := add(add(result, 0x20), k) mstore(last, 0) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, and(add(last, 31), not(31))) // Store the length of the result. mstore(result, k) } } /// @dev Returns the byte index of the first location of `search` in `subject`, /// searching from left to right, starting from `from`. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. function indexOf(string memory subject, string memory search, uint256 from) internal pure returns (uint256 result) { /// @solidity memory-safe-assembly assembly { for { let subjectLength := mload(subject) } 1 {} { if iszero(mload(search)) { // `result = min(from, subjectLength)`. result := xor(from, mul(xor(from, subjectLength), lt(subjectLength, from))) break } let searchLength := mload(search) let subjectStart := add(subject, 0x20) result := not(0) // Initialize to `NOT_FOUND`. subject := add(subjectStart, from) let subjectSearchEnd := add(sub(add(subjectStart, subjectLength), searchLength), 1) let m := shl(3, sub(32, and(searchLength, 31))) let s := mload(add(search, 0x20)) if iszero(lt(subject, subjectSearchEnd)) { break } if iszero(lt(searchLength, 32)) { for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} { if iszero(shr(m, xor(mload(subject), s))) { if eq(keccak256(subject, searchLength), h) { result := sub(subject, subjectStart) break } } subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } } break } for {} 1 {} { if iszero(shr(m, xor(mload(subject), s))) { result := sub(subject, subjectStart) break } subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } } break } } } /// @dev Returns the byte index of the first location of `search` in `subject`, /// searching from left to right. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. function indexOf(string memory subject, string memory search) internal pure returns (uint256 result) { result = indexOf(subject, search, 0); } /// @dev Returns the byte index of the first location of `search` in `subject`, /// searching from right to left, starting from `from`. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. function lastIndexOf(string memory subject, string memory search, uint256 from) internal pure returns (uint256 result) { /// @solidity memory-safe-assembly assembly { for {} 1 {} { let searchLength := mload(search) let fromMax := sub(mload(subject), searchLength) if iszero(gt(fromMax, from)) { from := fromMax } if iszero(mload(search)) { result := from break } result := not(0) // Initialize to `NOT_FOUND`. let subjectSearchEnd := sub(add(subject, 0x20), 1) subject := add(add(subject, 0x20), from) if iszero(gt(subject, subjectSearchEnd)) { break } // As this function is not too often used, // we shall simply use keccak256 for smaller bytecode size. for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} { if eq(keccak256(subject, searchLength), h) { result := sub(subject, add(subjectSearchEnd, 1)) break } subject := sub(subject, 1) if iszero(gt(subject, subjectSearchEnd)) { break } } break } } } /// @dev Returns the byte index of the first location of `search` in `subject`, /// searching from right to left. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. function lastIndexOf(string memory subject, string memory search) internal pure returns (uint256 result) { result = lastIndexOf(subject, search, uint256(int256(-1))); } /// @dev Returns whether `subject` starts with `search`. function startsWith(string memory subject, string memory search) internal pure returns (bool result) { /// @solidity memory-safe-assembly assembly { let searchLength := mload(search) // Just using keccak256 directly is actually cheaper. // forgefmt: disable-next-item result := and( iszero(gt(searchLength, mload(subject))), eq( keccak256(add(subject, 0x20), searchLength), keccak256(add(search, 0x20), searchLength) ) ) } } /// @dev Returns whether `subject` ends with `search`. function endsWith(string memory subject, string memory search) internal pure returns (bool result) { /// @solidity memory-safe-assembly assembly { let searchLength := mload(search) let subjectLength := mload(subject) // Whether `search` is not longer than `subject`. let withinRange := iszero(gt(searchLength, subjectLength)) // Just using keccak256 directly is actually cheaper. // forgefmt: disable-next-item result := and( withinRange, eq( keccak256( // `subject + 0x20 + max(subjectLength - searchLength, 0)`. add(add(subject, 0x20), mul(withinRange, sub(subjectLength, searchLength))), searchLength ), keccak256(add(search, 0x20), searchLength) ) ) } } /// @dev Returns `subject` repeated `times`. function repeat(string memory subject, uint256 times) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let subjectLength := mload(subject) if iszero(or(iszero(times), iszero(subjectLength))) { subject := add(subject, 0x20) result := mload(0x40) let output := add(result, 0x20) for {} 1 {} { // Copy the `subject` one word at a time. for { let o := 0 } 1 {} { mstore(add(output, o), mload(add(subject, o))) o := add(o, 0x20) if iszero(lt(o, subjectLength)) { break } } output := add(output, subjectLength) times := sub(times, 1) if iszero(times) { break } } // Zeroize the slot after the string. mstore(output, 0) // Store the length. let resultLength := sub(output, add(result, 0x20)) mstore(result, resultLength) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, add(result, and(add(resultLength, 63), not(31)))) } } } /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive). /// `start` and `end` are byte offsets. function slice(string memory subject, uint256 start, uint256 end) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let subjectLength := mload(subject) if iszero(gt(subjectLength, end)) { end := subjectLength } if iszero(gt(subjectLength, start)) { start := subjectLength } if lt(start, end) { result := mload(0x40) let resultLength := sub(end, start) mstore(result, resultLength) subject := add(subject, start) let w := not(31) // Copy the `subject` one word at a time, backwards. for { let o := and(add(resultLength, 31), w) } 1 {} { mstore(add(result, o), mload(add(subject, o))) o := add(o, w) // `sub(o, 0x20)`. if iszero(o) { break } } // Zeroize the slot after the string. mstore(add(add(result, 0x20), resultLength), 0) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, add(result, and(add(resultLength, 63), w))) } } } /// @dev Returns a copy of `subject` sliced from `start` to the end of the string. /// `start` is a byte offset. function slice(string memory subject, uint256 start) internal pure returns (string memory result) { result = slice(subject, start, uint256(int256(-1))); } /// @dev Returns all the indices of `search` in `subject`. /// The indices are byte offsets. function indicesOf(string memory subject, string memory search) internal pure returns (uint256[] memory result) { /// @solidity memory-safe-assembly assembly { let subjectLength := mload(subject) let searchLength := mload(search) if iszero(gt(searchLength, subjectLength)) { subject := add(subject, 0x20) search := add(search, 0x20) result := add(mload(0x40), 0x20) let subjectStart := subject let subjectSearchEnd := add(sub(add(subject, subjectLength), searchLength), 1) let h := 0 if iszero(lt(searchLength, 32)) { h := keccak256(search, searchLength) } let m := shl(3, sub(32, and(searchLength, 31))) let s := mload(search) for {} 1 {} { let t := mload(subject) // Whether the first `searchLength % 32` bytes of // `subject` and `search` matches. if iszero(shr(m, xor(t, s))) { if h { if iszero(eq(keccak256(subject, searchLength), h)) { subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } continue } } // Append to `result`. mstore(result, sub(subject, subjectStart)) result := add(result, 0x20) // Advance `subject` by `searchLength`. subject := add(subject, searchLength) if searchLength { if iszero(lt(subject, subjectSearchEnd)) { break } continue } } subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } } let resultEnd := result // Assign `result` to the free memory pointer. result := mload(0x40) // Store the length of `result`. mstore(result, shr(5, sub(resultEnd, add(result, 0x20)))) // Allocate memory for result. // We allocate one more word, so this array can be recycled for {split}. mstore(0x40, add(resultEnd, 0x20)) } } } /// @dev Returns a arrays of strings based on the `delimiter` inside of the `subject` string. function split(string memory subject, string memory delimiter) internal pure returns (string[] memory result) { uint256[] memory indices = indicesOf(subject, delimiter); /// @solidity memory-safe-assembly assembly { let w := not(31) let indexPtr := add(indices, 0x20) let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1))) mstore(add(indicesEnd, w), mload(subject)) mstore(indices, add(mload(indices), 1)) let prevIndex := 0 for {} 1 {} { let index := mload(indexPtr) mstore(indexPtr, 0x60) if iszero(eq(index, prevIndex)) { let element := mload(0x40) let elementLength := sub(index, prevIndex) mstore(element, elementLength) // Copy the `subject` one word at a time, backwards. for { let o := and(add(elementLength, 31), w) } 1 {} { mstore(add(element, o), mload(add(add(subject, prevIndex), o))) o := add(o, w) // `sub(o, 0x20)`. if iszero(o) { break } } // Zeroize the slot after the string. mstore(add(add(element, 0x20), elementLength), 0) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, add(element, and(add(elementLength, 63), w))) // Store the `element` into the array. mstore(indexPtr, element) } prevIndex := add(index, mload(delimiter)) indexPtr := add(indexPtr, 0x20) if iszero(lt(indexPtr, indicesEnd)) { break } } result := indices if iszero(mload(delimiter)) { result := add(indices, 0x20) mstore(result, sub(mload(indices), 2)) } } } /// @dev Returns a concatenated string of `a` and `b`. /// Cheaper than `string.concat()` and does not de-align the free memory pointer. function concat(string memory a, string memory b) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let w := not(31) result := mload(0x40) let aLength := mload(a) // Copy `a` one word at a time, backwards. for { let o := and(add(mload(a), 32), w) } 1 {} { mstore(add(result, o), mload(add(a, o))) o := add(o, w) // `sub(o, 0x20)`. if iszero(o) { break } } let bLength := mload(b) let output := add(result, mload(a)) // Copy `b` one word at a time, backwards. for { let o := and(add(bLength, 32), w) } 1 {} { mstore(add(output, o), mload(add(b, o))) o := add(o, w) // `sub(o, 0x20)`. if iszero(o) { break } } let totalLength := add(aLength, bLength) let last := add(add(result, 0x20), totalLength) // Zeroize the slot after the string. mstore(last, 0) // Stores the length. mstore(result, totalLength) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, and(add(last, 31), w)) } } /// @dev Returns a copy of the string in either lowercase or UPPERCASE. function toCase(string memory subject, bool toUpper) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let length := mload(subject) if length { result := add(mload(0x40), 0x20) subject := add(subject, 1) let flags := shl(add(70, shl(5, toUpper)), 67108863) let w := not(0) for { let o := length } 1 {} { o := add(o, w) let b := and(0xff, mload(add(subject, o))) mstore8(add(result, o), xor(b, and(shr(b, flags), 0x20))) if iszero(o) { break } } // Restore the result. result := mload(0x40) // Stores the string length. mstore(result, length) // Zeroize the slot after the string. let last := add(add(result, 0x20), length) mstore(last, 0) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, and(add(last, 31), not(31))) } } } /// @dev Returns a lowercased copy of the string. function lower(string memory subject) internal pure returns (string memory result) { result = toCase(subject, false); } /// @dev Returns an UPPERCASED copy of the string. function upper(string memory subject) internal pure returns (string memory result) { result = toCase(subject, true); } /// @dev Escapes the string to be used within HTML tags. function escapeHTML(string memory s) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { for { let end := add(s, mload(s)) result := add(mload(0x40), 0x20) // Store the bytes of the packed offsets and strides into the scratch space. // `packed = (stride << 5) | offset`. Max offset is 20. Max stride is 6. mstore(0x1f, 0x900094) mstore(0x08, 0xc0000000a6ab) // Store ""&'<>" into the scratch space. mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b)) } iszero(eq(s, end)) {} { s := add(s, 1) let c := and(mload(s), 0xff) // Not in `["\"","'","&","<",">"]`. if iszero(and(shl(c, 1), 0x500000c400000000)) { mstore8(result, c) result := add(result, 1) continue } let t := shr(248, mload(c)) mstore(result, mload(and(t, 31))) result := add(result, shr(5, t)) } let last := result // Zeroize the slot after the string. mstore(last, 0) // Restore the result to the start of the free memory. result := mload(0x40) // Store the length of the result. mstore(result, sub(last, add(result, 0x20))) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, and(add(last, 31), not(31))) } } /// @dev Escapes the string to be used within double-quotes in a JSON. function escapeJSON(string memory s) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { for { let end := add(s, mload(s)) result := add(mload(0x40), 0x20) // Store "\\u0000" in scratch space. // Store "0123456789abcdef" in scratch space. // Also, store `{0x08:"b", 0x09:"t", 0x0a:"n", 0x0c:"f", 0x0d:"r"}`. // into the scratch space. mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672) // Bitmask for detecting `["\"","\\"]`. let e := or(shl(0x22, 1), shl(0x5c, 1)) } iszero(eq(s, end)) {} { s := add(s, 1) let c := and(mload(s), 0xff) if iszero(lt(c, 0x20)) { if iszero(and(shl(c, 1), e)) { // Not in `["\"","\\"]`. mstore8(result, c) result := add(result, 1) continue } mstore8(result, 0x5c) // "\\". mstore8(add(result, 1), c) result := add(result, 2) continue } if iszero(and(shl(c, 1), 0x3700)) { // Not in `["\b","\t","\n","\f","\d"]`. mstore8(0x1d, mload(shr(4, c))) // Hex value. mstore8(0x1e, mload(and(c, 15))) // Hex value. mstore(result, mload(0x19)) // "\\u00XX". result := add(result, 6) continue } mstore8(result, 0x5c) // "\\". mstore8(add(result, 1), mload(add(c, 8))) result := add(result, 2) } let last := result // Zeroize the slot after the string. mstore(last, 0) // Restore the result to the start of the free memory. result := mload(0x40) // Store the length of the result. mstore(result, sub(last, add(result, 0x20))) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, and(add(last, 31), not(31))) } } /// @dev Returns whether `a` equals `b`. function eq(string memory a, string memory b) internal pure returns (bool result) { assembly { result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b))) } } /// @dev Packs a single string with its length into a single word. /// Returns `bytes32(0)` if the length is zero or greater than 31. function packOne(string memory a) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { // We don't need to zero right pad the string, // since this is our own custom non-standard packing scheme. result := mul( // Load the length and the bytes. mload(add(a, 0x1f)), // `length != 0 && length < 32`. Abuses underflow. // Assumes that the length is valid and within the block gas limit. lt(sub(mload(a), 1), 0x1f) ) } } /// @dev Unpacks a string packed using {packOne}. /// Returns the empty string if `packed` is `bytes32(0)`. /// If `packed` is not an output of {packOne}, the output behaviour is undefined. function unpackOne(bytes32 packed) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { // Grab the free memory pointer. result := mload(0x40) // Allocate 2 words (1 for the length, 1 for the bytes). mstore(0x40, add(result, 0x40)) // Zeroize the length slot. mstore(result, 0) // Store the length and bytes. mstore(add(result, 0x1f), packed) // Right pad with zeroes. mstore(add(add(result, 0x20), mload(result)), 0) } } /// @dev Packs two strings with their lengths into a single word. /// Returns `bytes32(0)` if combined length is zero or greater than 30. function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { let aLength := mload(a) // We don't need to zero right pad the strings, // since this is our own custom non-standard packing scheme. result := mul( // Load the length and the bytes of `a` and `b`. or( shl(shl(3, sub(0x1f, aLength)), mload(add(a, aLength))), mload(sub(add(b, 0x1e), aLength)) ), // `totalLength != 0 && totalLength < 31`. Abuses underflow. // Assumes that the lengths are valid and within the block gas limit. lt(sub(add(aLength, mload(b)), 1), 0x1e) ) } } /// @dev Unpacks strings packed using {packTwo}. /// Returns the empty strings if `packed` is `bytes32(0)`. /// If `packed` is not an output of {packTwo}, the output behaviour is undefined. function unpackTwo(bytes32 packed) internal pure returns (string memory resultA, string memory resultB) { /// @solidity memory-safe-assembly assembly { // Grab the free memory pointer. resultA := mload(0x40) resultB := add(resultA, 0x40) // Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words. mstore(0x40, add(resultB, 0x40)) // Zeroize the length slots. mstore(resultA, 0) mstore(resultB, 0) // Store the lengths and bytes. mstore(add(resultA, 0x1f), packed) mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA)))) // Right pad with zeroes. mstore(add(add(resultA, 0x20), mload(resultA)), 0) mstore(add(add(resultB, 0x20), mload(resultB)), 0) } } /// @dev Directly returns `a` without copying. function directReturn(string memory a) internal pure { assembly { // Assumes that the string does not start from the scratch space. let retStart := sub(a, 0x20) let retSize := add(mload(a), 0x40) // Right pad with zeroes. Just in case the string is produced // by a method that doesn't zero right pad. mstore(add(retStart, retSize), 0) // Store the return offset. mstore(retStart, 0x20) // End the transaction, returning the string. return(retStart, retSize) } } } // File: solady/utils/MerkleProofLib.sol pragma solidity ^0.8.4; /// @notice Gas optimized verification of proof of inclusion for a leaf in a Merkle tree. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/MerkleProofLib.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/MerkleProof.sol) library MerkleProofLib { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* MERKLE PROOF VERIFICATION OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`. function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool isValid) { /// @solidity memory-safe-assembly assembly { if mload(proof) { // Initialize `offset` to the offset of `proof` elements in memory. let offset := add(proof, 0x20) // Left shift by 5 is equivalent to multiplying by 0x20. let end := add(offset, shl(5, mload(proof))) // Iterate over proof elements to compute root hash. for {} 1 {} { // Slot of `leaf` in scratch space. // If the condition is true: 0x20, otherwise: 0x00. let scratch := shl(5, gt(leaf, mload(offset))) // Store elements to hash contiguously in scratch space. // Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes. mstore(scratch, leaf) mstore(xor(scratch, 0x20), mload(offset)) // Reuse `leaf` to store the hash to reduce stack operations. leaf := keccak256(0x00, 0x40) offset := add(offset, 0x20) if iszero(lt(offset, end)) { break } } } isValid := eq(leaf, root) } } /// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`. function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool isValid) { /// @solidity memory-safe-assembly assembly { if proof.length { // Left shift by 5 is equivalent to multiplying by 0x20. let end := add(proof.offset, shl(5, proof.length)) // Initialize `offset` to the offset of `proof` in the calldata. let offset := proof.offset // Iterate over proof elements to compute root hash. for {} 1 {} { // Slot of `leaf` in scratch space. // If the condition is true: 0x20, otherwise: 0x00. let scratch := shl(5, gt(leaf, calldataload(offset))) // Store elements to hash contiguously in scratch space. // Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes. mstore(scratch, leaf) mstore(xor(scratch, 0x20), calldataload(offset)) // Reuse `leaf` to store the hash to reduce stack operations. leaf := keccak256(0x00, 0x40) offset := add(offset, 0x20) if iszero(lt(offset, end)) { break } } } isValid := eq(leaf, root) } } /// @dev Returns whether all `leafs` exist in the Merkle tree with `root`, /// given `proof` and `flags`. function verifyMultiProof( bytes32[] memory proof, bytes32 root, bytes32[] memory leafs, bool[] memory flags ) internal pure returns (bool isValid) { // Rebuilds the root by consuming and producing values on a queue. // The queue starts with the `leafs` array, and goes into a `hashes` array. // After the process, the last element on the queue is verified // to be equal to the `root`. // // The `flags` array denotes whether the sibling // should be popped from the queue (`flag == true`), or // should be popped from the `proof` (`flag == false`). /// @solidity memory-safe-assembly assembly { // Cache the lengths of the arrays. let leafsLength := mload(leafs) let proofLength := mload(proof) let flagsLength := mload(flags) // Advance the pointers of the arrays to point to the data. leafs := add(0x20, leafs) proof := add(0x20, proof) flags := add(0x20, flags) // If the number of flags is correct. for {} eq(add(leafsLength, proofLength), add(flagsLength, 1)) {} { // For the case where `proof.length + leafs.length == 1`. if iszero(flagsLength) { // `isValid = (proof.length == 1 ? proof[0] : leafs[0]) == root`. isValid := eq(mload(xor(leafs, mul(xor(proof, leafs), proofLength))), root) break } // We can use the free memory space for the queue. // We don't need to allocate, since the queue is temporary. let hashesFront := mload(0x40) // Copy the leafs into the hashes. // Sometimes, a little memory expansion costs less than branching. // Should cost less, even with a high free memory offset of 0x7d00. // Left shift by 5 is equivalent to multiplying by 0x20. leafsLength := shl(5, leafsLength) for { let i := 0 } iszero(eq(i, leafsLength)) { i := add(i, 0x20) } { mstore(add(hashesFront, i), mload(add(leafs, i))) } // Compute the back of the hashes. let hashesBack := add(hashesFront, leafsLength) // This is the end of the memory for the queue. // We recycle `flagsLength` to save on stack variables // (this trick may not always save gas). flagsLength := add(hashesBack, shl(5, flagsLength)) for {} 1 {} { // Pop from `hashes`. let a := mload(hashesFront) // Pop from `hashes`. let b := mload(add(hashesFront, 0x20)) hashesFront := add(hashesFront, 0x40) // If the flag is false, load the next proof, // else, pops from the queue. if iszero(mload(flags)) { // Loads the next proof. b := mload(proof) proof := add(proof, 0x20) // Unpop from `hashes`. hashesFront := sub(hashesFront, 0x20) } // Advance to the next flag. flags := add(flags, 0x20) // Slot of `a` in scratch space. // If the condition is true: 0x20, otherwise: 0x00. let scratch := shl(5, gt(a, b)) // Hash the scratch space and push the result onto the queue. mstore(scratch, a) mstore(xor(scratch, 0x20), b) mstore(hashesBack, keccak256(0x00, 0x40)) hashesBack := add(hashesBack, 0x20) if iszero(lt(hashesBack, flagsLength)) { break } } // Checks if the last value in the queue is same as the root. isValid := eq(mload(sub(hashesBack, 0x20)), root) break } } } /// @dev Returns whether all `leafs` exist in the Merkle tree with `root`, /// given `proof` and `flags`. function verifyMultiProofCalldata( bytes32[] calldata proof, bytes32 root, bytes32[] calldata leafs, bool[] calldata flags ) internal pure returns (bool isValid) { // Rebuilds the root by consuming and producing values on a queue. // The queue starts with the `leafs` array, and goes into a `hashes` array. // After the process, the last element on the queue is verified // to be equal to the `root`. // // The `flags` array denotes whether the sibling // should be popped from the queue (`flag == true`), or // should be popped from the `proof` (`flag == false`). /// @solidity memory-safe-assembly assembly { // If the number of flags is correct. for {} eq(add(leafs.length, proof.length), add(flags.length, 1)) {} { // For the case where `proof.length + leafs.length == 1`. if iszero(flags.length) { // `isValid = (proof.length == 1 ? proof[0] : leafs[0]) == root`. // forgefmt: disable-next-item isValid := eq( calldataload( xor(leafs.offset, mul(xor(proof.offset, leafs.offset), proof.length)) ), root ) break } // We can use the free memory space for the queue. // We don't need to allocate, since the queue is temporary. let hashesFront := mload(0x40) // Copy the leafs into the hashes. // Sometimes, a little memory expansion costs less than branching. // Should cost less, even with a high free memory offset of 0x7d00. // Left shift by 5 is equivalent to multiplying by 0x20. calldatacopy(hashesFront, leafs.offset, shl(5, leafs.length)) // Compute the back of the hashes. let hashesBack := add(hashesFront, shl(5, leafs.length)) // This is the end of the memory for the queue. // We recycle `flags.length` to save on stack variables // (this trick may not always save gas). flags.length := add(hashesBack, shl(5, flags.length)) // We don't need to make a copy of `proof.offset` or `flags.offset`, // as they are pass-by-value (this trick may not always save gas). for {} 1 {} { // Pop from `hashes`. let a := mload(hashesFront) // Pop from `hashes`. let b := mload(add(hashesFront, 0x20)) hashesFront := add(hashesFront, 0x40) // If the flag is false, load the next proof, // else, pops from the queue. if iszero(calldataload(flags.offset)) { // Loads the next proof. b := calldataload(proof.offset) proof.offset := add(proof.offset, 0x20) // Unpop from `hashes`. hashesFront := sub(hashesFront, 0x20) } // Advance to the next flag offset. flags.offset := add(flags.offset, 0x20) // Slot of `a` in scratch space. // If the condition is true: 0x20, otherwise: 0x00. let scratch := shl(5, gt(a, b)) // Hash the scratch space and push the result onto the queue. mstore(scratch, a) mstore(xor(scratch, 0x20), b) mstore(hashesBack, keccak256(0x00, 0x40)) hashesBack := add(hashesBack, 0x20) if iszero(lt(hashesBack, flags.length)) { break } } // Checks if the last value in the queue is same as the root. isValid := eq(mload(sub(hashesBack, 0x20)), root) break } } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EMPTY CALLDATA HELPERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns an empty calldata bytes32 array. function emptyProof() internal pure returns (bytes32[] calldata proof) { /// @solidity memory-safe-assembly assembly { proof.length := 0 } } /// @dev Returns an empty calldata bytes32 array. function emptyLeafs() internal pure returns (bytes32[] calldata leafs) { /// @solidity memory-safe-assembly assembly { leafs.length := 0 } } /// @dev Returns an empty calldata bool array. function emptyFlags() internal pure returns (bool[] calldata flags) { /// @solidity memory-safe-assembly assembly { flags.length := 0 } } } // File: solady/auth/Ownable.sol pragma solidity ^0.8.4; /// @notice Simple single owner authorization mixin. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol) /// @dev While the ownable portion follows [EIP-173](https://eips.ethereum.org/EIPS/eip-173) /// for compatibility, the nomenclature for the 2-step ownership handover /// may be unique to this codebase. abstract contract Ownable { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The caller is not authorized to call the function. error Unauthorized(); /// @dev The `newOwner` cannot be the zero address. error NewOwnerIsZeroAddress(); /// @dev The `pendingOwner` does not have a valid handover request. error NoHandoverRequest(); /// @dev `bytes4(keccak256(bytes("Unauthorized()")))`. uint256 private constant _UNAUTHORIZED_ERROR_SELECTOR = 0x82b42900; /// @dev `bytes4(keccak256(bytes("NewOwnerIsZeroAddress()")))`. uint256 private constant _NEW_OWNER_IS_ZERO_ADDRESS_ERROR_SELECTOR = 0x7448fbae; /// @dev `bytes4(keccak256(bytes("NoHandoverRequest()")))`. uint256 private constant _NO_HANDOVER_REQUEST_ERROR_SELECTOR = 0x6f5e8818; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EVENTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The ownership is transferred from `oldOwner` to `newOwner`. /// This event is intentionally kept the same as OpenZeppelin's Ownable to be /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173), /// despite it not being as lightweight as a single argument event. event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); /// @dev An ownership handover to `pendingOwner` has been requested. event OwnershipHandoverRequested(address indexed pendingOwner); /// @dev The ownership handover to `pendingOwner` has been canceled. event OwnershipHandoverCanceled(address indexed pendingOwner); /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`. uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE = 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0; /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`. uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE = 0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d; /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`. uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE = 0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STORAGE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The owner slot is given by: `not(_OWNER_SLOT_NOT)`. /// It is intentionally choosen to be a high value /// to avoid collision with lower slots. /// The choice of manual storage layout is to enable compatibility /// with both regular and upgradeable contracts. uint256 private constant _OWNER_SLOT_NOT = 0x8b78c6d8; /// The ownership handover slot of `newOwner` is given by: /// ``` /// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED)) /// let handoverSlot := keccak256(0x00, 0x20) /// ``` /// It stores the expiry timestamp of the two-step ownership handover. uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Initializes the owner directly without authorization guard. /// This function must be called upon initialization, /// regardless of whether the contract is upgradeable or not. /// This is to enable generalization to both regular and upgradeable contracts, /// and to save gas in case the initial owner is not the caller. /// For performance reasons, this function will not check if there /// is an existing owner. function _initializeOwner(address newOwner) internal virtual { /// @solidity memory-safe-assembly assembly { // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Store the new value. sstore(not(_OWNER_SLOT_NOT), newOwner) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner) } } /// @dev Sets the owner directly without authorization guard. function _setOwner(address newOwner) internal virtual { /// @solidity memory-safe-assembly assembly { let ownerSlot := not(_OWNER_SLOT_NOT) // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner) // Store the new value. sstore(ownerSlot, newOwner) } } /// @dev Throws if the sender is not the owner. function _checkOwner() internal view virtual { /// @solidity memory-safe-assembly assembly { // If the caller is not the stored owner, revert. if iszero(eq(caller(), sload(not(_OWNER_SLOT_NOT)))) { mstore(0x00, _UNAUTHORIZED_ERROR_SELECTOR) revert(0x1c, 0x04) } } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PUBLIC UPDATE FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Allows the owner to transfer the ownership to `newOwner`. function transferOwnership(address newOwner) public payable virtual onlyOwner { if (newOwner == address(0)) revert NewOwnerIsZeroAddress(); _setOwner(newOwner); } /// @dev Allows the owner to renounce their ownership. function renounceOwnership() public payable virtual onlyOwner { _setOwner(address(0)); } /// @dev Request a two-step ownership handover to the caller. /// The request will be automatically expire in 48 hours (172800 seconds) by default. function requestOwnershipHandover() public payable virtual { unchecked { uint256 expires = block.timestamp + ownershipHandoverValidFor(); /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to 1. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x20), expires) // Emit the {OwnershipHandoverRequested} event. log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller()) } } } /// @dev Cancels the two-step ownership handover to the caller, if any. function cancelOwnershipHandover() public payable virtual { /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to 0. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x20), 0) // Emit the {OwnershipHandoverCanceled} event. log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller()) } } /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`. /// Reverts if there is no existing ownership handover requested by `pendingOwner`. function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner { /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to 0. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, pendingOwner) let handoverSlot := keccak256(0x0c, 0x20) // If the handover does not exist, or has expired. if gt(timestamp(), sload(handoverSlot)) { mstore(0x00, _NO_HANDOVER_REQUEST_ERROR_SELECTOR) revert(0x1c, 0x04) } // Set the handover slot to 0. sstore(handoverSlot, 0) // Clean the upper 96 bits. let newOwner := shr(96, mload(0x0c)) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, caller(), newOwner) // Store the new value. sstore(not(_OWNER_SLOT_NOT), newOwner) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PUBLIC READ FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the owner of the contract. function owner() public view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { result := sload(not(_OWNER_SLOT_NOT)) } } /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`. function ownershipHandoverExpiresAt(address pendingOwner) public view virtual returns (uint256 result) { /// @solidity memory-safe-assembly assembly { // Compute the handover slot. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, pendingOwner) // Load the handover slot. result := sload(keccak256(0x0c, 0x20)) } } /// @dev Returns how long a two-step ownership handover is valid for in seconds. function ownershipHandoverValidFor() public view virtual returns (uint64) { return 48 * 3600; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* MODIFIERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Marks a function as only callable by the owner. modifier onlyOwner() virtual { _checkOwner(); _; } } // File: solady/tokens/ERC1155.sol pragma solidity ^0.8.4; /// @notice Modern and gas efficient ERC1155 implementation. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC1155.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC1155/ERC1155.sol) abstract contract ERC1155 { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The lengths of the input arrays are not the same. error ArrayLengthsMismatch(); /// @dev Cannot mint or transfer to the zero address. error TransferToZeroAddress(); /// @dev The recipient's balance has overflowed. error AccountBalanceOverflow(); /// @dev Insufficient balance. error InsufficientBalance(); /// @dev Only the token owner or an approved account can manage the tokens. error NotOwnerNorApproved(); /// @dev Cannot safely transfer to a contract that does not implement /// the ERC1155Receiver interface. error TransferToNonERC1155ReceiverImplementer(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EVENTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Emitted when `amount` of token `id` is transferred /// from `from` to `to` by `operator`. event TransferSingle( address indexed operator, address indexed from, address indexed to, uint256 id, uint256 amount ); /// @dev Emitted when `amounts` of token `ids` are transferred /// from `from` to `to` by `operator`. event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] amounts ); /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens. event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved); /// @dev Emitted when the Uniform Resource Identifier (URI) for token `id` /// is updated to `value`. This event is not used in the base contract. /// You may need to emit this event depending on your URI logic. /// /// See: https://eips.ethereum.org/EIPS/eip-1155#metadata event URI(string value, uint256 indexed id); /// @dev `keccak256(bytes("TransferSingle(address,address,address,uint256,uint256)"))`. uint256 private constant _TRANSFER_SINGLE_EVENT_SIGNATURE = 0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62; /// @dev `keccak256(bytes("TransferBatch(address,address,address,uint256[],uint256[])"))`. uint256 private constant _TRANSFER_BATCH_EVENT_SIGNATURE = 0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb; /// @dev `keccak256(bytes("ApprovalForAll(address,address,bool)"))`. uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE = 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STORAGE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The `ownerSlotSeed` of a given owner is given by. /// ``` /// let ownerSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, owner)) /// ``` /// /// The balance slot of `owner` is given by. /// ``` /// mstore(0x20, ownerSlotSeed) /// mstore(0x00, id) /// let balanceSlot := keccak256(0x00, 0x40) /// ``` /// /// The operator approval slot of `owner` is given by. /// ``` /// mstore(0x20, ownerSlotSeed) /// mstore(0x00, operator) /// let operatorApprovalSlot := keccak256(0x0c, 0x34) /// ``` uint256 private constant _ERC1155_MASTER_SLOT_SEED = 0x9a31110384e0b0c9; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC1155 METADATA */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the URI for token `id`. /// /// Can either return the same templated URI for all token IDs, /// or substitute the `id` on the contract side. /// /// See: https://eips.ethereum.org/EIPS/eip-1155#metadata function uri(uint256 id) public view virtual returns (string memory); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC1155 */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the amount of `id` owned by `owner`. function balanceOf(address owner, uint256 id) public view virtual returns (uint256 result) { /// @solidity memory-safe-assembly assembly { mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, shl(96, owner))) mstore(0x00, id) result := sload(keccak256(0x00, 0x40)) } } /// @dev Returns whether `operator` is approved to manage the tokens of `owner`. function isApprovedForAll(address owner, address operator) public view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, shl(96, owner))) mstore(0x00, operator) result := sload(keccak256(0x0c, 0x34)) } } /// @dev Sets whether `operator` is approved to manage the tokens of the caller. /// /// Emits a {ApprovalForAll} event. function setApprovalForAll(address operator, bool isApproved) public virtual { /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. operator := shr(96, shl(96, operator)) // Convert to 0 or 1. isApproved := iszero(iszero(isApproved)) // Update the `isApproved` for (`msg.sender`, `operator`). mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, shl(96, caller()))) mstore(0x00, operator) sstore(keccak256(0x0c, 0x34), isApproved) // Emit the {ApprovalForAll} event. mstore(0x00, isApproved) log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), operator) } } /// @dev Transfers `amount` of `id` from `from` to `to`. /// /// Requirements: /// - `to` cannot be the zero address. /// - `from` must have at least `amount` of `id`. /// - If the caller is not `from`, /// it must be approved to manage the tokens of `from`. /// - If `to` refers to a smart contract, it must implement /// {ERC1155-onERC1155Reveived}, which is called upon a batch transfer. /// /// Emits a {Transfer} event. function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) public virtual { if (_useBeforeTokenTransfer()) { _beforeTokenTransfer(from, to, _single(id), _single(amount), data); } /// @solidity memory-safe-assembly assembly { let fromSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, from)) let toSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, to)) mstore(0x20, fromSlotSeed) // Clear the upper 96 bits. from := shr(96, fromSlotSeed) to := shr(96, toSlotSeed) // If the caller is not `from`, do the authorization check. if iszero(eq(caller(), from)) { mstore(0x00, caller()) if iszero(sload(keccak256(0x0c, 0x34))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Subtract and store the updated balance of `from`. { mstore(0x00, id) let fromBalanceSlot := keccak256(0x00, 0x40) let fromBalance := sload(fromBalanceSlot) if gt(amount, fromBalance) { mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. revert(0x1c, 0x04) } sstore(fromBalanceSlot, sub(fromBalance, amount)) } // Increase and store the updated balance of `to`. { mstore(0x20, toSlotSeed) let toBalanceSlot := keccak256(0x00, 0x40) let toBalanceBefore := sload(toBalanceSlot) let toBalanceAfter := add(toBalanceBefore, amount) if lt(toBalanceAfter, toBalanceBefore) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(toBalanceSlot, toBalanceAfter) } // Emit a {TransferSingle} event. { mstore(0x20, amount) log4(0x00, 0x40, _TRANSFER_SINGLE_EVENT_SIGNATURE, caller(), from, to) } } if (_useAfterTokenTransfer()) { _afterTokenTransfer(from, to, _single(id), _single(amount), data); } /// @solidity memory-safe-assembly assembly { // Do the {onERC1155Received} check if `to` is a smart contract. if extcodesize(to) { // Prepare the calldata. let m := mload(0x40) let onERC1155ReceivedSelector := 0xf23a6e61 mstore(m, onERC1155ReceivedSelector) mstore(add(m, 0x20), caller()) mstore(add(m, 0x40), from) mstore(add(m, 0x60), id) mstore(add(m, 0x80), amount) mstore(add(m, 0xa0), 0xa0) calldatacopy(add(m, 0xc0), sub(data.offset, 0x20), add(0x20, data.length)) // Revert if the call reverts. if iszero(call(gas(), to, 0, add(m, 0x1c), add(0xc4, data.length), m, 0x20)) { if returndatasize() { // Bubble up the revert if the delegatecall reverts. returndatacopy(0x00, 0x00, returndatasize()) revert(0x00, returndatasize()) } mstore(m, 0) } // Load the returndata and compare it. if iszero(eq(mload(m), shl(224, onERC1155ReceivedSelector))) { mstore(0x00, 0x9c05499b) // `TransferToNonERC1155ReceiverImplementer()`. revert(0x1c, 0x04) } } } } /// @dev Transfers `amounts` of `ids` from `from` to `to`. /// /// Requirements: /// - `to` cannot be the zero address. /// - `from` must have at least `amount` of `id`. /// - `ids` and `amounts` must have the same length. /// - If the caller is not `from`, /// it must be approved to manage the tokens of `from`. /// - If `to` refers to a smart contract, it must implement /// {ERC1155-onERC1155BatchReveived}, which is called upon a batch transfer. /// /// Emits a {TransferBatch} event. function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) public virtual { if (_useBeforeTokenTransfer()) { _beforeTokenTransfer(from, to, ids, amounts, data); } /// @solidity memory-safe-assembly assembly { if iszero(eq(ids.length, amounts.length)) { mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. revert(0x1c, 0x04) } let fromSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, from)) let toSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, to)) mstore(0x20, fromSlotSeed) // Clear the upper 96 bits. from := shr(96, fromSlotSeed) to := shr(96, toSlotSeed) // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // If the caller is not `from`, do the authorization check. if iszero(eq(caller(), from)) { mstore(0x00, caller()) if iszero(sload(keccak256(0x0c, 0x34))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Loop through all the `ids` and update the balances. { let end := shl(5, ids.length) for { let i := 0 } iszero(eq(i, end)) { i := add(i, 0x20) } { let amount := calldataload(add(amounts.offset, i)) // Subtract and store the updated balance of `from`. { mstore(0x20, fromSlotSeed) mstore(0x00, calldataload(add(ids.offset, i))) let fromBalanceSlot := keccak256(0x00, 0x40) let fromBalance := sload(fromBalanceSlot) if gt(amount, fromBalance) { mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. revert(0x1c, 0x04) } sstore(fromBalanceSlot, sub(fromBalance, amount)) } // Increase and store the updated balance of `to`. { mstore(0x20, toSlotSeed) let toBalanceSlot := keccak256(0x00, 0x40) let toBalanceBefore := sload(toBalanceSlot) let toBalanceAfter := add(toBalanceBefore, amount) if lt(toBalanceAfter, toBalanceBefore) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(toBalanceSlot, toBalanceAfter) } } } // Emit a {TransferBatch} event. { let m := mload(0x40) // Copy the `ids`. mstore(m, 0x40) let n := add(0x20, shl(5, ids.length)) let o := add(m, 0x40) calldatacopy(o, sub(ids.offset, 0x20), n) // Copy the `amounts`. mstore(add(m, 0x20), add(0x40, n)) o := add(o, n) n := add(0x20, shl(5, amounts.length)) calldatacopy(o, sub(amounts.offset, 0x20), n) n := sub(add(o, n), m) // Do the emit. log4(m, n, _TRANSFER_BATCH_EVENT_SIGNATURE, caller(), from, to) } } if (_useAfterTokenTransfer()) { _afterTokenTransferCalldata(from, to, ids, amounts, data); } /// @solidity memory-safe-assembly assembly { // Do the {onERC1155BatchReceived} check if `to` is a smart contract. if extcodesize(to) { let m := mload(0x40) // Prepare the calldata. let onERC1155BatchReceivedSelector := 0xbc197c81 mstore(m, onERC1155BatchReceivedSelector) mstore(add(m, 0x20), caller()) mstore(add(m, 0x40), from) // Copy the `ids`. mstore(add(m, 0x60), 0xa0) let n := add(0x20, shl(5, ids.length)) let o := add(m, 0xc0) calldatacopy(o, sub(ids.offset, 0x20), n) // Copy the `amounts`. let s := add(0xa0, n) mstore(add(m, 0x80), s) o := add(o, n) n := add(0x20, shl(5, amounts.length)) calldatacopy(o, sub(amounts.offset, 0x20), n) // Copy the `data`. mstore(add(m, 0xa0), add(s, n)) o := add(o, n) n := add(0x20, data.length) calldatacopy(o, sub(data.offset, 0x20), n) n := sub(add(o, n), add(m, 0x1c)) // Revert if the call reverts. if iszero(call(gas(), to, 0, add(m, 0x1c), n, m, 0x20)) { if returndatasize() { // Bubble up the revert if the delegatecall reverts. returndatacopy(0x00, 0x00, returndatasize()) revert(0x00, returndatasize()) } mstore(m, 0) } // Load the returndata and compare it. if iszero(eq(mload(m), shl(224, onERC1155BatchReceivedSelector))) { mstore(0x00, 0x9c05499b) // `TransferToNonERC1155ReceiverImplementer()`. revert(0x1c, 0x04) } } } } /// @dev Returns the amounts of `ids` for `owners. /// /// Requirements: /// - `owners` and `ids` must have the same length. function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) public view virtual returns (uint256[] memory balances) { /// @solidity memory-safe-assembly assembly { if iszero(eq(ids.length, owners.length)) { mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. revert(0x1c, 0x04) } balances := mload(0x40) mstore(balances, ids.length) let o := add(balances, 0x20) let end := shl(5, ids.length) mstore(0x40, add(end, o)) // Loop through all the `ids` and load the balances. for { let i := 0 } iszero(eq(i, end)) { i := add(i, 0x20) } { let owner := calldataload(add(owners.offset, i)) mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, shl(96, owner))) mstore(0x00, calldataload(add(ids.offset, i))) mstore(add(o, i), sload(keccak256(0x00, 0x40))) } } } /// @dev Returns true if this contract implements the interface defined by `interfaceId`. /// See: https://eips.ethereum.org/EIPS/eip-165 /// This function call must use less than 30000 gas. function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { let s := shr(224, interfaceId) // ERC165: 0x01ffc9a7, ERC1155: 0xd9b67a26, ERC1155MetadataURI: 0x0e89341c. result := or(or(eq(s, 0x01ffc9a7), eq(s, 0xd9b67a26)), eq(s, 0x0e89341c)) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL MINT FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Mints `amount` of `id` to `to`. /// /// Requirements: /// - `to` cannot be the zero address. /// - If `to` refers to a smart contract, it must implement /// {ERC1155-onERC1155Reveived}, which is called upon a batch transfer. /// /// Emits a {Transfer} event. function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual { if (_useBeforeTokenTransfer()) { _beforeTokenTransfer(address(0), to, _single(id), _single(amount), data); } /// @solidity memory-safe-assembly assembly { let toSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, to)) // Clear the upper 96 bits. to := shr(96, toSlotSeed) // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Increase and store the updated balance of `to`. { mstore(0x20, toSlotSeed) mstore(0x00, id) let toBalanceSlot := keccak256(0x00, 0x40) let toBalanceBefore := sload(toBalanceSlot) let toBalanceAfter := add(toBalanceBefore, amount) if lt(toBalanceAfter, toBalanceBefore) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(toBalanceSlot, toBalanceAfter) } // Emit a {TransferSingle} event. { mstore(0x00, id) mstore(0x20, amount) log4(0x00, 0x40, _TRANSFER_SINGLE_EVENT_SIGNATURE, caller(), 0, to) } } if (_useAfterTokenTransfer()) { _afterTokenTransfer(address(0), to, _single(id), _single(amount), data); } if (_hasCode(to)) _checkOnERC1155Received(address(0), to, id, amount, data); } /// @dev Mints `amounts` of `ids` to `to`. /// /// Requirements: /// - `to` cannot be the zero address. /// - `ids` and `amounts` must have the same length. /// - If `to` refers to a smart contract, it must implement /// {ERC1155-onERC1155BatchReveived}, which is called upon a batch transfer. /// /// Emits a {TransferBatch} event. function _batchMint( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { if (_useBeforeTokenTransfer()) { _beforeTokenTransfer(address(0), to, ids, amounts, data); } /// @solidity memory-safe-assembly assembly { if iszero(eq(mload(ids), mload(amounts))) { mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. revert(0x1c, 0x04) } let toSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, to)) // Clear the upper 96 bits. to := shr(96, toSlotSeed) // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Loop through all the `ids` and update the balances. { let end := shl(5, mload(ids)) for { let i := 0 } iszero(eq(i, end)) {} { i := add(i, 0x20) let amount := mload(add(amounts, i)) // Increase and store the updated balance of `to`. { mstore(0x20, toSlotSeed) mstore(0x00, mload(add(ids, i))) let toBalanceSlot := keccak256(0x00, 0x40) let toBalanceBefore := sload(toBalanceSlot) let toBalanceAfter := add(toBalanceBefore, amount) if lt(toBalanceAfter, toBalanceBefore) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(toBalanceSlot, toBalanceAfter) } } } // Emit a {TransferBatch} event. { let m := mload(0x40) // Copy the `ids`. mstore(m, 0x40) let n := add(0x20, shl(5, mload(ids))) let o := add(m, 0x40) pop(staticcall(gas(), 4, ids, n, o, n)) // Copy the `amounts`. mstore(add(m, 0x20), add(0x40, returndatasize())) o := add(o, returndatasize()) n := add(0x20, shl(5, mload(amounts))) pop(staticcall(gas(), 4, amounts, n, o, n)) n := sub(add(o, returndatasize()), m) // Do the emit. log4(m, n, _TRANSFER_BATCH_EVENT_SIGNATURE, caller(), 0, to) } } if (_useAfterTokenTransfer()) { _afterTokenTransfer(address(0), to, ids, amounts, data); } if (_hasCode(to)) _checkOnERC1155BatchReceived(address(0), to, ids, amounts, data); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL BURN FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Equivalent to `_burn(address(0), from, id, amount)`. function _burn(address from, uint256 id, uint256 amount) internal virtual { _burn(address(0), from, id, amount); } /// @dev Destroys `amount` of `id` from `from`. /// /// Requirements: /// - `from` must have at least `amount` of `id`. /// - If `by` is not the zero address, it must be either `from`, /// or approved to manage the tokens of `from`. /// /// Emits a {Transfer} event. function _burn(address by, address from, uint256 id, uint256 amount) internal virtual { if (_useBeforeTokenTransfer()) { _beforeTokenTransfer(from, address(0), _single(id), _single(amount), ""); } /// @solidity memory-safe-assembly assembly { let fromSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, from)) mstore(0x20, fromSlotSeed) // Clear the upper 96 bits. from := shr(96, fromSlotSeed) by := shr(96, shl(96, by)) // If `by` is not the zero address, and not equal to `from`, // check if it is approved to manage all the tokens of `from`. if iszero(or(iszero(by), eq(by, from))) { mstore(0x00, by) if iszero(sload(keccak256(0x0c, 0x34))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Decrease and store the updated balance of `from`. { mstore(0x00, id) let fromBalanceSlot := keccak256(0x00, 0x40) let fromBalance := sload(fromBalanceSlot) if gt(amount, fromBalance) { mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. revert(0x1c, 0x04) } sstore(fromBalanceSlot, sub(fromBalance, amount)) } // Emit a {TransferSingle} event. { mstore(0x00, id) mstore(0x20, amount) log4(0x00, 0x40, _TRANSFER_SINGLE_EVENT_SIGNATURE, caller(), from, 0) } } if (_useAfterTokenTransfer()) { _afterTokenTransfer(from, address(0), _single(id), _single(amount), ""); } } /// @dev Equivalent to `_batchBurn(address(0), from, ids, amounts)`. function _batchBurn(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual { _batchBurn(address(0), from, ids, amounts); } /// @dev Destroys `amounts` of `ids` from `from`. /// /// Requirements: /// - `ids` and `amounts` must have the same length. /// - `from` must have at least `amounts` of `ids`. /// - If `by` is not the zero address, it must be either `from`, /// or approved to manage the tokens of `from`. /// /// Emits a {TransferBatch} event. function _batchBurn(address by, address from, uint256[] memory ids, uint256[] memory amounts) internal virtual { if (_useBeforeTokenTransfer()) { _beforeTokenTransfer(from, address(0), ids, amounts, ""); } /// @solidity memory-safe-assembly assembly { if iszero(eq(mload(ids), mload(amounts))) { mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. revert(0x1c, 0x04) } let fromSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, from)) mstore(0x20, fromSlotSeed) // Clear the upper 96 bits. from := shr(96, fromSlotSeed) by := shr(96, shl(96, by)) // If `by` is not the zero address, and not equal to `from`, // check if it is approved to manage all the tokens of `from`. if iszero(or(iszero(by), eq(by, from))) { mstore(0x00, by) if iszero(sload(keccak256(0x0c, 0x34))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Loop through all the `ids` and update the balances. { let end := shl(5, mload(ids)) for { let i := 0 } iszero(eq(i, end)) {} { i := add(i, 0x20) let amount := mload(add(amounts, i)) // Increase and store the updated balance of `to`. { mstore(0x00, mload(add(ids, i))) let fromBalanceSlot := keccak256(0x00, 0x40) let fromBalance := sload(fromBalanceSlot) if gt(amount, fromBalance) { mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. revert(0x1c, 0x04) } sstore(fromBalanceSlot, sub(fromBalance, amount)) } } } // Emit a {TransferBatch} event. { let m := mload(0x40) // Copy the `ids`. mstore(m, 0x40) let n := add(0x20, shl(5, mload(ids))) let o := add(m, 0x40) pop(staticcall(gas(), 4, ids, n, o, n)) // Copy the `amounts`. mstore(add(m, 0x20), add(0x40, returndatasize())) o := add(o, returndatasize()) n := add(0x20, shl(5, mload(amounts))) pop(staticcall(gas(), 4, amounts, n, o, n)) n := sub(add(o, returndatasize()), m) // Do the emit. log4(m, n, _TRANSFER_BATCH_EVENT_SIGNATURE, caller(), from, 0) } } if (_useAfterTokenTransfer()) { _afterTokenTransfer(from, address(0), ids, amounts, ""); } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL APPROVAL FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Approve or remove the `operator` as an operator for `by`, /// without authorization checks. /// /// Emits a {ApprovalForAll} event. function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual { /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. operator := shr(96, shl(96, operator)) // Convert to 0 or 1. isApproved := iszero(iszero(isApproved)) // Update the `isApproved` for (`by`, `operator`). mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, shl(96, by))) mstore(0x00, operator) sstore(keccak256(0x0c, 0x34), isApproved) // Emit the {ApprovalForAll} event. mstore(0x00, isApproved) log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), operator) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL TRANSFER FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Equivalent to `_safeTransfer(address(0), from, to, id, amount, data)`. function _safeTransfer(address from, address to, uint256 id, uint256 amount, bytes memory data) internal virtual { _safeTransfer(address(0), from, to, id, amount, data); } /// @dev Transfers `amount` of `id` from `from` to `to`. /// /// Requirements: /// - `to` cannot be the zero address. /// - `from` must have at least `amount` of `id`. /// - If `by` is not the zero address, it must be either `from`, /// or approved to manage the tokens of `from`. /// - If `to` refers to a smart contract, it must implement /// {ERC1155-onERC1155Reveived}, which is called upon a batch transfer. /// /// Emits a {Transfer} event. function _safeTransfer( address by, address from, address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { if (_useBeforeTokenTransfer()) { _beforeTokenTransfer(from, to, _single(id), _single(amount), data); } /// @solidity memory-safe-assembly assembly { let fromSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, from)) let toSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, to)) mstore(0x20, fromSlotSeed) // Clear the upper 96 bits. from := shr(96, fromSlotSeed) to := shr(96, toSlotSeed) by := shr(96, shl(96, by)) // If `by` is not the zero address, and not equal to `from`, // check if it is approved to manage all the tokens of `from`. if iszero(or(iszero(by), eq(by, from))) { mstore(0x00, by) if iszero(sload(keccak256(0x0c, 0x34))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Subtract and store the updated balance of `from`. { mstore(0x00, id) let fromBalanceSlot := keccak256(0x00, 0x40) let fromBalance := sload(fromBalanceSlot) if gt(amount, fromBalance) { mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. revert(0x1c, 0x04) } sstore(fromBalanceSlot, sub(fromBalance, amount)) } // Increase and store the updated balance of `to`. { mstore(0x20, toSlotSeed) let toBalanceSlot := keccak256(0x00, 0x40) let toBalanceBefore := sload(toBalanceSlot) let toBalanceAfter := add(toBalanceBefore, amount) if lt(toBalanceAfter, toBalanceBefore) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(toBalanceSlot, toBalanceAfter) } // Emit a {TransferSingle} event. { mstore(0x20, amount) log4(0x00, 0x40, _TRANSFER_SINGLE_EVENT_SIGNATURE, caller(), from, to) } } if (_hasCode(to)) _checkOnERC1155Received(from, to, id, amount, data); if (_useAfterTokenTransfer()) { _afterTokenTransfer(from, to, _single(id), _single(amount), data); } } /// @dev Equivalent to `_safeBatchTransfer(address(0), from, to, ids, amounts, data)`. function _safeBatchTransfer( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { _safeBatchTransfer(address(0), from, to, ids, amounts, data); } /// @dev Transfers `amounts` of `ids` from `from` to `to`. /// /// Requirements: /// - `to` cannot be the zero address. /// - `ids` and `amounts` must have the same length. /// - `from` must have at least `amounts` of `ids`. /// - If `by` is not the zero address, it must be either `from`, /// or approved to manage the tokens of `from`. /// - If `to` refers to a smart contract, it must implement /// {ERC1155-onERC1155BatchReveived}, which is called upon a batch transfer. /// /// Emits a {TransferBatch} event. function _safeBatchTransfer( address by, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { if (_useBeforeTokenTransfer()) { _beforeTokenTransfer(from, to, ids, amounts, data); } /// @solidity memory-safe-assembly assembly { if iszero(eq(mload(ids), mload(amounts))) { mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. revert(0x1c, 0x04) } let fromSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, from)) let toSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, to)) mstore(0x20, fromSlotSeed) // Clear the upper 96 bits. from := shr(96, fromSlotSeed) to := shr(96, toSlotSeed) by := shr(96, shl(96, by)) // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // If `by` is not the zero address, and not equal to `from`, // check if it is approved to manage all the tokens of `from`. if iszero(or(iszero(by), eq(by, from))) { mstore(0x00, by) if iszero(sload(keccak256(0x0c, 0x34))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Loop through all the `ids` and update the balances. { let end := shl(5, mload(ids)) for { let i := 0 } iszero(eq(i, end)) {} { i := add(i, 0x20) let amount := mload(add(amounts, i)) // Subtract and store the updated balance of `from`. { mstore(0x20, fromSlotSeed) mstore(0x00, mload(add(ids, i))) let fromBalanceSlot := keccak256(0x00, 0x40) let fromBalance := sload(fromBalanceSlot) if gt(amount, fromBalance) { mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. revert(0x1c, 0x04) } sstore(fromBalanceSlot, sub(fromBalance, amount)) } // Increase and store the updated balance of `to`. { mstore(0x20, toSlotSeed) let toBalanceSlot := keccak256(0x00, 0x40) let toBalanceBefore := sload(toBalanceSlot) let toBalanceAfter := add(toBalanceBefore, amount) if lt(toBalanceAfter, toBalanceBefore) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(toBalanceSlot, toBalanceAfter) } } } // Emit a {TransferBatch} event. { let m := mload(0x40) // Copy the `ids`. mstore(m, 0x40) let n := add(0x20, shl(5, mload(ids))) let o := add(m, 0x40) pop(staticcall(gas(), 4, ids, n, o, n)) // Copy the `amounts`. mstore(add(m, 0x20), add(0x40, returndatasize())) o := add(o, returndatasize()) n := add(0x20, shl(5, mload(amounts))) pop(staticcall(gas(), 4, amounts, n, o, n)) n := sub(add(o, returndatasize()), m) // Do the emit. log4(m, n, _TRANSFER_BATCH_EVENT_SIGNATURE, caller(), from, to) } } if (_hasCode(to)) _checkOnERC1155BatchReceived(from, to, ids, amounts, data); if (_useAfterTokenTransfer()) { _afterTokenTransfer(from, to, ids, amounts, data); } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* HOOKS FOR OVERRIDING */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Override this function to return true if `_beforeTokenTransfer` is used. /// The is to help the compiler avoid producing dead bytecode. function _useBeforeTokenTransfer() internal view virtual returns (bool) { return false; } /// @dev Hook that is called before any token transfer. /// This includes minting and burning, as well as batched variants. /// /// The same hook is called on both single and batched variants. /// For single transfers, the length of the `id` and `amount` arrays are 1. function _beforeTokenTransfer( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} /// @dev Override this function to return true if `_afterTokenTransfer` is used. /// The is to help the compiler avoid producing dead bytecode. function _useAfterTokenTransfer() internal view virtual returns (bool) { return false; } /// @dev Hook that is called after any token transfer. /// This includes minting and burning, as well as batched variants. /// /// The same hook is called on both single and batched variants. /// For single transfers, the length of the `id` and `amount` arrays are 1. function _afterTokenTransfer( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PRIVATE HELPERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Helper for calling the `_afterTokenTransfer` hook. /// The is to help the compiler avoid producing dead bytecode. function _afterTokenTransferCalldata( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) private { if (_useAfterTokenTransfer()) { _afterTokenTransfer(from, to, ids, amounts, data); } } /// @dev Returns if `a` has bytecode of non-zero length. function _hasCode(address a) private view returns (bool result) { /// @solidity memory-safe-assembly assembly { result := extcodesize(a) // Can handle dirty upper bits. } } /// @dev Perform a call to invoke {IERC1155Receiver-onERC1155Received} on `to`. /// Reverts if the target does not support the function correctly. function _checkOnERC1155Received( address from, address to, uint256 id, uint256 amount, bytes memory data ) private { /// @solidity memory-safe-assembly assembly { // Prepare the calldata. let m := mload(0x40) let onERC1155ReceivedSelector := 0xf23a6e61 mstore(m, onERC1155ReceivedSelector) mstore(add(m, 0x20), caller()) mstore(add(m, 0x40), shr(96, shl(96, from))) mstore(add(m, 0x60), id) mstore(add(m, 0x80), amount) mstore(add(m, 0xa0), 0xa0) let n := mload(data) mstore(add(m, 0xc0), n) if n { pop(staticcall(gas(), 4, add(data, 0x20), n, add(m, 0xe0), n)) } // Revert if the call reverts. if iszero(call(gas(), to, 0, add(m, 0x1c), add(0xc4, n), m, 0x20)) { if returndatasize() { // Bubble up the revert if the delegatecall reverts. returndatacopy(0x00, 0x00, returndatasize()) revert(0x00, returndatasize()) } mstore(m, 0) } // Load the returndata and compare it. if iszero(eq(mload(m), shl(224, onERC1155ReceivedSelector))) { mstore(0x00, 0x9c05499b) // `TransferToNonERC1155ReceiverImplementer()`. revert(0x1c, 0x04) } } } /// @dev Perform a call to invoke {IERC1155Receiver-onERC1155BatchReceived} on `to`. /// Reverts if the target does not support the function correctly. function _checkOnERC1155BatchReceived( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) private { /// @solidity memory-safe-assembly assembly { // Prepare the calldata. let m := mload(0x40) let onERC1155BatchReceivedSelector := 0xbc197c81 mstore(m, onERC1155BatchReceivedSelector) mstore(add(m, 0x20), caller()) mstore(add(m, 0x40), shr(96, shl(96, from))) // Copy the `ids`. mstore(add(m, 0x60), 0xa0) let n := add(0x20, shl(5, mload(ids))) let o := add(m, 0xc0) pop(staticcall(gas(), 4, ids, n, o, n)) // Copy the `amounts`. let s := add(0xa0, returndatasize()) mstore(add(m, 0x80), s) o := add(o, returndatasize()) n := add(0x20, shl(5, mload(amounts))) pop(staticcall(gas(), 4, amounts, n, o, n)) // Copy the `data`. mstore(add(m, 0xa0), add(s, returndatasize())) o := add(o, returndatasize()) n := add(0x20, mload(data)) pop(staticcall(gas(), 4, data, n, o, n)) n := sub(add(o, returndatasize()), add(m, 0x1c)) // Revert if the call reverts. if iszero(call(gas(), to, 0, add(m, 0x1c), n, m, 0x20)) { if returndatasize() { // Bubble up the revert if the delegatecall reverts. returndatacopy(0x00, 0x00, returndatasize()) revert(0x00, returndatasize()) } mstore(m, 0) } // Load the returndata and compare it. if iszero(eq(mload(m), shl(224, onERC1155BatchReceivedSelector))) { mstore(0x00, 0x9c05499b) // `TransferToNonERC1155ReceiverImplementer()`. revert(0x1c, 0x04) } } } /// @dev Returns `x` in an array with a single element. function _single(uint256 x) private pure returns (uint256[] memory result) { assembly { result := mload(0x40) mstore(0x40, add(result, 0x40)) mstore(result, 1) mstore(add(result, 0x20), x) } } } // File: miladystationrejects/rejects.sol /// @title miladystationrejects /// @author arthurt /// @notice !pray ✦✦✦ pragma solidity ^0.8.17; contract MiladyStationRejects is ERC1155, Ownable { error IDAmountMismatch(); error WalletUnauthorizedToMint(); error NotFriend(); error IncorrectValueSent(); error GreedyAlliance(); error FirmamentReached(); error NeedThree(); string public name = "Mony MissingNo."; string public symbol = "MSX"; string public _uri; bytes32 public root; struct Token { string name; uint currentSupply; } uint256 public count; mapping(uint => Token) public tokens; mapping(address => bool) public holderMints; constructor() { _initializeOwner(msg.sender); } function setRoot(bytes32 newRoot) public onlyOwner { root = newRoot; } function mintSingle( uint id ) public payable { if (count + 1 > 123) { revert FirmamentReached();} if (msg.value != 7000000000000000) { revert IncorrectValueSent();} _mint(msg.sender, id, 1, ""); tokens[id].currentSupply += 1; count += 1; } function mintMerkleSingle( bytes32[] calldata proof, uint id ) public payable { if (count + 3 > 123 || holderMints[msg.sender]) { revert FirmamentReached();} if(proven(proof, root, leafit())){ _mint(msg.sender, id, 3, ""); tokens[id].currentSupply += 3; count += 3; holderMints[msg.sender] = true; } else { revert WalletUnauthorizedToMint(); } } function mintBatch( uint[] calldata ids, uint[] calldata amounts ) external payable { if(ids.length != amounts.length) revert IDAmountMismatch(); uint256 _amt; uint totalEtherPrice; for (uint i = 0; i < ids.length; i++) { totalEtherPrice += amounts[i] * 7000000000000000; _amt += amounts[i]; } if (count + _amt > 123) { revert FirmamentReached();} if (msg.value != totalEtherPrice) { revert IncorrectValueSent();} _batchMint(msg.sender, ids, amounts, ""); for (uint i = 0; i < ids.length; i++) { tokens[ids[i]].currentSupply += amounts[i]; } count += _amt; } function mintMerkleBatch( bytes32[] calldata proof, uint[] calldata ids ) external payable { if(ids.length != 3) revert NeedThree(); uint256 amt = 1; uint256[] memory amts = new uint256[](3); amts[0] = amt; amts[1] = amt; amts[2] = amt; if (count + 3 > 123 || holderMints[msg.sender]) { revert FirmamentReached();} if(proven(proof, root, leafit())){ _batchMint(msg.sender, ids, amts, ""); for (uint i = 0; i < ids.length; i++) { tokens[ids[i]].currentSupply += 1; } count += 3; holderMints[msg.sender] = true; } else { revert WalletUnauthorizedToMint(); } } //uses solady merkleprooflib to prove a merkle proof proves merkleness function proven (bytes32[] calldata proof, bytes32 key, bytes32 leaf) public pure returns (bool) { bool prove = MerkleProofLib.verifyCalldata(proof, key, leaf); return prove; } //hashes person interacting for merkling function leafit() public view returns (bytes32) { bytes20 me = bytes20(msg.sender); return keccak256(abi.encodePacked(me)); } /// solady override with token id function uri(uint256) public view virtual override returns (string memory) { return _uri; } function setURI(string memory newuri) external onlyOwner { _uri = newuri; } function withdraw() external onlyOwner { uint balance = address(this).balance; payable(msg.sender).transfer(balance); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountBalanceOverflow","type":"error"},{"inputs":[],"name":"ArrayLengthsMismatch","type":"error"},{"inputs":[],"name":"FirmamentReached","type":"error"},{"inputs":[],"name":"GreedyAlliance","type":"error"},{"inputs":[],"name":"IDAmountMismatch","type":"error"},{"inputs":[],"name":"IncorrectValueSent","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"NeedThree","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"NotFriend","type":"error"},{"inputs":[],"name":"NotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferToNonERC1155ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"WalletUnauthorizedToMint","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"isApproved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[],"name":"_uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"owners","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"holderMints","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"leafit","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"mintBatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"mintMerkleBatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"mintMerkleSingle","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"mintSingle","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownershipHandoverValidFor","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"bytes32","name":"leaf","type":"bytes32"}],"name":"proven","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"isApproved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newRoot","type":"bytes32"}],"name":"setRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newuri","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokens","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"currentSupply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c0604052600f60809081526e26b7b73c9026b4b9b9b4b733a7379760891b60a0526000906200003090826200015b565b5060408051808201909152600381526209aa6b60eb1b60208201526001906200005a90826200015b565b503480156200006857600080fd5b5062000074336200007a565b62000227565b6001600160a01b0316638b78c6d8198190558060007f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620000e157607f821691505b6020821081036200010257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200015657600081815260208120601f850160051c81016020861015620001315750805b601f850160051c820191505b8181101562000152578281556001016200013d565b5050505b505050565b81516001600160401b03811115620001775762000177620000b6565b6200018f81620001888454620000cc565b8462000108565b602080601f831160018114620001c75760008415620001ae5750858301515b600019600386901b1c1916600185901b17855562000152565b600085815260208120601f198616915b82811015620001f857888601518255948401946001909101908401620001d7565b5085821015620002175787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61200580620002376000396000f3fe6080604052600436106101e25760003560e01c80635c5bc9ea11610102578063dab5f34011610095578063f242432a11610064578063f242432a1461059f578063f2fde38b146105bf578063f4ae63d1146105d2578063fee81cf4146105e557600080fd5b8063dab5f3401461051c578063e985e9c51461053c578063ebf0c71714610576578063f04e283e1461058c57600080fd5b8063a22cb465116100d1578063a22cb465146104ab578063af4b8e6e146104cb578063d351cfdc146104eb578063d7533f02146104fe57600080fd5b80635c5bc9ea1461040c578063715018a6146104555780638da5cb5b1461045d57806395d89b411461049657600080fd5b8063256929621161017a5780634f64b2be116101495780634f64b2be1461039357806353b8eb67146103c157806354d1f13d146103d457806355f94c9e146103dc57600080fd5b806325692962146103295780632eb2c2d6146103315780633ccfd60b146103515780634e1273f41461036657600080fd5b806306fdde03116101b657806306fdde03146102bf5780630dccc9ad146102e15780630e89341c146102f65780631dc485361461031657600080fd5b8062fdd58e146101e757806301ffc9a71461023a57806302fe53051461028757806306661abd146102a9575b600080fd5b3480156101f357600080fd5b506102276102023660046118b3565b60008260601b679a31110384e0b0c91760205281600052604060002054905092915050565b6040519081526020015b60405180910390f35b34801561024657600080fd5b506102776102553660046118dd565b6301ffc9a760e09190911c90811463d9b67a26821417630e89341c9091141790565b6040519015158152602001610231565b34801561029357600080fd5b506102a76102a236600461193c565b610618565b005b3480156102b557600080fd5b5061022760045481565b3480156102cb57600080fd5b506102d4610630565b6040516102319190611a33565b3480156102ed57600080fd5b506102d46106be565b34801561030257600080fd5b506102d4610311366004611a46565b6106cb565b6102a7610324366004611aab565b61075f565b6102a76109d9565b34801561033d57600080fd5b506102a761034c366004611b59565b610a29565b34801561035d57600080fd5b506102a7610c73565b34801561037257600080fd5b50610386610381366004611aab565b610caa565b6040516102319190611c14565b34801561039f57600080fd5b506103b36103ae366004611a46565b610d1a565b604051610231929190611c58565b6102a76103cf366004611a46565b610dbe565b6102a7610e93565b3480156103e857600080fd5b506102776103f7366004611c7a565b60066020526000908152604090205460ff1681565b34801561041857600080fd5b50604080516bffffffffffffffffffffffff193360601b166020808301919091528251601481840301815260349092019092528051910120610227565b6102a7610ecf565b34801561046957600080fd5b50638b78c6d8195460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610231565b3480156104a257600080fd5b506102d4610ee3565b3480156104b757600080fd5b506102a76104c6366004611c95565b610ef0565b3480156104d757600080fd5b506102776104e6366004611cd1565b610f4a565b6102a76104f9366004611aab565b610f63565b34801561050a57600080fd5b506040516202a3008152602001610231565b34801561052857600080fd5b506102a7610537366004611a46565b611197565b34801561054857600080fd5b50610277610557366004611d22565b60609190911b679a31110384e0b0c9176020526000526034600c205490565b34801561058257600080fd5b5061022760035481565b6102a761059a366004611c7a565b6111a4565b3480156105ab57600080fd5b506102a76105ba366004611d55565b611210565b6102a76105cd366004611c7a565b611373565b6102a76105e0366004611dcd565b6113d4565b3480156105f157600080fd5b50610227610600366004611c7a565b63389a75e1600c908152600091909152602090205490565b6106206114ed565b600261062c8282611e99565b5050565b6000805461063d90611e19565b80601f016020809104026020016040519081016040528092919081815260200182805461066990611e19565b80156106b65780601f1061068b576101008083540402835291602001916106b6565b820191906000526020600020905b81548152906001019060200180831161069957829003601f168201915b505050505081565b6002805461063d90611e19565b6060600280546106da90611e19565b80601f016020809104026020016040519081016040528092919081815260200182805461070690611e19565b80156107535780601f1061072857610100808354040283529160200191610753565b820191906000526020600020905b81548152906001019060200180831161073657829003601f168201915b50505050509050919050565b60038114610799576040517f2897e94800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600380825260808201909252600191600091906020820160608036833701905050905081816000815181106107d4576107d4611f59565b60200260200101818152505081816001815181106107f4576107f4611f59565b602002602001018181525050818160028151811061081457610814611f59565b602002602001018181525050607b60045460036108319190611f85565b118061084c57503360009081526006602052604090205460ff165b1561086a57604051632eccfe9760e11b815260040160405180910390fd5b6108b386866003546104e66040513360601b6bffffffffffffffffffffffff19811660208301526000916034016040516020818303038152906040528051906020012091505090565b1561099f57610905338585808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250604080516020810190915290815287935091506115089050565b60005b838110156109675760016005600087878581811061092857610928611f59565b905060200201358152602001908152602001600020600101600082825461094f9190611f85565b9091555081905061095f81611f9e565b915050610908565b5060036004600082825461097b9190611f85565b9091555050336000908152600660205260409020805460ff191660011790556109d1565b6040517fd838648f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b828514610a3e57633b800a466000526004601cfd5b8760601b679a31110384e0b0c9178760601b679a31110384e0b0c917816020528160601c99508060601c985088610a7d5763ea553b346000526004601cfd5b893314610aa057336000526034600c2054610aa057634b6e7f186000526004601cfd5b8660051b60005b818114610b11578088013584602052818b01356000526040600020805480831115610ada5763f4d678b86000526004601cfd5b829003905560208490526040600020805480830181811015610b04576301336cea6000526004601cfd5b9091555050602001610aa7565b50505050604051604081528560051b602001604082018160208a03823760408201602084810191909152600587901b01910181601f198801823701819003888a337f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8486a45050610b80600090565b15610b9557610b95888888888888888861162a565b863b15610c695760405163bc197c8180825233602083015289604083015260a060608301528660051b60200160c083018160208b0382378160a00180608086015282820191508760051b60200192508260208a038337820160a085015260208501910181601f1987018237018290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe40160208382601c820160008e5af1610c4c573d15610c47573d6000803e3d6000fd5b600083525b508060e01b825114610c6657639c05499b6000526004601cfd5b50505b5050505050505050565b610c7b6114ed565b6040514790339082156108fc029083906000818181858888f1935050505015801561062c573d6000803e3d6000fd5b6060838214610cc157633b800a466000526004601cfd5b6040519050818152602081018260051b81810160405260005b818114610d0f57679a31110384e0b0c98882013560601b17602090815286820135600090815260409020548483015201610cda565b505050949350505050565b600560205260009081526040902080548190610d3590611e19565b80601f0160208091040260200160405190810160405280929190818152602001828054610d6190611e19565b8015610dae5780601f10610d8357610100808354040283529160200191610dae565b820191906000526020600020905b815481529060010190602001808311610d9157829003601f168201915b5050505050908060010154905082565b607b6004546001610dcf9190611f85565b1115610dee57604051632eccfe9760e11b815260040160405180910390fd5b346618de76816d800014610e2e576040517f48b1ee8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e4a338260016040518060200160405280600081525061162f565b6001600560008381526020019081526020016000206001016000828254610e719190611f85565b92505081905550600160046000828254610e8b9190611f85565b909155505050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b610ed76114ed565b610ee160006116cc565b565b6001805461063d90611e19565b8160601b60601c915080151590503360601b679a31110384e0b0c91760205281600052806034600c20558060005281337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160206000a35050565b600080610f5986868686611717565b9695505050505050565b828114610f9c576040517f7955807f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561101957848482818110610fbc57610fbc611f59565b905060200201356618de76816d8000610fd59190611fb8565b610fdf9083611f85565b9150848482818110610ff357610ff3611f59565b90506020020135836110059190611f85565b92508061101181611f9e565b915050610fa2565b50607b8260045461102a9190611f85565b111561104957604051632eccfe9760e11b815260040160405180910390fd5b803414611082576040517f48b1ee8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110fe3387878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092018290525060408051602081019091529081529250611508915050565b60005b858110156111775784848281811061111b5761111b611f59565b905060200201356005600089898581811061113857611138611f59565b905060200201358152602001908152602001600020600101600082825461115f9190611f85565b9091555081905061116f81611f9e565b915050611101565b50816004600082825461118a9190611f85565b9091555050505050505050565b61119f6114ed565b600355565b6111ac6114ed565b63389a75e1600c52806000526020600c2080544211156111d457636f5e88186000526004601cfd5b6000815550600c5160601c80337f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3638b78c6d8195550565b8560601b679a31110384e0b0c9178560601b679a31110384e0b0c917816020528160601c97508060601c965087331461125f57336000526034600c205461125f57634b6e7f186000526004601cfd5b866112725763ea553b346000526004601cfd5b85600052604060002091508154808611156112955763f4d678b86000526004601cfd5b85810383555080602052604060002091508154858101818110156112c1576301336cea6000526004601cfd5b909255505060208390528486337fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260406000a4843b156109d15760405163f23a6e6180825233602083015287604083015285606083015284608083015260a080830152826020016020850360c08401376020828460c401601c850160008b5af161135a573d15611355573d6000803e3d6000fd5b600082525b8060e01b825114610c6957639c05499b6000526004601cfd5b61137b6114ed565b73ffffffffffffffffffffffffffffffffffffffff81166113c8576040517f7448fbae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113d1816116cc565b50565b607b60045460036113e59190611f85565b118061140057503360009081526006602052604090205460ff165b1561141e57604051632eccfe9760e11b815260040160405180910390fd5b61146783836003546104e66040513360601b6bffffffffffffffffffffffff19811660208301526000916034016040516020818303038152906040528051906020012091505090565b1561099f57611488338260036040518060200160405280600081525061162f565b60008181526005602052604081206001018054600392906114aa908490611f85565b925050819055506003600460008282546114c49190611f85565b9091555050336000908152600660205260409020805460ff19166001179055505050565b505050565b638b78c6d819543314610ee1576382b429006000526004601cfd5b815183511461151f57633b800a466000526004601cfd5b8360601b679a31110384e0b0c9178060601c9450846115465763ea553b346000526004601cfd5b835160051b60005b81811461159557602081019050808501518360205281870151600052604060002080548281018181101561158a576301336cea6000526004601cfd5b9091555061154e9050565b50505060405160408152835160051b602001604082018181838860045afa503d60400160208401523d81019050845160051b60200191508181838760045afa503d018290039050856000337f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8486a4505061160e600090565b50833b1561162457611624600085858585611751565b50505050565b610c69565b8360601b679a31110384e0b0c9178060601c9450846116565763ea553b346000526004601cfd5b8060205283600052604060002080548481018181101561167e576301336cea6000526004601cfd5b808355505050508260005281602052836000337fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260406000a4833b1561162457611624600085858585611819565b638b78c6d819805473ffffffffffffffffffffffffffffffffffffffff9092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b60008315611749578360051b8501855b803580851160051b948552602094851852604060002093018181106117275750505b501492915050565b60405163bc197c818082523360208301528660601b60601c604083015260a06060830152845160051b60200160c083018181838960045afa503d60a0018060808601523d82019150865160051b60200192508282848960045afa503d0160a0850152845160200191503d018181818760045afa50601c84013d82010391505060208382601c860160008b5af16117f6573d156117f1573d6000803e3d6000fd5b600083525b508060e01b82511461181057639c05499b6000526004601cfd5b50505050505050565b60405163f23a6e618082523360208301528660601b60601c604083015284606083015283608083015260a08083015282518060c08401528015611866578060e08401826020870160045afa505b6020838260c401601c860160008b5af16117f6573d156117f1573d6000803e3d6000fd5b803573ffffffffffffffffffffffffffffffffffffffff811681146118ae57600080fd5b919050565b600080604083850312156118c657600080fd5b6118cf8361188a565b946020939093013593505050565b6000602082840312156118ef57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461191f57600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561194e57600080fd5b813567ffffffffffffffff8082111561196657600080fd5b818401915084601f83011261197a57600080fd5b81358181111561198c5761198c611926565b604051601f8201601f19908116603f011681019083821181831017156119b4576119b4611926565b816040528281528760208487010111156119cd57600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000815180845260005b81811015611a13576020818501810151868301820152016119f7565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061191f60208301846119ed565b600060208284031215611a5857600080fd5b5035919050565b60008083601f840112611a7157600080fd5b50813567ffffffffffffffff811115611a8957600080fd5b6020830191508360208260051b8501011115611aa457600080fd5b9250929050565b60008060008060408587031215611ac157600080fd5b843567ffffffffffffffff80821115611ad957600080fd5b611ae588838901611a5f565b90965094506020870135915080821115611afe57600080fd5b50611b0b87828801611a5f565b95989497509550505050565b60008083601f840112611b2957600080fd5b50813567ffffffffffffffff811115611b4157600080fd5b602083019150836020828501011115611aa457600080fd5b60008060008060008060008060a0898b031215611b7557600080fd5b611b7e8961188a565b9750611b8c60208a0161188a565b9650604089013567ffffffffffffffff80821115611ba957600080fd5b611bb58c838d01611a5f565b909850965060608b0135915080821115611bce57600080fd5b611bda8c838d01611a5f565b909650945060808b0135915080821115611bf357600080fd5b50611c008b828c01611b17565b999c989b5096995094979396929594505050565b6020808252825182820181905260009190848201906040850190845b81811015611c4c57835183529284019291840191600101611c30565b50909695505050505050565b604081526000611c6b60408301856119ed565b90508260208301529392505050565b600060208284031215611c8c57600080fd5b61191f8261188a565b60008060408385031215611ca857600080fd5b611cb18361188a565b915060208301358015158114611cc657600080fd5b809150509250929050565b60008060008060608587031215611ce757600080fd5b843567ffffffffffffffff811115611cfe57600080fd5b611d0a87828801611a5f565b90989097506020870135966040013595509350505050565b60008060408385031215611d3557600080fd5b611d3e8361188a565b9150611d4c6020840161188a565b90509250929050565b60008060008060008060a08789031215611d6e57600080fd5b611d778761188a565b9550611d856020880161188a565b94506040870135935060608701359250608087013567ffffffffffffffff811115611daf57600080fd5b611dbb89828a01611b17565b979a9699509497509295939492505050565b600080600060408486031215611de257600080fd5b833567ffffffffffffffff811115611df957600080fd5b611e0586828701611a5f565b909790965060209590950135949350505050565b600181811c90821680611e2d57607f821691505b602082108103611e4d57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156114e857600081815260208120601f850160051c81016020861015611e7a5750805b601f850160051c820191505b818110156109d157828155600101611e86565b815167ffffffffffffffff811115611eb357611eb3611926565b611ec781611ec18454611e19565b84611e53565b602080601f831160018114611efc5760008415611ee45750858301515b600019600386901b1c1916600185901b1785556109d1565b600085815260208120601f198616915b82811015611f2b57888601518255948401946001909101908401611f0c565b5085821015611f495787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115611f9857611f98611f6f565b92915050565b60006000198203611fb157611fb1611f6f565b5060010190565b8082028115828204841417611f9857611f98611f6f56fea26469706673582212201d5e3737c19518835f6d145d034f7d2173eb405acc8dc3d2a78c0c90f3711b1864736f6c63430008120033
Deployed Bytecode
0x6080604052600436106101e25760003560e01c80635c5bc9ea11610102578063dab5f34011610095578063f242432a11610064578063f242432a1461059f578063f2fde38b146105bf578063f4ae63d1146105d2578063fee81cf4146105e557600080fd5b8063dab5f3401461051c578063e985e9c51461053c578063ebf0c71714610576578063f04e283e1461058c57600080fd5b8063a22cb465116100d1578063a22cb465146104ab578063af4b8e6e146104cb578063d351cfdc146104eb578063d7533f02146104fe57600080fd5b80635c5bc9ea1461040c578063715018a6146104555780638da5cb5b1461045d57806395d89b411461049657600080fd5b8063256929621161017a5780634f64b2be116101495780634f64b2be1461039357806353b8eb67146103c157806354d1f13d146103d457806355f94c9e146103dc57600080fd5b806325692962146103295780632eb2c2d6146103315780633ccfd60b146103515780634e1273f41461036657600080fd5b806306fdde03116101b657806306fdde03146102bf5780630dccc9ad146102e15780630e89341c146102f65780631dc485361461031657600080fd5b8062fdd58e146101e757806301ffc9a71461023a57806302fe53051461028757806306661abd146102a9575b600080fd5b3480156101f357600080fd5b506102276102023660046118b3565b60008260601b679a31110384e0b0c91760205281600052604060002054905092915050565b6040519081526020015b60405180910390f35b34801561024657600080fd5b506102776102553660046118dd565b6301ffc9a760e09190911c90811463d9b67a26821417630e89341c9091141790565b6040519015158152602001610231565b34801561029357600080fd5b506102a76102a236600461193c565b610618565b005b3480156102b557600080fd5b5061022760045481565b3480156102cb57600080fd5b506102d4610630565b6040516102319190611a33565b3480156102ed57600080fd5b506102d46106be565b34801561030257600080fd5b506102d4610311366004611a46565b6106cb565b6102a7610324366004611aab565b61075f565b6102a76109d9565b34801561033d57600080fd5b506102a761034c366004611b59565b610a29565b34801561035d57600080fd5b506102a7610c73565b34801561037257600080fd5b50610386610381366004611aab565b610caa565b6040516102319190611c14565b34801561039f57600080fd5b506103b36103ae366004611a46565b610d1a565b604051610231929190611c58565b6102a76103cf366004611a46565b610dbe565b6102a7610e93565b3480156103e857600080fd5b506102776103f7366004611c7a565b60066020526000908152604090205460ff1681565b34801561041857600080fd5b50604080516bffffffffffffffffffffffff193360601b166020808301919091528251601481840301815260349092019092528051910120610227565b6102a7610ecf565b34801561046957600080fd5b50638b78c6d8195460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610231565b3480156104a257600080fd5b506102d4610ee3565b3480156104b757600080fd5b506102a76104c6366004611c95565b610ef0565b3480156104d757600080fd5b506102776104e6366004611cd1565b610f4a565b6102a76104f9366004611aab565b610f63565b34801561050a57600080fd5b506040516202a3008152602001610231565b34801561052857600080fd5b506102a7610537366004611a46565b611197565b34801561054857600080fd5b50610277610557366004611d22565b60609190911b679a31110384e0b0c9176020526000526034600c205490565b34801561058257600080fd5b5061022760035481565b6102a761059a366004611c7a565b6111a4565b3480156105ab57600080fd5b506102a76105ba366004611d55565b611210565b6102a76105cd366004611c7a565b611373565b6102a76105e0366004611dcd565b6113d4565b3480156105f157600080fd5b50610227610600366004611c7a565b63389a75e1600c908152600091909152602090205490565b6106206114ed565b600261062c8282611e99565b5050565b6000805461063d90611e19565b80601f016020809104026020016040519081016040528092919081815260200182805461066990611e19565b80156106b65780601f1061068b576101008083540402835291602001916106b6565b820191906000526020600020905b81548152906001019060200180831161069957829003601f168201915b505050505081565b6002805461063d90611e19565b6060600280546106da90611e19565b80601f016020809104026020016040519081016040528092919081815260200182805461070690611e19565b80156107535780601f1061072857610100808354040283529160200191610753565b820191906000526020600020905b81548152906001019060200180831161073657829003601f168201915b50505050509050919050565b60038114610799576040517f2897e94800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600380825260808201909252600191600091906020820160608036833701905050905081816000815181106107d4576107d4611f59565b60200260200101818152505081816001815181106107f4576107f4611f59565b602002602001018181525050818160028151811061081457610814611f59565b602002602001018181525050607b60045460036108319190611f85565b118061084c57503360009081526006602052604090205460ff165b1561086a57604051632eccfe9760e11b815260040160405180910390fd5b6108b386866003546104e66040513360601b6bffffffffffffffffffffffff19811660208301526000916034016040516020818303038152906040528051906020012091505090565b1561099f57610905338585808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250604080516020810190915290815287935091506115089050565b60005b838110156109675760016005600087878581811061092857610928611f59565b905060200201358152602001908152602001600020600101600082825461094f9190611f85565b9091555081905061095f81611f9e565b915050610908565b5060036004600082825461097b9190611f85565b9091555050336000908152600660205260409020805460ff191660011790556109d1565b6040517fd838648f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b828514610a3e57633b800a466000526004601cfd5b8760601b679a31110384e0b0c9178760601b679a31110384e0b0c917816020528160601c99508060601c985088610a7d5763ea553b346000526004601cfd5b893314610aa057336000526034600c2054610aa057634b6e7f186000526004601cfd5b8660051b60005b818114610b11578088013584602052818b01356000526040600020805480831115610ada5763f4d678b86000526004601cfd5b829003905560208490526040600020805480830181811015610b04576301336cea6000526004601cfd5b9091555050602001610aa7565b50505050604051604081528560051b602001604082018160208a03823760408201602084810191909152600587901b01910181601f198801823701819003888a337f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8486a45050610b80600090565b15610b9557610b95888888888888888861162a565b863b15610c695760405163bc197c8180825233602083015289604083015260a060608301528660051b60200160c083018160208b0382378160a00180608086015282820191508760051b60200192508260208a038337820160a085015260208501910181601f1987018237018290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe40160208382601c820160008e5af1610c4c573d15610c47573d6000803e3d6000fd5b600083525b508060e01b825114610c6657639c05499b6000526004601cfd5b50505b5050505050505050565b610c7b6114ed565b6040514790339082156108fc029083906000818181858888f1935050505015801561062c573d6000803e3d6000fd5b6060838214610cc157633b800a466000526004601cfd5b6040519050818152602081018260051b81810160405260005b818114610d0f57679a31110384e0b0c98882013560601b17602090815286820135600090815260409020548483015201610cda565b505050949350505050565b600560205260009081526040902080548190610d3590611e19565b80601f0160208091040260200160405190810160405280929190818152602001828054610d6190611e19565b8015610dae5780601f10610d8357610100808354040283529160200191610dae565b820191906000526020600020905b815481529060010190602001808311610d9157829003601f168201915b5050505050908060010154905082565b607b6004546001610dcf9190611f85565b1115610dee57604051632eccfe9760e11b815260040160405180910390fd5b346618de76816d800014610e2e576040517f48b1ee8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e4a338260016040518060200160405280600081525061162f565b6001600560008381526020019081526020016000206001016000828254610e719190611f85565b92505081905550600160046000828254610e8b9190611f85565b909155505050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b610ed76114ed565b610ee160006116cc565b565b6001805461063d90611e19565b8160601b60601c915080151590503360601b679a31110384e0b0c91760205281600052806034600c20558060005281337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160206000a35050565b600080610f5986868686611717565b9695505050505050565b828114610f9c576040517f7955807f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561101957848482818110610fbc57610fbc611f59565b905060200201356618de76816d8000610fd59190611fb8565b610fdf9083611f85565b9150848482818110610ff357610ff3611f59565b90506020020135836110059190611f85565b92508061101181611f9e565b915050610fa2565b50607b8260045461102a9190611f85565b111561104957604051632eccfe9760e11b815260040160405180910390fd5b803414611082576040517f48b1ee8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110fe3387878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092018290525060408051602081019091529081529250611508915050565b60005b858110156111775784848281811061111b5761111b611f59565b905060200201356005600089898581811061113857611138611f59565b905060200201358152602001908152602001600020600101600082825461115f9190611f85565b9091555081905061116f81611f9e565b915050611101565b50816004600082825461118a9190611f85565b9091555050505050505050565b61119f6114ed565b600355565b6111ac6114ed565b63389a75e1600c52806000526020600c2080544211156111d457636f5e88186000526004601cfd5b6000815550600c5160601c80337f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3638b78c6d8195550565b8560601b679a31110384e0b0c9178560601b679a31110384e0b0c917816020528160601c97508060601c965087331461125f57336000526034600c205461125f57634b6e7f186000526004601cfd5b866112725763ea553b346000526004601cfd5b85600052604060002091508154808611156112955763f4d678b86000526004601cfd5b85810383555080602052604060002091508154858101818110156112c1576301336cea6000526004601cfd5b909255505060208390528486337fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260406000a4843b156109d15760405163f23a6e6180825233602083015287604083015285606083015284608083015260a080830152826020016020850360c08401376020828460c401601c850160008b5af161135a573d15611355573d6000803e3d6000fd5b600082525b8060e01b825114610c6957639c05499b6000526004601cfd5b61137b6114ed565b73ffffffffffffffffffffffffffffffffffffffff81166113c8576040517f7448fbae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113d1816116cc565b50565b607b60045460036113e59190611f85565b118061140057503360009081526006602052604090205460ff165b1561141e57604051632eccfe9760e11b815260040160405180910390fd5b61146783836003546104e66040513360601b6bffffffffffffffffffffffff19811660208301526000916034016040516020818303038152906040528051906020012091505090565b1561099f57611488338260036040518060200160405280600081525061162f565b60008181526005602052604081206001018054600392906114aa908490611f85565b925050819055506003600460008282546114c49190611f85565b9091555050336000908152600660205260409020805460ff19166001179055505050565b505050565b638b78c6d819543314610ee1576382b429006000526004601cfd5b815183511461151f57633b800a466000526004601cfd5b8360601b679a31110384e0b0c9178060601c9450846115465763ea553b346000526004601cfd5b835160051b60005b81811461159557602081019050808501518360205281870151600052604060002080548281018181101561158a576301336cea6000526004601cfd5b9091555061154e9050565b50505060405160408152835160051b602001604082018181838860045afa503d60400160208401523d81019050845160051b60200191508181838760045afa503d018290039050856000337f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8486a4505061160e600090565b50833b1561162457611624600085858585611751565b50505050565b610c69565b8360601b679a31110384e0b0c9178060601c9450846116565763ea553b346000526004601cfd5b8060205283600052604060002080548481018181101561167e576301336cea6000526004601cfd5b808355505050508260005281602052836000337fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260406000a4833b1561162457611624600085858585611819565b638b78c6d819805473ffffffffffffffffffffffffffffffffffffffff9092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b60008315611749578360051b8501855b803580851160051b948552602094851852604060002093018181106117275750505b501492915050565b60405163bc197c818082523360208301528660601b60601c604083015260a06060830152845160051b60200160c083018181838960045afa503d60a0018060808601523d82019150865160051b60200192508282848960045afa503d0160a0850152845160200191503d018181818760045afa50601c84013d82010391505060208382601c860160008b5af16117f6573d156117f1573d6000803e3d6000fd5b600083525b508060e01b82511461181057639c05499b6000526004601cfd5b50505050505050565b60405163f23a6e618082523360208301528660601b60601c604083015284606083015283608083015260a08083015282518060c08401528015611866578060e08401826020870160045afa505b6020838260c401601c860160008b5af16117f6573d156117f1573d6000803e3d6000fd5b803573ffffffffffffffffffffffffffffffffffffffff811681146118ae57600080fd5b919050565b600080604083850312156118c657600080fd5b6118cf8361188a565b946020939093013593505050565b6000602082840312156118ef57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461191f57600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561194e57600080fd5b813567ffffffffffffffff8082111561196657600080fd5b818401915084601f83011261197a57600080fd5b81358181111561198c5761198c611926565b604051601f8201601f19908116603f011681019083821181831017156119b4576119b4611926565b816040528281528760208487010111156119cd57600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000815180845260005b81811015611a13576020818501810151868301820152016119f7565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061191f60208301846119ed565b600060208284031215611a5857600080fd5b5035919050565b60008083601f840112611a7157600080fd5b50813567ffffffffffffffff811115611a8957600080fd5b6020830191508360208260051b8501011115611aa457600080fd5b9250929050565b60008060008060408587031215611ac157600080fd5b843567ffffffffffffffff80821115611ad957600080fd5b611ae588838901611a5f565b90965094506020870135915080821115611afe57600080fd5b50611b0b87828801611a5f565b95989497509550505050565b60008083601f840112611b2957600080fd5b50813567ffffffffffffffff811115611b4157600080fd5b602083019150836020828501011115611aa457600080fd5b60008060008060008060008060a0898b031215611b7557600080fd5b611b7e8961188a565b9750611b8c60208a0161188a565b9650604089013567ffffffffffffffff80821115611ba957600080fd5b611bb58c838d01611a5f565b909850965060608b0135915080821115611bce57600080fd5b611bda8c838d01611a5f565b909650945060808b0135915080821115611bf357600080fd5b50611c008b828c01611b17565b999c989b5096995094979396929594505050565b6020808252825182820181905260009190848201906040850190845b81811015611c4c57835183529284019291840191600101611c30565b50909695505050505050565b604081526000611c6b60408301856119ed565b90508260208301529392505050565b600060208284031215611c8c57600080fd5b61191f8261188a565b60008060408385031215611ca857600080fd5b611cb18361188a565b915060208301358015158114611cc657600080fd5b809150509250929050565b60008060008060608587031215611ce757600080fd5b843567ffffffffffffffff811115611cfe57600080fd5b611d0a87828801611a5f565b90989097506020870135966040013595509350505050565b60008060408385031215611d3557600080fd5b611d3e8361188a565b9150611d4c6020840161188a565b90509250929050565b60008060008060008060a08789031215611d6e57600080fd5b611d778761188a565b9550611d856020880161188a565b94506040870135935060608701359250608087013567ffffffffffffffff811115611daf57600080fd5b611dbb89828a01611b17565b979a9699509497509295939492505050565b600080600060408486031215611de257600080fd5b833567ffffffffffffffff811115611df957600080fd5b611e0586828701611a5f565b909790965060209590950135949350505050565b600181811c90821680611e2d57607f821691505b602082108103611e4d57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156114e857600081815260208120601f850160051c81016020861015611e7a5750805b601f850160051c820191505b818110156109d157828155600101611e86565b815167ffffffffffffffff811115611eb357611eb3611926565b611ec781611ec18454611e19565b84611e53565b602080601f831160018114611efc5760008415611ee45750858301515b600019600386901b1c1916600185901b1785556109d1565b600085815260208120601f198616915b82811015611f2b57888601518255948401946001909101908401611f0c565b5085821015611f495787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115611f9857611f98611f6f565b92915050565b60006000198203611fb157611fb1611f6f565b5060010190565b8082028115828204841417611f9857611f98611f6f56fea26469706673582212201d5e3737c19518835f6d145d034f7d2173eb405acc8dc3d2a78c0c90f3711b1864736f6c63430008120033
Deployed Bytecode Sourcemap
119861:3929:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75528:329;;;;;;;;;;-1:-1:-1;75528:329:0;;;;;:::i;:::-;75603:14;75749:5;75745:2;75741:14;75714:25;75711:45;75705:4;75698:59;75784:2;75778:4;75771:16;75833:4;75827;75817:21;75811:28;75801:38;;75528:329;;;;;;;;620:25:1;;;608:2;593:18;75528:329:0;;;;;;;;89857:392;;;;;;;;;;-1:-1:-1;89857:392:0;;;;;:::i;:::-;90180:10;90038:3;90034:21;;;;90174:17;;;90199:10;90193:17;;90171:40;90219:10;90213:17;;;90168:63;;89857:392;;;;1158:14:1;;1151:22;1133:41;;1121:2;1106:18;89857:392:0;993:187:1;123546:89:0;;;;;;;;;;-1:-1:-1;123546:89:0;;;;;:::i;:::-;;:::i;:::-;;120348:20;;;;;;;;;;;;;;;;120133:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;120213:18::-;;;;;;;;;;;;;:::i;123433:105::-;;;;;;;;;;-1:-1:-1;123433:105:0;;;;;:::i;:::-;;:::i;122151:750::-;;;;;;:::i;:::-;;:::i;65925:621::-;;;:::i;82432:5994::-;;;;;;;;;;-1:-1:-1;82432:5994:0;;;;;:::i;:::-;;:::i;123643:142::-;;;;;;;;;;;;;:::i;88579:1064::-;;;;;;;;;;-1:-1:-1;88579:1064:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;120377:36::-;;;;;;;;;;-1:-1:-1;120377:36:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;120641:304::-;;;;;;:::i;:::-;;:::i;66631:466::-;;;:::i;120420:43::-;;;;;;;;;;-1:-1:-1;120420:43:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;123238:148;;;;;;;;;;-1:-1:-1;123357:20:0;;;-1:-1:-1;;123318:10:0;123310:19;;15536:79:1;123357:20:0;;;;15524:92:1;;;;123357:20:0;;;;;;;;;15632:12:1;;;;123357:20:0;;;123347:31;;;;;123238:148;;65657:102;;;:::i;68640:196::-;;;;;;;;;;-1:-1:-1;;;68791:27:0;68640:196;;8234:42:1;8222:55;;;8204:74;;8192:2;8177:18;68640:196:0;8058:226:1;120178:28:0;;;;;;;;;;;;;:::i;76481:753::-;;;;;;;;;;-1:-1:-1;76481:753:0;;;;;:::i;:::-;;:::i;122985:199::-;;;;;;;;;;-1:-1:-1;122985:199:0;;;;;:::i;:::-;;:::i;121419:724::-;;;;;;:::i;:::-;;:::i;69485:109::-;;;;;;;;;;-1:-1:-1;69485:109:0;;69577:9;10141:50:1;;10129:2;10114:18;69485:109:0;9997:200:1;120549:84:0;;;;;;;;;;-1:-1:-1;120549:84:0;;;;;:::i;:::-;;:::i;75951:386::-;;;;;;;;;;-1:-1:-1;75951:386:0;;;;;:::i;:::-;76219:2;76215:14;;;;76188:25;76185:45;76179:4;76172:59;76075:11;76245:22;76313:4;76307;76297:21;76291:28;;75951:386;120238:19;;;;;;;;;;;;;;;;67288:1008;;;;;;:::i;:::-;;:::i;77726:4144::-;;;;;;;;;;-1:-1:-1;77726:4144:0;;;;;:::i;:::-;;:::i;65404:185::-;;;;;;:::i;:::-;;:::i;120953:458::-;;;;;;:::i;:::-;;:::i;68942:449::-;;;;;;;;;;-1:-1:-1;68942:449:0;;;;;:::i;:::-;69221:19;69215:4;69208:33;;;69065:14;69255:26;;;;69367:4;69351:21;;69345:28;;68942:449;123546:89;69991:13;:11;:13::i;:::-;123614:4:::1;:13;123621:6:::0;123614:4;:13:::1;:::i;:::-;;123546:89:::0;:::o;120133:38::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;120213:18::-;;;;;;;:::i;123433:105::-;123493:13;123526:4;123519:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;123433:105;;;:::o;122151:750::-;122295:1;122281:15;;122278:38;;122305:11;;;;;;;;;;;;;;122278:38;122379:16;;;122393:1;122379:16;;;;;;;;;122343:1;;122329:11;;122379:16;;;;;;;;;;;-1:-1:-1;122379:16:0;122355:40;;122416:3;122406:4;122411:1;122406:7;;;;;;;;:::i;:::-;;;;;;:13;;;;;122440:3;122430:4;122435:1;122430:7;;;;;;;;:::i;:::-;;;;;;:13;;;;;122464:3;122454:4;122459:1;122454:7;;;;;;;;:::i;:::-;;;;;;:13;;;;;122494:3;122482:5;;122490:1;122482:9;;;;:::i;:::-;:15;:42;;;-1:-1:-1;122513:10:0;122501:23;;;;:11;:23;;;;;;;;122482:42;122478:77;;;122535:18;;-1:-1:-1;;;122535:18:0;;;;;;;;;;;122478:77;122568:29;122575:5;;122582:4;;122588:8;123357:20;;123318:10;123310:19;;-1:-1:-1;;15536:79:1;;123357:20:0;;;15524:92:1;123277:7:0;;15632:12:1;;123357:20:0;;;;;;;;;;;;123347:31;;;;;;123340:38;;;123238:148;;122568:29;122565:329;;;122609:37;122620:10;122632:3;;122609:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;122609:37:0;;;;;;;;;;;;122637:4;;-1:-1:-1;122609:37:0;-1:-1:-1;122609:10:0;;-1:-1:-1;122609:37:0:i;:::-;122662:6;122657:98;122674:14;;;122657:98;;;122742:1;122710:6;:14;122717:3;;122721:1;122717:6;;;;;;;:::i;:::-;;;;;;;122710:14;;;;;;;;;;;:28;;;:33;;;;;;;:::i;:::-;;;;-1:-1:-1;122690:3:0;;-1:-1:-1;122690:3:0;;;:::i;:::-;;;;122657:98;;;;122774:1;122765:5;;:10;;;;;;;:::i;:::-;;;;-1:-1:-1;;122798:10:0;122786:23;;;;:11;:23;;;;;:30;;-1:-1:-1;;122786:30:0;122812:4;122786:30;;;122565:329;;;122856:26;;;;;;;;;;;;;;122565:329;122265:636;;122151:750;;;;:::o;65925:621::-;66020:15;69577:9;66038:45;;:15;:45;66020:63;;66247:19;66241:4;66234:33;66298:8;66292:4;66285:22;66355:7;66348:4;66342;66332:21;66325:38;66504:8;66457:45;66454:1;66451;66446:67;66155:373;65925:621::o;82432:5994::-;82851:14;82839:10;82836:30;82826:165;;82900:10;82894:4;82887:24;82971:4;82965;82958:18;82826:165;83063:4;83059:2;83055:13;83028:25;83025:44;83139:2;83135;83131:11;83104:25;83101:42;83170:12;83164:4;83157:26;83254:12;83250:2;83246:21;83238:29;;83295:10;83291:2;83287:19;83281:25;;83382:2;83372:138;;83418:10;83412:4;83405:24;83490:4;83484;83477:18;83372:138;83620:4;83610:8;83607:18;83597:278;;83659:8;83653:4;83646:22;83718:4;83712;83702:21;83696:28;83686:174;;83762:10;83756:4;83749:24;83836:4;83830;83823:18;83686:174;83994:10;83991:1;83987:18;84038:1;84023:1489;84055:3;84052:1;84049:10;84023:1489;;84153:1;84137:14;84133:22;84120:36;84292:12;84286:4;84279:26;84373:1;84361:10;84357:18;84344:32;84338:4;84331:46;84442:4;84436;84426:21;84498:15;84492:22;84554:11;84546:6;84543:23;84540:185;;;84611:10;84605:4;84598:24;84693:4;84687;84680:18;84540:185;84775:24;;;84751:49;;84951:4;84944:24;;;85031:4;85025;85015:21;85085:20;;85153:28;;;85210:35;;;85207:200;;;85290:10;85284:4;85277:24;85375:4;85369;85362:18;85207:200;85433:37;;;-1:-1:-1;;84075:4:0;84068:12;84023:1489;;;84027:14;;83957:1570;;85621:4;85615:11;85690:4;85687:1;85680:15;85739:10;85736:1;85732:18;85726:4;85722:29;85785:4;85782:1;85778:12;85847:1;85840:4;85828:10;85824:21;85821:1;85808:41;85932:4;85928:12;;85921:4;85914:12;;;85907:34;;;;86010:1;86006:22;;;85996:33;;85964:9;85996:33;-1:-1:-1;;86063:25:0;;85964:9;86047:45;86119:9;86115:17;;;86243:2;86237:4;86227:8;86194:31;86115:17;86130:1;86183:63;;;86286:24;113162:4;113096:103;;86286:24;86282:114;;;86327:57;86355:4;86361:2;86365:3;;86370:7;;86379:4;;86327:27;:57::i;:::-;86572:2;86560:15;86557:1851;;;86610:4;86604:11;86713:10;86751:30;86748:1;86741:41;86821:8;86814:4;86811:1;86807:12;86800:30;86869:4;86862;86859:1;86855:12;86848:26;86949:4;86942;86939:1;86935:12;86928:26;86998:10;86995:1;86991:18;86985:4;86981:29;87044:4;87041:1;87037:12;87106:1;87099:4;87087:10;87083:21;87080:1;87067:41;87185:1;87179:4;87175:12;87226:1;87219:4;87216:1;87212:12;87205:23;87258:1;87255;87251:9;87246:14;;87300;87297:1;87293:22;87287:4;87283:33;87278:38;;87377:1;87370:4;87354:14;87350:25;87347:1;87334:45;87455:9;;87448:4;87441:12;;87434:31;87524:4;87520:22;;;87488:9;87520:22;-1:-1:-1;;87576:22:0;;87488:9;87560:42;87629:9;87625:28;;;;;87768:4;87625:28;;87647:4;87640:12;;87745:1;87741:2;87734:5;87729:44;87719:380;;87801:16;87798:248;;;87950:16;87944:4;87938;87923:44;88006:16;88000:4;87993:30;87798:248;88078:1;88075;88068:12;87719:380;;88205:30;88200:3;88196:40;88192:1;88186:8;88183:54;88173:220;;88275:10;88269:4;88262:24;88369:4;88363;88356:18;88173:220;;;86557:1851;82432:5994;;;;;;;;:::o;123643:142::-;69991:13;:11;:13::i;:::-;123740:37:::1;::::0;123708:21:::1;::::0;123748:10:::1;::::0;123740:37;::::1;;;::::0;123708:21;;123693:12:::1;123740:37:::0;123693:12;123740:37;123708:21;123748:10;123740:37;::::1;;;;;;;;;;;;;::::0;::::1;;;;88579:1064:::0;88719:25;88855:13;88843:10;88840:29;88830:164;;88903:10;88897:4;88890:24;88974:4;88968;88961:18;88830:164;89026:4;89020:11;89008:23;;89062:10;89052:8;89045:28;89110:4;89100:8;89096:19;89147:10;89144:1;89140:18;89194:1;89189:3;89185:11;89179:4;89172:25;89292:1;89277:348;89309:3;89306:1;89303:10;89277:348;;89438:25;89382:21;;;89369:35;89469:2;89465:14;89435:45;89429:4;89422:59;;;89525:18;;;89512:32;89506:4;89499:46;;;89603:4;89587:21;;89581:28;89570:9;;;89563:47;89322:12;89277:348;;;89281:14;;;88579:1064;;;;;;:::o;120377:36::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;120641:304::-;120728:3;120716:5;;120724:1;120716:9;;;;:::i;:::-;:15;120712:50;;;120742:18;;-1:-1:-1;;;120742:18:0;;;;;;;;;;;120712:50;120776:9;120789:16;120776:29;120772:66;;120816:20;;;;;;;;;;;;;;120772:66;120848:28;120854:10;120866:2;120870:1;120848:28;;;;;;;;;;;;:5;:28::i;:::-;120915:1;120887:6;:10;120894:2;120887:10;;;;;;;;;;;:24;;;:29;;;;;;;:::i;:::-;;;;;;;;120936:1;120927:5;;:10;;;;;;;:::i;:::-;;;;-1:-1:-1;;;120641:304:0:o;66631:466::-;66837:19;66831:4;66824:33;66884:8;66878:4;66871:22;66937:1;66930:4;66924;66914:21;66907:32;67070:8;67024:44;67021:1;67018;67013:66;66631:466::o;65657:102::-;69991:13;:11;:13::i;:::-;65730:21:::1;65748:1;65730:9;:21::i;:::-;65657:102::o:0;120178:28::-;;;;;;;:::i;76481:753::-;76706:8;76702:2;76698:17;76694:2;76690:26;76678:38;;76793:10;76786:18;76779:26;76765:40;;76942:8;76938:2;76934:17;76907:25;76904:48;76898:4;76891:62;76980:8;76974:4;76967:22;77033:10;77026:4;77020;77010:21;77003:41;77120:10;77114:4;77107:24;77207:8;77197;77162:33;77156:4;77150;77145:71;76481:753;;:::o;122985:199::-;123076:4;123093:10;123106:47;123136:5;;123143:3;123148:4;123106:29;:47::i;:::-;123093:60;122985:199;-1:-1:-1;;;;;;122985:199:0:o;121419:724::-;121540:28;;;121537:58;;121577:18;;;;;;;;;;;;;;121537:58;121606:12;121629:20;121665:6;121660:146;121677:14;;;121660:146;;;121732:7;;121740:1;121732:10;;;;;;;:::i;:::-;;;;;;;121745:16;121732:29;;;;:::i;:::-;121713:48;;;;:::i;:::-;;;121784:7;;121792:1;121784:10;;;;;;;:::i;:::-;;;;;;;121776:18;;;;;:::i;:::-;;-1:-1:-1;121693:3:0;;;;:::i;:::-;;;;121660:146;;;;121835:3;121828:4;121820:5;;:12;;;;:::i;:::-;:18;121816:53;;;121849:18;;-1:-1:-1;;;121849:18:0;;;;;;;;;;;121816:53;121896:15;121883:9;:28;121879:65;;121922:20;;;;;;;;;;;;;;121879:65;121954:40;121965:10;121977:3;;121954:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;121954:40:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;121982:7:0;;-1:-1:-1;121982:7:0;;;;121954:40;;;121982:7;;121954:40;121982:7;121954:40;;;;;;;;-1:-1:-1;121954:40:0;;;;;;;;;;;;;-1:-1:-1;121954:10:0;;-1:-1:-1;;121954:40:0:i;:::-;122010:6;122005:107;122022:14;;;122005:107;;;122090:7;;122098:1;122090:10;;;;;;;:::i;:::-;;;;;;;122058:6;:14;122065:3;;122069:1;122065:6;;;;;;;:::i;:::-;;;;;;;122058:14;;;;;;;;;;;:28;;;:42;;;;;;;:::i;:::-;;;;-1:-1:-1;122038:3:0;;-1:-1:-1;122038:3:0;;;:::i;:::-;;;;122005:107;;;;122131:4;122122:5;;:13;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;;121419:724:0:o;120549:84::-;69991:13;:11;:13::i;:::-;120611:4:::1;:14:::0;120549:84::o;67288:1008::-;69991:13;:11;:13::i;:::-;67526:19:::1;67520:4;67513:33;67573:12;67567:4;67560:26;67636:4;67630;67620:21;67744:12;67738:19;67725:11;67722:36;67719:159;;;67791:35;67785:4;67778:49;67858:4;67852;67845:18;67719:159;67957:1;67943:12;67936:23;;68044:4;68038:11;68034:2;68030:20;68180:8;68170;68130:38;68127:1;68124::::0;68119:70:::1;-1:-1:-1::0;;68240:38:0;-1:-1:-1;67288:1008:0:o;77726:4144::-;78165:4;78161:2;78157:13;78130:25;78127:44;78241:2;78237;78233:11;78206:25;78203:42;78272:12;78266:4;78259:26;78356:12;78352:2;78348:21;78340:29;;78397:10;78393:2;78389:19;78383:25;;78518:4;78508:8;78505:18;78495:278;;78557:8;78551:4;78544:22;78616:4;78610;78600:21;78594:28;78584:174;;78660:10;78654:4;78647:24;78734:4;78728;78721:18;78584:174;78849:2;78839:138;;78885:10;78879:4;78872:24;78957:4;78951;78944:18;78839:138;79089:2;79083:4;79076:16;79149:4;79143;79133:21;79110:44;;79197:15;79191:22;79245:11;79237:6;79234:23;79231:161;;;79294:10;79288:4;79281:24;79368:4;79362;79355:18;79231:161;79451:6;79438:11;79434:24;79417:15;79410:49;;79584:10;79578:4;79571:24;79650:4;79644;79634:21;79613:42;;79702:13;79696:20;79777:6;79760:15;79756:28;79824:15;79808:14;79805:35;79802:176;;;79877:10;79871:4;79864:24;79954:4;79948;79941:18;79802:176;79996:37;;;-1:-1:-1;;80135:4:0;80128:20;;;80233:2;80227:4;80217:8;80183:32;80177:4;80171;80166:70;80565:2;80553:15;80550:1302;;;80645:4;80639:11;80701:10;80739:25;80736:1;80729:36;80804:8;80797:4;80794:1;80790:12;80783:30;80852:4;80845;80842:1;80838:12;80831:26;80896:2;80889:4;80886:1;80882:12;80875:24;80938:6;80931:4;80928:1;80924:12;80917:28;80984:4;80977;80974:1;80970:12;80963:26;81068:11;81062:4;81058:22;81051:4;81038:11;81034:22;81027:4;81024:1;81020:12;81007:74;81217:4;81214:1;81200:11;81194:4;81190:22;81183:4;81180:1;81176:12;81173:1;81169:2;81162:5;81157:65;81147:401;;81250:16;81247:248;;;81399:16;81393:4;81387;81372:44;81455:16;81449:4;81442:30;81247:248;81527:1;81524;81517:12;81147:401;81654:25;81649:3;81645:35;81641:1;81635:8;81632:49;81622:215;;81719:10;81713:4;81706:24;81813:4;81807;81800:18;65404:185;69991:13;:11;:13::i;:::-;65497:22:::1;::::0;::::1;65493:58;;65528:23;;;;;;;;;;;;;;65493:58;65562:19;65572:8;65562:9;:19::i;:::-;65404:185:::0;:::o;120953:458::-;121081:3;121069:5;;121077:1;121069:9;;;;:::i;:::-;:15;:42;;;-1:-1:-1;121100:10:0;121088:23;;;;:11;:23;;;;;;;;121069:42;121065:77;;;121122:18;;-1:-1:-1;;;121122:18:0;;;;;;;;;;;121065:77;121155:29;121162:5;;121169:4;;121175:8;123357:20;;123318:10;123310:19;;-1:-1:-1;;15536:79:1;;123357:20:0;;;15524:92:1;123277:7:0;;15632:12:1;;123357:20:0;;;;;;;;;;;;123347:31;;;;;;123340:38;;;123238:148;;121155:29;121152:252;;;121196:28;121202:10;121214:2;121218:1;121196:28;;;;;;;;;;;;:5;:28::i;:::-;121235:10;;;;:6;:10;;;;;:24;;:29;;121263:1;;121235:10;:29;;121263:1;;121235:29;:::i;:::-;;;;;;;;121284:1;121275:5;;:10;;;;;;;:::i;:::-;;;;-1:-1:-1;;121308:10:0;121296:23;;;;:11;:23;;;;;:30;;-1:-1:-1;;121296:30:0;121322:4;121296:30;;;120953:458;;;:::o;121152:252::-;120953:458;;;:::o;64667:370::-;-1:-1:-1;;64877:27:0;64867:8;64864:41;64854:165;;64939:28;64933:4;64926:42;64999:4;64993;64986:18;92980:2939;93373:7;93367:14;93361:3;93355:10;93352:30;93342:165;;93416:10;93410:4;93403:24;93487:4;93481;93474:18;93342:165;93577:2;93573;93569:11;93542:25;93539:42;93650:10;93646:2;93642:19;93636:25;;93737:2;93727:138;;93773:10;93767:4;93760:24;93845:4;93839;93832:18;93727:138;93990:3;93984:10;93981:1;93977:18;94028:1;94013:886;94045:3;94042:1;94039:10;94013:886;;94089:4;94086:1;94082:12;94077:17;;94149:1;94140:7;94136:15;94130:22;94286:10;94280:4;94273:24;94351:1;94346:3;94342:11;94336:18;94330:4;94323:32;94418:4;94412;94402:21;94478:13;94472:20;94561:6;94544:15;94540:28;94616:15;94600:14;94597:35;94594:200;;;94677:10;94671:4;94664:24;94762:4;94756;94749:18;94594:200;94820:37;;;-1:-1:-1;94013:886:0;;-1:-1:-1;94013:886:0;;94017:14;;93947:967;95008:4;95002:11;95077:4;95074:1;95067:15;95132:3;95126:10;95123:1;95119:18;95113:4;95109:29;95172:4;95169:1;95165:12;95231:1;95228;95225;95220:3;95217:1;95210:5;95199:34;95195:39;95323:16;95317:4;95313:27;95306:4;95303:1;95299:12;95292:49;95371:16;95368:1;95364:24;95359:29;;95434:7;95428:14;95425:1;95421:22;95415:4;95411:33;95406:38;;95502:1;95499;95496;95487:7;95484:1;95477:5;95466:38;-1:-1:-1;95539:16:0;95532:24;95528:32;;;;-1:-1:-1;95668:2:0;95665:1;95655:8;95622:31;95528:32;95558:1;95611:60;;;95711:24;113162:4;113096:103;;95711:24;95707:112;115424:14;;95829:82;;;95847:64;95884:1;95888:2;95892:3;95897:7;95906:4;95847:28;:64::i;:::-;92980:2939;;;;:::o;114881:320::-;115088:106;;90854:1738;91220:2;91216;91212:11;91185:25;91182:42;91293:10;91289:2;91285:19;91279:25;;91380:2;91370:138;;91416:10;91410:4;91403:24;91488:4;91482;91475:18;91370:138;91618:10;91612:4;91605:24;91660:2;91654:4;91647:16;91718:4;91712;91702:21;91770:13;91764:20;91845:6;91828:15;91824:28;91892:15;91876:14;91873:35;91870:176;;;91945:10;91939:4;91932:24;92022:4;92016;92009:18;91870:176;92086:14;92071:13;92064:37;;;;91586:530;92209:2;92203:4;92196:16;92243:6;92237:4;92230:20;92332:2;92329:1;92319:8;92285:32;92279:4;92273;92268:67;115424:14;;92509:75;;;92527:57;92559:1;92563:2;92567;92571:6;92579:4;92527:23;:57::i;64100:506::-;-1:-1:-1;;64483:16:0;;64337:26;;;;;;;64443:38;64440:1;;64432:78;64561:27;64100:506::o;47465:1436::-;47593:12;47694;47691:1153;;;47836:12;47833:1;47829:20;47815:12;47811:39;47964:12;48064:765;48260:20;;48251:30;;;48248:1;48244:38;48478:21;;;48541:4;48528:18;;;48521:48;48698:4;48692;48682:21;;48735:17;48784:15;;;48064:765;48774:36;48068:2;;47691:1153;-1:-1:-1;48869:14:0;;47465:1436;-1:-1:-1;;47465:1436:0:o;117319:2029::-;117642:4;117636:11;117699:10;117733:30;117730:1;117723:41;117799:8;117792:4;117789:1;117785:12;117778:30;117859:4;117855:2;117851:13;117847:2;117843:22;117836:4;117833:1;117829:12;117822:44;117933:4;117926;117923:1;117919:12;117912:26;117984:3;117978:10;117975:1;117971:18;117965:4;117961:29;118020:4;118017:1;118013:12;118075:1;118072;118069;118064:3;118061:1;118054:5;118043:34;118039:39;118147:16;118141:4;118137:27;118199:1;118192:4;118189:1;118185:12;118178:23;118227:16;118224:1;118220:24;118215:29;;118286:7;118280:14;118277:1;118273:22;118267:4;118263:33;118258:38;;118350:1;118347;118344;118335:7;118332:1;118325:5;118314:38;-1:-1:-1;118428:16:0;118421:24;118414:4;118407:12;;118400:46;118518:11;;118512:4;118508:22;;-1:-1:-1;118472:16:0;118465:24;118508:22;118465:24;118508:22;118524:4;118566:1;118559:5;118548:35;118544:40;118640:4;118637:1;118633:12;118614:16;118611:1;118607:24;118603:43;118598:48;;;118753:4;118750:1;118747;118740:4;118737:1;118733:12;118730:1;118726:2;118719:5;118714:44;118704:352;;118782:16;118779:232;;;118923:16;118917:4;118911;118896:44;118975:16;118969:4;118962:30;118779:232;119039:1;119036;119029:12;118704:352;;119154:30;119149:3;119145:40;119141:1;119135:8;119132:54;119122:208;;119220:10;119214:4;119207:24;119310:4;119304;119297:18;119122:208;;;117319:2029;;;;;:::o;115653:1496::-;115951:4;115945:11;116003:10;116037:25;116034:1;116027:36;116098:8;116091:4;116088:1;116084:12;116077:30;116158:4;116154:2;116150:13;116146:2;116142:22;116135:4;116132:1;116128:12;116121:44;116200:2;116193:4;116190:1;116186:12;116179:24;116238:6;116231:4;116228:1;116224:12;116217:28;116280:4;116273;116270:1;116266:12;116259:26;116314:4;116308:11;116354:1;116347:4;116344:1;116340:12;116333:23;116373:1;116370:71;;;116436:1;116429:4;116426:1;116422:12;116419:1;116412:4;116406;116402:15;116399:1;116392:5;116381:57;116377:62;116370:71;116559:4;116556:1;116552;116546:4;116542:12;116535:4;116532:1;116528:12;116525:1;116521:2;116514:5;116509:55;116499:363;;116588:16;116585:232;;;116729:16;116723:4;116717;116702:44;116781:16;116775:4;116768:30;14:196:1;82:20;;142:42;131:54;;121:65;;111:93;;200:1;197;190:12;111:93;14:196;;;:::o;215:254::-;283:6;291;344:2;332:9;323:7;319:23;315:32;312:52;;;360:1;357;350:12;312:52;383:29;402:9;383:29;:::i;:::-;373:39;459:2;444:18;;;;431:32;;-1:-1:-1;;;215:254:1:o;656:332::-;714:6;767:2;755:9;746:7;742:23;738:32;735:52;;;783:1;780;773:12;735:52;822:9;809:23;872:66;865:5;861:78;854:5;851:89;841:117;;954:1;951;944:12;841:117;977:5;656:332;-1:-1:-1;;;656:332:1:o;1185:184::-;-1:-1:-1;;;1234:1:1;1227:88;1334:4;1331:1;1324:15;1358:4;1355:1;1348:15;1374:981;1443:6;1496:2;1484:9;1475:7;1471:23;1467:32;1464:52;;;1512:1;1509;1502:12;1464:52;1552:9;1539:23;1581:18;1622:2;1614:6;1611:14;1608:34;;;1638:1;1635;1628:12;1608:34;1676:6;1665:9;1661:22;1651:32;;1721:7;1714:4;1710:2;1706:13;1702:27;1692:55;;1743:1;1740;1733:12;1692:55;1779:2;1766:16;1801:2;1797;1794:10;1791:36;;;1807:18;;:::i;:::-;1941:2;1935:9;2003:4;1995:13;;-1:-1:-1;;1991:22:1;;;2015:2;1987:31;1983:40;1971:53;;;2039:18;;;2059:22;;;2036:46;2033:72;;;2085:18;;:::i;:::-;2125:10;2121:2;2114:22;2160:2;2152:6;2145:18;2200:7;2195:2;2190;2186;2182:11;2178:20;2175:33;2172:53;;;2221:1;2218;2211:12;2172:53;2277:2;2272;2268;2264:11;2259:2;2251:6;2247:15;2234:46;2322:1;2300:15;;;2317:2;2296:24;2289:35;;;;-1:-1:-1;2304:6:1;1374:981;-1:-1:-1;;;;;1374:981:1:o;2360:482::-;2402:3;2440:5;2434:12;2467:6;2462:3;2455:19;2492:1;2502:162;2516:6;2513:1;2510:13;2502:162;;;2578:4;2634:13;;;2630:22;;2624:29;2606:11;;;2602:20;;2595:59;2531:12;2502:162;;;2506:3;2709:1;2702:4;2693:6;2688:3;2684:16;2680:27;2673:38;2831:4;-1:-1:-1;;2756:2:1;2748:6;2744:15;2740:88;2735:3;2731:98;2727:109;2720:116;;;2360:482;;;;:::o;2847:220::-;2996:2;2985:9;2978:21;2959:4;3016:45;3057:2;3046:9;3042:18;3034:6;3016:45;:::i;3072:180::-;3131:6;3184:2;3172:9;3163:7;3159:23;3155:32;3152:52;;;3200:1;3197;3190:12;3152:52;-1:-1:-1;3223:23:1;;3072:180;-1:-1:-1;3072:180:1:o;3257:367::-;3320:8;3330:6;3384:3;3377:4;3369:6;3365:17;3361:27;3351:55;;3402:1;3399;3392:12;3351:55;-1:-1:-1;3425:20:1;;3468:18;3457:30;;3454:50;;;3500:1;3497;3490:12;3454:50;3537:4;3529:6;3525:17;3513:29;;3597:3;3590:4;3580:6;3577:1;3573:14;3565:6;3561:27;3557:38;3554:47;3551:67;;;3614:1;3611;3604:12;3551:67;3257:367;;;;;:::o;3629:773::-;3751:6;3759;3767;3775;3828:2;3816:9;3807:7;3803:23;3799:32;3796:52;;;3844:1;3841;3834:12;3796:52;3884:9;3871:23;3913:18;3954:2;3946:6;3943:14;3940:34;;;3970:1;3967;3960:12;3940:34;4009:70;4071:7;4062:6;4051:9;4047:22;4009:70;:::i;:::-;4098:8;;-1:-1:-1;3983:96:1;-1:-1:-1;4186:2:1;4171:18;;4158:32;;-1:-1:-1;4202:16:1;;;4199:36;;;4231:1;4228;4221:12;4199:36;;4270:72;4334:7;4323:8;4312:9;4308:24;4270:72;:::i;:::-;3629:773;;;;-1:-1:-1;4361:8:1;-1:-1:-1;;;;3629:773:1:o;4407:347::-;4458:8;4468:6;4522:3;4515:4;4507:6;4503:17;4499:27;4489:55;;4540:1;4537;4530:12;4489:55;-1:-1:-1;4563:20:1;;4606:18;4595:30;;4592:50;;;4638:1;4635;4628:12;4592:50;4675:4;4667:6;4663:17;4651:29;;4727:3;4720:4;4711:6;4703;4699:19;4695:30;4692:39;4689:59;;;4744:1;4741;4734:12;4759:1210;4919:6;4927;4935;4943;4951;4959;4967;4975;5028:3;5016:9;5007:7;5003:23;4999:33;4996:53;;;5045:1;5042;5035:12;4996:53;5068:29;5087:9;5068:29;:::i;:::-;5058:39;;5116:38;5150:2;5139:9;5135:18;5116:38;:::i;:::-;5106:48;;5205:2;5194:9;5190:18;5177:32;5228:18;5269:2;5261:6;5258:14;5255:34;;;5285:1;5282;5275:12;5255:34;5324:70;5386:7;5377:6;5366:9;5362:22;5324:70;:::i;:::-;5413:8;;-1:-1:-1;5298:96:1;-1:-1:-1;5501:2:1;5486:18;;5473:32;;-1:-1:-1;5517:16:1;;;5514:36;;;5546:1;5543;5536:12;5514:36;5585:72;5649:7;5638:8;5627:9;5623:24;5585:72;:::i;:::-;5676:8;;-1:-1:-1;5559:98:1;-1:-1:-1;5764:3:1;5749:19;;5736:33;;-1:-1:-1;5781:16:1;;;5778:36;;;5810:1;5807;5800:12;5778:36;;5849:60;5901:7;5890:8;5879:9;5875:24;5849:60;:::i;:::-;4759:1210;;;;-1:-1:-1;4759:1210:1;;-1:-1:-1;4759:1210:1;;;;;;5928:8;-1:-1:-1;;;4759:1210:1:o;6752:632::-;6923:2;6975:21;;;7045:13;;6948:18;;;7067:22;;;6894:4;;6923:2;7146:15;;;;7120:2;7105:18;;;6894:4;7189:169;7203:6;7200:1;7197:13;7189:169;;;7264:13;;7252:26;;7333:15;;;;7298:12;;;;7225:1;7218:9;7189:169;;;-1:-1:-1;7375:3:1;;6752:632;-1:-1:-1;;;;;;6752:632:1:o;7389:291::-;7566:2;7555:9;7548:21;7529:4;7586:45;7627:2;7616:9;7612:18;7604:6;7586:45;:::i;:::-;7578:53;;7667:6;7662:2;7651:9;7647:18;7640:34;7389:291;;;;;:::o;7685:186::-;7744:6;7797:2;7785:9;7776:7;7772:23;7768:32;7765:52;;;7813:1;7810;7803:12;7765:52;7836:29;7855:9;7836:29;:::i;8289:347::-;8354:6;8362;8415:2;8403:9;8394:7;8390:23;8386:32;8383:52;;;8431:1;8428;8421:12;8383:52;8454:29;8473:9;8454:29;:::i;:::-;8444:39;;8533:2;8522:9;8518:18;8505:32;8580:5;8573:13;8566:21;8559:5;8556:32;8546:60;;8602:1;8599;8592:12;8546:60;8625:5;8615:15;;;8289:347;;;;;:::o;8641:573::-;8745:6;8753;8761;8769;8822:2;8810:9;8801:7;8797:23;8793:32;8790:52;;;8838:1;8835;8828:12;8790:52;8878:9;8865:23;8911:18;8903:6;8900:30;8897:50;;;8943:1;8940;8933:12;8897:50;8982:70;9044:7;9035:6;9024:9;9020:22;8982:70;:::i;:::-;9071:8;;8956:96;;-1:-1:-1;9153:2:1;9138:18;;9125:32;;9204:2;9189:18;9176:32;;-1:-1:-1;8641:573:1;-1:-1:-1;;;;8641:573:1:o;10387:260::-;10455:6;10463;10516:2;10504:9;10495:7;10491:23;10487:32;10484:52;;;10532:1;10529;10522:12;10484:52;10555:29;10574:9;10555:29;:::i;:::-;10545:39;;10603:38;10637:2;10626:9;10622:18;10603:38;:::i;:::-;10593:48;;10387:260;;;;;:::o;10652:695::-;10758:6;10766;10774;10782;10790;10798;10851:3;10839:9;10830:7;10826:23;10822:33;10819:53;;;10868:1;10865;10858:12;10819:53;10891:29;10910:9;10891:29;:::i;:::-;10881:39;;10939:38;10973:2;10962:9;10958:18;10939:38;:::i;:::-;10929:48;;11024:2;11013:9;11009:18;10996:32;10986:42;;11075:2;11064:9;11060:18;11047:32;11037:42;;11130:3;11119:9;11115:19;11102:33;11158:18;11150:6;11147:30;11144:50;;;11190:1;11187;11180:12;11144:50;11229:58;11279:7;11270:6;11259:9;11255:22;11229:58;:::i;:::-;10652:695;;;;-1:-1:-1;10652:695:1;;-1:-1:-1;10652:695:1;;11306:8;;10652:695;-1:-1:-1;;;10652:695:1:o;11352:505::-;11447:6;11455;11463;11516:2;11504:9;11495:7;11491:23;11487:32;11484:52;;;11532:1;11529;11522:12;11484:52;11572:9;11559:23;11605:18;11597:6;11594:30;11591:50;;;11637:1;11634;11627:12;11591:50;11676:70;11738:7;11729:6;11718:9;11714:22;11676:70;:::i;:::-;11765:8;;11650:96;;-1:-1:-1;11847:2:1;11832:18;;;;11819:32;;11352:505;-1:-1:-1;;;;11352:505:1:o;11862:437::-;11941:1;11937:12;;;;11984;;;12005:61;;12059:4;12051:6;12047:17;12037:27;;12005:61;12112:2;12104:6;12101:14;12081:18;12078:38;12075:218;;-1:-1:-1;;;12146:1:1;12139:88;12250:4;12247:1;12240:15;12278:4;12275:1;12268:15;12075:218;;11862:437;;;:::o;12430:545::-;12532:2;12527:3;12524:11;12521:448;;;12568:1;12593:5;12589:2;12582:17;12638:4;12634:2;12624:19;12708:2;12696:10;12692:19;12689:1;12685:27;12679:4;12675:38;12744:4;12732:10;12729:20;12726:47;;;-1:-1:-1;12767:4:1;12726:47;12822:2;12817:3;12813:12;12810:1;12806:20;12800:4;12796:31;12786:41;;12877:82;12895:2;12888:5;12885:13;12877:82;;;12940:17;;;12921:1;12910:13;12877:82;;13211:1471;13337:3;13331:10;13364:18;13356:6;13353:30;13350:56;;;13386:18;;:::i;:::-;13415:97;13505:6;13465:38;13497:4;13491:11;13465:38;:::i;:::-;13459:4;13415:97;:::i;:::-;13567:4;;13631:2;13620:14;;13648:1;13643:782;;;;14469:1;14486:6;14483:89;;;-1:-1:-1;14538:19:1;;;14532:26;14483:89;-1:-1:-1;;13108:1:1;13104:11;;;13100:84;13096:89;13086:100;13192:1;13188:11;;;13083:117;14585:81;;13613:1063;;13643:782;12377:1;12370:14;;;12414:4;12401:18;;-1:-1:-1;;13679:79:1;;;13856:236;13870:7;13867:1;13864:14;13856:236;;;13959:19;;;13953:26;13938:42;;14051:27;;;;14019:1;14007:14;;;;13886:19;;13856:236;;;13860:3;14120:6;14111:7;14108:19;14105:261;;;14181:19;;;14175:26;-1:-1:-1;;14264:1:1;14260:14;;;14276:3;14256:24;14252:97;14248:102;14233:118;14218:134;;14105:261;-1:-1:-1;;;;;14412:1:1;14396:14;;;14392:22;14379:36;;-1:-1:-1;13211:1471:1:o;14687:184::-;-1:-1:-1;;;14736:1:1;14729:88;14836:4;14833:1;14826:15;14860:4;14857:1;14850:15;14876:184;-1:-1:-1;;;14925:1:1;14918:88;15025:4;15022:1;15015:15;15049:4;15046:1;15039:15;15065:125;15130:9;;;15151:10;;;15148:36;;;15164:18;;:::i;:::-;15065:125;;;;:::o;15195:195::-;15234:3;-1:-1:-1;;15258:5:1;15255:77;15252:103;;15335:18;;:::i;:::-;-1:-1:-1;15382:1:1;15371:13;;15195:195::o;15655:168::-;15728:9;;;15759;;15776:15;;;15770:22;;15756:37;15746:71;;15797:18;;:::i
Swarm Source
ipfs://1d5e3737c19518835f6d145d034f7d2173eb405acc8dc3d2a78c0c90f3711b18
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.