tokenboost-solidity-erc20token
Version:
Solidity contracts for TokenBoost (ERC20Token)
592 lines • 2.05 MB
JSON
{
"contractName": "strings",
"abi": [],
"bytecode": "0x604c602c600b82828239805160001a60731460008114601c57601e565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600080fd00a165627a7a723058208e2e7c9eb0c75d096a877f09c256b4568c2e448e5c4aacd9716a4d4756a206f00029",
"deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fd00a165627a7a723058208e2e7c9eb0c75d096a877f09c256b4568c2e448e5c4aacd9716a4d4756a206f00029",
"sourceMap": "2003:23357:9:-;;132:2:-1;166:7;155:9;146:7;137:37;252:7;246:14;243:1;238:23;232:4;229:33;270:1;265:20;;;;222:63;;265:20;274:9;222:63;;298:9;295:1;288:20;328:4;319:7;311:22;352:7;343;336:24",
"deployedSourceMap": "2003:23357:9:-;;;;;;;;",
"source": "/*\n * @title String & slice utility library for Solidity contracts.\n * @author Nick Johnson <arachnid@notdot.net>\n *\n * @dev Functionality in this library is largely implemented using an\n * abstraction called a 'slice'. A slice represents a part of a string -\n * anything from the entire string to a single character, or even no\n * characters at all (a 0-length slice). Since a slice only has to specify\n * an offset and a length, copying and manipulating slices is a lot less\n * expensive than copying and manipulating the strings they reference.\n *\n * To further reduce gas costs, most functions on slice that need to return\n * a slice modify the original one instead of allocating a new one; for\n * instance, `s.split(\".\")` will return the text up to the first '.',\n * modifying s to only contain the remainder of the string after the '.'.\n * In situations where you do not want to modify the original slice, you\n * can make a copy first with `.copy()`, for example:\n * `s.copy().split(\".\")`. Try and avoid using this idiom in loops; since\n * Solidity has no memory management, it will result in allocating many\n * short-lived slices that are later discarded.\n *\n * Functions that return two slices come in two versions: a non-allocating\n * version that takes the second slice as an argument, modifying it in\n * place, and an allocating version that allocates and returns the second\n * slice; see `nextRune` for example.\n *\n * Functions that have to copy string data will return strings rather than\n * slices; these can be cast back to slices for further processing if\n * required.\n *\n * For convenience, some functions are provided with non-modifying\n * variants that create a new slice and return both; for instance,\n * `s.splitNew('.')` leaves s unmodified, and returns two values\n * corresponding to the left and right parts of the string.\n */\n\npragma solidity ^0.4.14;\n\nlibrary strings {\n struct slice {\n uint _len;\n uint _ptr;\n }\n\n function memcpy(uint dest, uint src, uint len) private pure {\n // Copy word-length chunks while possible\n for(; len >= 32; len -= 32) {\n assembly {\n mstore(dest, mload(src))\n }\n dest += 32;\n src += 32;\n }\n\n // Copy remaining bytes\n uint mask = 256 ** (32 - len) - 1;\n assembly {\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n /*\n * @dev Returns a slice containing the entire string.\n * @param self The string to make a slice from.\n * @return A newly allocated slice containing the entire string.\n */\n function toSlice(string memory self) internal pure returns (slice memory) {\n uint ptr;\n assembly {\n ptr := add(self, 0x20)\n }\n return slice(bytes(self).length, ptr);\n }\n\n /*\n * @dev Returns the length of a null-terminated bytes32 string.\n * @param self The value to find the length of.\n * @return The length of the string, from 0 to 32.\n */\n function len(bytes32 self) internal pure returns (uint) {\n uint ret;\n if (self == 0)\n return 0;\n if (self & 0xffffffffffffffffffffffffffffffff == 0) {\n ret += 16;\n self = bytes32(uint(self) / 0x100000000000000000000000000000000);\n }\n if (self & 0xffffffffffffffff == 0) {\n ret += 8;\n self = bytes32(uint(self) / 0x10000000000000000);\n }\n if (self & 0xffffffff == 0) {\n ret += 4;\n self = bytes32(uint(self) / 0x100000000);\n }\n if (self & 0xffff == 0) {\n ret += 2;\n self = bytes32(uint(self) / 0x10000);\n }\n if (self & 0xff == 0) {\n ret += 1;\n }\n return 32 - ret;\n }\n\n /*\n * @dev Returns a slice containing the entire bytes32, interpreted as a\n * null-terminated utf-8 string.\n * @param self The bytes32 value to convert to a slice.\n * @return A new slice containing the value of the input argument up to the\n * first null.\n */\n function toSliceB32(bytes32 self) internal pure returns (slice memory ret) {\n // Allocate space for `self` in memory, copy it there, and point ret at it\n assembly {\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, 0x20))\n mstore(ptr, self)\n mstore(add(ret, 0x20), ptr)\n }\n ret._len = len(self);\n }\n\n /*\n * @dev Returns a new slice containing the same data as the current slice.\n * @param self The slice to copy.\n * @return A new slice containing the same data as `self`.\n */\n function copy(slice memory self) internal pure returns (slice memory) {\n return slice(self._len, self._ptr);\n }\n\n /*\n * @dev Copies a slice to a new string.\n * @param self The slice to copy.\n * @return A newly allocated string containing the slice's text.\n */\n function toString(slice memory self) internal pure returns (string memory) {\n string memory ret = new string(self._len);\n uint retptr;\n assembly { retptr := add(ret, 32) }\n\n memcpy(retptr, self._ptr, self._len);\n return ret;\n }\n\n /*\n * @dev Returns the length in runes of the slice. Note that this operation\n * takes time proportional to the length of the slice; avoid using it\n * in loops, and call `slice.empty()` if you only need to know whether\n * the slice is empty or not.\n * @param self The slice to operate on.\n * @return The length of the slice in runes.\n */\n function len(slice memory self) internal pure returns (uint l) {\n // Starting at ptr-31 means the LSB will be the byte we care about\n uint ptr = self._ptr - 31;\n uint end = ptr + self._len;\n for (l = 0; ptr < end; l++) {\n uint8 b;\n assembly { b := and(mload(ptr), 0xFF) }\n if (b < 0x80) {\n ptr += 1;\n } else if(b < 0xE0) {\n ptr += 2;\n } else if(b < 0xF0) {\n ptr += 3;\n } else if(b < 0xF8) {\n ptr += 4;\n } else if(b < 0xFC) {\n ptr += 5;\n } else {\n ptr += 6;\n }\n }\n }\n\n /*\n * @dev Returns true if the slice is empty (has a length of 0).\n * @param self The slice to operate on.\n * @return True if the slice is empty, False otherwise.\n */\n function empty(slice memory self) internal pure returns (bool) {\n return self._len == 0;\n }\n\n /*\n * @dev Returns a positive number if `other` comes lexicographically after\n * `self`, a negative number if it comes before, or zero if the\n * contents of the two slices are equal. Comparison is done per-rune,\n * on unicode codepoints.\n * @param self The first slice to compare.\n * @param other The second slice to compare.\n * @return The result of the comparison.\n */\n function compare(slice memory self, slice memory other) internal pure returns (int) {\n uint shortest = self._len;\n if (other._len < self._len)\n shortest = other._len;\n\n uint selfptr = self._ptr;\n uint otherptr = other._ptr;\n for (uint idx = 0; idx < shortest; idx += 32) {\n uint a;\n uint b;\n assembly {\n a := mload(selfptr)\n b := mload(otherptr)\n }\n if (a != b) {\n // Mask out irrelevant bytes and check again\n uint256 mask = uint256(-1); // 0xffff...\n if(shortest < 32) {\n mask = ~(2 ** (8 * (32 - shortest + idx)) - 1);\n }\n uint256 diff = (a & mask) - (b & mask);\n if (diff != 0)\n return int(diff);\n }\n selfptr += 32;\n otherptr += 32;\n }\n return int(self._len) - int(other._len);\n }\n\n /*\n * @dev Returns true if the two slices contain the same text.\n * @param self The first slice to compare.\n * @param self The second slice to compare.\n * @return True if the slices are equal, false otherwise.\n */\n function equals(slice memory self, slice memory other) internal pure returns (bool) {\n return compare(self, other) == 0;\n }\n\n /*\n * @dev Extracts the first rune in the slice into `rune`, advancing the\n * slice to point to the next rune and returning `self`.\n * @param self The slice to operate on.\n * @param rune The slice that will contain the first rune.\n * @return `rune`.\n */\n function nextRune(slice memory self, slice memory rune) internal pure returns (slice memory) {\n rune._ptr = self._ptr;\n\n if (self._len == 0) {\n rune._len = 0;\n return rune;\n }\n\n uint l;\n uint b;\n // Load the first byte of the rune into the LSBs of b\n assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) }\n if (b < 0x80) {\n l = 1;\n } else if(b < 0xE0) {\n l = 2;\n } else if(b < 0xF0) {\n l = 3;\n } else {\n l = 4;\n }\n\n // Check for truncated codepoints\n if (l > self._len) {\n rune._len = self._len;\n self._ptr += self._len;\n self._len = 0;\n return rune;\n }\n\n self._ptr += l;\n self._len -= l;\n rune._len = l;\n return rune;\n }\n\n /*\n * @dev Returns the first rune in the slice, advancing the slice to point\n * to the next rune.\n * @param self The slice to operate on.\n * @return A slice containing only the first rune from `self`.\n */\n function nextRune(slice memory self) internal pure returns (slice memory ret) {\n nextRune(self, ret);\n }\n\n /*\n * @dev Returns the number of the first codepoint in the slice.\n * @param self The slice to operate on.\n * @return The number of the first codepoint in the slice.\n */\n function ord(slice memory self) internal pure returns (uint ret) {\n if (self._len == 0) {\n return 0;\n }\n\n uint word;\n uint length;\n uint divisor = 2 ** 248;\n\n // Load the rune into the MSBs of b\n assembly { word:= mload(mload(add(self, 32))) }\n uint b = word / divisor;\n if (b < 0x80) {\n ret = b;\n length = 1;\n } else if(b < 0xE0) {\n ret = b & 0x1F;\n length = 2;\n } else if(b < 0xF0) {\n ret = b & 0x0F;\n length = 3;\n } else {\n ret = b & 0x07;\n length = 4;\n }\n\n // Check for truncated codepoints\n if (length > self._len) {\n return 0;\n }\n\n for (uint i = 1; i < length; i++) {\n divisor = divisor / 256;\n b = (word / divisor) & 0xFF;\n if (b & 0xC0 != 0x80) {\n // Invalid UTF-8 sequence\n return 0;\n }\n ret = (ret * 64) | (b & 0x3F);\n }\n\n return ret;\n }\n\n /*\n * @dev Returns the keccak-256 hash of the slice.\n * @param self The slice to hash.\n * @return The hash of the slice.\n */\n function keccak(slice memory self) internal pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(mload(add(self, 32)), mload(self))\n }\n }\n\n /*\n * @dev Returns true if `self` starts with `needle`.\n * @param self The slice to operate on.\n * @param needle The slice to search for.\n * @return True if the slice starts with the provided text, false otherwise.\n */\n function startsWith(slice memory self, slice memory needle) internal pure returns (bool) {\n if (self._len < needle._len) {\n return false;\n }\n\n if (self._ptr == needle._ptr) {\n return true;\n }\n\n bool equal;\n assembly {\n let length := mload(needle)\n let selfptr := mload(add(self, 0x20))\n let needleptr := mload(add(needle, 0x20))\n equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))\n }\n return equal;\n }\n\n /*\n * @dev If `self` starts with `needle`, `needle` is removed from the\n * beginning of `self`. Otherwise, `self` is unmodified.\n * @param self The slice to operate on.\n * @param needle The slice to search for.\n * @return `self`\n */\n function beyond(slice memory self, slice memory needle) internal pure returns (slice memory) {\n if (self._len < needle._len) {\n return self;\n }\n\n bool equal = true;\n if (self._ptr != needle._ptr) {\n assembly {\n let length := mload(needle)\n let selfptr := mload(add(self, 0x20))\n let needleptr := mload(add(needle, 0x20))\n equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))\n }\n }\n\n if (equal) {\n self._len -= needle._len;\n self._ptr += needle._len;\n }\n\n return self;\n }\n\n /*\n * @dev Returns true if the slice ends with `needle`.\n * @param self The slice to operate on.\n * @param needle The slice to search for.\n * @return True if the slice starts with the provided text, false otherwise.\n */\n function endsWith(slice memory self, slice memory needle) internal pure returns (bool) {\n if (self._len < needle._len) {\n return false;\n }\n\n uint selfptr = self._ptr + self._len - needle._len;\n\n if (selfptr == needle._ptr) {\n return true;\n }\n\n bool equal;\n assembly {\n let length := mload(needle)\n let needleptr := mload(add(needle, 0x20))\n equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))\n }\n\n return equal;\n }\n\n /*\n * @dev If `self` ends with `needle`, `needle` is removed from the\n * end of `self`. Otherwise, `self` is unmodified.\n * @param self The slice to operate on.\n * @param needle The slice to search for.\n * @return `self`\n */\n function until(slice memory self, slice memory needle) internal pure returns (slice memory) {\n if (self._len < needle._len) {\n return self;\n }\n\n uint selfptr = self._ptr + self._len - needle._len;\n bool equal = true;\n if (selfptr != needle._ptr) {\n assembly {\n let length := mload(needle)\n let needleptr := mload(add(needle, 0x20))\n equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))\n }\n }\n\n if (equal) {\n self._len -= needle._len;\n }\n\n return self;\n }\n\n // Returns the memory address of the first byte of the first occurrence of\n // `needle` in `self`, or the first byte after `self` if not found.\n function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) {\n uint ptr = selfptr;\n uint idx;\n\n if (needlelen <= selflen) {\n if (needlelen <= 32) {\n bytes32 mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));\n\n bytes32 needledata;\n assembly { needledata := and(mload(needleptr), mask) }\n\n uint end = selfptr + selflen - needlelen;\n bytes32 ptrdata;\n assembly { ptrdata := and(mload(ptr), mask) }\n\n while (ptrdata != needledata) {\n if (ptr >= end)\n return selfptr + selflen;\n ptr++;\n assembly { ptrdata := and(mload(ptr), mask) }\n }\n return ptr;\n } else {\n // For long needles, use hashing\n bytes32 hash;\n assembly { hash := keccak256(needleptr, needlelen) }\n\n for (idx = 0; idx <= selflen - needlelen; idx++) {\n bytes32 testHash;\n assembly { testHash := keccak256(ptr, needlelen) }\n if (hash == testHash)\n return ptr;\n ptr += 1;\n }\n }\n }\n return selfptr + selflen;\n }\n\n // Returns the memory address of the first byte after the last occurrence of\n // `needle` in `self`, or the address of `self` if not found.\n function rfindPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) {\n uint ptr;\n\n if (needlelen <= selflen) {\n if (needlelen <= 32) {\n bytes32 mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));\n\n bytes32 needledata;\n assembly { needledata := and(mload(needleptr), mask) }\n\n ptr = selfptr + selflen - needlelen;\n bytes32 ptrdata;\n assembly { ptrdata := and(mload(ptr), mask) }\n\n while (ptrdata != needledata) {\n if (ptr <= selfptr)\n return selfptr;\n ptr--;\n assembly { ptrdata := and(mload(ptr), mask) }\n }\n return ptr + needlelen;\n } else {\n // For long needles, use hashing\n bytes32 hash;\n assembly { hash := keccak256(needleptr, needlelen) }\n ptr = selfptr + (selflen - needlelen);\n while (ptr >= selfptr) {\n bytes32 testHash;\n assembly { testHash := keccak256(ptr, needlelen) }\n if (hash == testHash)\n return ptr + needlelen;\n ptr -= 1;\n }\n }\n }\n return selfptr;\n }\n\n /*\n * @dev Modifies `self` to contain everything from the first occurrence of\n * `needle` to the end of the slice. `self` is set to the empty slice\n * if `needle` is not found.\n * @param self The slice to search and modify.\n * @param needle The text to search for.\n * @return `self`.\n */\n function find(slice memory self, slice memory needle) internal pure returns (slice memory) {\n uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);\n self._len -= ptr - self._ptr;\n self._ptr = ptr;\n return self;\n }\n\n /*\n * @dev Modifies `self` to contain the part of the string from the start of\n * `self` to the end of the first occurrence of `needle`. If `needle`\n * is not found, `self` is set to the empty slice.\n * @param self The slice to search and modify.\n * @param needle The text to search for.\n * @return `self`.\n */\n function rfind(slice memory self, slice memory needle) internal pure returns (slice memory) {\n uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);\n self._len = ptr - self._ptr;\n return self;\n }\n\n /*\n * @dev Splits the slice, setting `self` to everything after the first\n * occurrence of `needle`, and `token` to everything before it. If\n * `needle` does not occur in `self`, `self` is set to the empty slice,\n * and `token` is set to the entirety of `self`.\n * @param self The slice to split.\n * @param needle The text to search for in `self`.\n * @param token An output parameter to which the first token is written.\n * @return `token`.\n */\n function split(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) {\n uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);\n token._ptr = self._ptr;\n token._len = ptr - self._ptr;\n if (ptr == self._ptr + self._len) {\n // Not found\n self._len = 0;\n } else {\n self._len -= token._len + needle._len;\n self._ptr = ptr + needle._len;\n }\n return token;\n }\n\n /*\n * @dev Splits the slice, setting `self` to everything after the first\n * occurrence of `needle`, and returning everything before it. If\n * `needle` does not occur in `self`, `self` is set to the empty slice,\n * and the entirety of `self` is returned.\n * @param self The slice to split.\n * @param needle The text to search for in `self`.\n * @return The part of `self` up to the first occurrence of `delim`.\n */\n function split(slice memory self, slice memory needle) internal pure returns (slice memory token) {\n split(self, needle, token);\n }\n\n /*\n * @dev Splits the slice, setting `self` to everything before the last\n * occurrence of `needle`, and `token` to everything after it. If\n * `needle` does not occur in `self`, `self` is set to the empty slice,\n * and `token` is set to the entirety of `self`.\n * @param self The slice to split.\n * @param needle The text to search for in `self`.\n * @param token An output parameter to which the first token is written.\n * @return `token`.\n */\n function rsplit(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) {\n uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);\n token._ptr = ptr;\n token._len = self._len - (ptr - self._ptr);\n if (ptr == self._ptr) {\n // Not found\n self._len = 0;\n } else {\n self._len -= token._len + needle._len;\n }\n return token;\n }\n\n /*\n * @dev Splits the slice, setting `self` to everything before the last\n * occurrence of `needle`, and returning everything after it. If\n * `needle` does not occur in `self`, `self` is set to the empty slice,\n * and the entirety of `self` is returned.\n * @param self The slice to split.\n * @param needle The text to search for in `self`.\n * @return The part of `self` after the last occurrence of `delim`.\n */\n function rsplit(slice memory self, slice memory needle) internal pure returns (slice memory token) {\n rsplit(self, needle, token);\n }\n\n /*\n * @dev Counts the number of nonoverlapping occurrences of `needle` in `self`.\n * @param self The slice to search.\n * @param needle The text to search for in `self`.\n * @return The number of occurrences of `needle` found in `self`.\n */\n function count(slice memory self, slice memory needle) internal pure returns (uint cnt) {\n uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len;\n while (ptr <= self._ptr + self._len) {\n cnt++;\n ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr) + needle._len;\n }\n }\n\n /*\n * @dev Returns True if `self` contains `needle`.\n * @param self The slice to search.\n * @param needle The text to search for in `self`.\n * @return True if `needle` is found in `self`, false otherwise.\n */\n function contains(slice memory self, slice memory needle) internal pure returns (bool) {\n return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr;\n }\n\n /*\n * @dev Returns a newly allocated string containing the concatenation of\n * `self` and `other`.\n * @param self The first slice to concatenate.\n * @param other The second slice to concatenate.\n * @return The concatenation of the two strings.\n */\n function concat(slice memory self, slice memory other) internal pure returns (string memory) {\n string memory ret = new string(self._len + other._len);\n uint retptr;\n assembly { retptr := add(ret, 32) }\n memcpy(retptr, self._ptr, self._len);\n memcpy(retptr + self._len, other._ptr, other._len);\n return ret;\n }\n\n /*\n * @dev Joins an array of slices, using `self` as a delimiter, returning a\n * newly allocated string.\n * @param self The delimiter to use.\n * @param parts A list of slices to join.\n * @return A newly allocated string containing all the slices in `parts`,\n * joined with `self`.\n */\n function join(slice memory self, slice[] memory parts) internal pure returns (string memory) {\n if (parts.length == 0)\n return \"\";\n\n uint length = self._len * (parts.length - 1);\n for(uint i = 0; i < parts.length; i++)\n length += parts[i]._len;\n\n string memory ret = new string(length);\n uint retptr;\n assembly { retptr := add(ret, 32) }\n\n for(i = 0; i < parts.length; i++) {\n memcpy(retptr, parts[i]._ptr, parts[i]._len);\n retptr += parts[i]._len;\n if (i < parts.length - 1) {\n memcpy(retptr, self._ptr, self._len);\n retptr += self._len;\n }\n }\n\n return ret;\n }\n}",
"sourcePath": "tokenboost-solidity/contracts/utils/strings.sol",
"ast": {
"absolutePath": "tokenboost-solidity/contracts/utils/strings.sol",
"exportedSymbols": {
"strings": [
2700
]
},
"id": 2701,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1007,
"literals": [
"solidity",
"^",
"0.4",
".14"
],
"nodeType": "PragmaDirective",
"src": "1977:24:9"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "library",
"documentation": null,
"fullyImplemented": true,
"id": 2700,
"linearizedBaseContracts": [
2700
],
"name": "strings",
"nodeType": "ContractDefinition",
"nodes": [
{
"canonicalName": "strings.slice",
"id": 1012,
"members": [
{
"constant": false,
"id": 1009,
"name": "_len",
"nodeType": "VariableDeclaration",
"scope": 1012,
"src": "2048:9:9",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 1008,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "2048:4:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1011,
"name": "_ptr",
"nodeType": "VariableDeclaration",
"scope": 1012,
"src": "2067:9:9",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 1010,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "2067:4:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"name": "slice",
"nodeType": "StructDefinition",
"scope": 2700,
"src": "2025:58:9",
"visibility": "public"
},
{
"body": {
"id": 1051,
"nodeType": "Block",
"src": "2149:488:9",
"statements": [
{
"body": {
"id": 1037,
"nodeType": "Block",
"src": "2237:136:9",
"statements": [
{
"externalReferences": [
{
"dest": {
"declaration": 1014,
"isOffset": false,
"isSlot": false,
"src": "2285:4:9",
"valueSize": 1
}
},
{
"src": {
"declaration": 1016,
"isOffset": false,
"isSlot": false,
"src": "2297:3:9",
"valueSize": 1
}
}
],
"id": 1028,
"nodeType": "InlineAssembly",
"operations": "{\n mstore(dest, mload(src))\n}",
"src": "2251:82:9"
},
{
"expression": {
"argumentTypes": null,
"id": 1031,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1029,
"name": "dest",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1014,
"src": "2329:4:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "Assignment",
"operator": "+=",
"rightHandSide": {
"argumentTypes": null,
"hexValue": "3332",
"id": 1030,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "2337:2:9",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_32_by_1",
"typeString": "int_const 32"
},
"value": "32"
},
"src": "2329:10:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 1032,
"nodeType": "ExpressionStatement",
"src": "2329:10:9"
},
{
"expression": {
"argumentTypes": null,
"id": 1035,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1033,
"name": "src",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1016,
"src": "2353:3:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "Assignment",
"operator": "+=",
"rightHandSide": {
"argumentTypes": null,
"hexValue": "3332",
"id": 1034,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "2360:2:9",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_32_by_1",
"typeString": "int_const 32"
},
"value": "32"
},
"src": "2353:9:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 1036,
"nodeType": "ExpressionStatement",
"src": "2353:9:9"
}
]
},
"condition": {
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 1023,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 1021,
"name": "len",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1018,
"src": "2215:3:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": ">=",
"rightExpression": {
"argumentTypes": null,
"hexValue": "3332",
"id": 1022,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "2222:2:9",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_32_by_1",
"typeString": "int_const 32"
},
"value": "32"
},
"src": "2215:9:9",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"id": 1038,
"initializationExpression": null,
"loopExpression": {
"expression": {
"argumentTypes": null,
"id": 1026,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1024,
"name": "len",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1018,
"src": "2226:3:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "Assignment",
"operator": "-=",
"rightHandSide": {
"argumentTypes": null,
"hexValue": "3332",
"id": 1025,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "2233:2:9",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_32_by_1",
"typeString": "int_const 32"
},
"value": "32"
},
"src": "2226:9:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 1027,
"nodeType": "ExpressionStatement",
"src": "2226:9:9"
},
"nodeType": "ForStatement",
"src": "2209:164:9"
},
{
"assignments": [
1040
],
"declarations": [
{
"constant": false,
"id": 1040,
"name": "mask",
"nodeType": "VariableDeclaration",
"scope": 1052,
"src": "2415:9:9",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 1039,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "2415:4:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"id": 1049,
"initialValue": {
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 1048,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 1046,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"hexValue": "323536",
"id": 1041,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "2427:3:9",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_256_by_1",
"typeString": "int_const 256"
},
"value": "256"
},
"nodeType": "BinaryOperation",
"operator": "**",
"rightExpression": {
"argumentTypes": null,
"components": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 1044,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"hexValue": "3332",
"id": 1042,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "2435:2:9",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_32_by_1",
"typeString": "int_const 32"
},
"value": "32"
},
"nodeType": "BinaryOperation",
"operator": "-",
"rightExpression": {
"argumentTypes": null,
"id": 1043,
"name": "len",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1018,
"src": "2440:3:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"src": "2435:8:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
}
],
"id": 1045,
"isConstant": false,
"isInlineArray": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"nodeType": "TupleExpression",
"src": "2434:10:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"src": "2427:17:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": "-",
"rightExpression": {
"argumentTypes": null,
"hexValue": "31",
"id": 1047,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "2447:1:9",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_1_by_1",
"typeString": "int_const 1"
},
"value": "1"
},
"src": "2427:21:9",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "VariableDeclarationStatement",
"src": "2415:33:9"
},
{
"externalReferences": [
{
"src": {
"declaration": 1016,
"isOffset": false,
"isSlot": false,
"src": "2506:3:9",
"valueSize": 1
}
},
{
"mask": {
"declaration": 1040,
"isOffset": false,
"isSlot": false,
"src": "2516:4:9",
"valueSize": 1
}
},
{
"dest": {
"declaration": 1014,
"isOffset": false,
"isSlot": false,
"src": "2561:4:9",
"valueSize": 1
}
},
{
"mask": {
"declaration": 1040,
"isOffset": false,
"isSlot": false,
"src": "2568:4:9",
"valueSize": 1
}
},
{
"dest": {
"declaration": 1014,
"isOffset": false,
"isSlot": false,
"src": "2593:4:9",
"valueSize": 1
}
}
],
"id": 1050,
"nodeType": "InlineAssembly",
"operations": "{\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n}",
"src": "2458:179:9"
}
]
},
"documentation": null,
"id": 1052,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": true,
"m