Description:
Decentralized Finance (DeFi) protocol contract providing Mintable, Non-Fungible, Liquidity, Factory functionality.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{"Eggs.sol":{"content":"/****************************************************\r
* *\r
* EGGS Token (EGGS) *\r
* ERC-20721 Standard *\r
* *\r
* • Total Supply: 256 tokens only *\r
* • Initial Liquidity: 1 ETH + 128 EGGS *\r
* • Mint Price: 0.1 ETH from contract *\r
* • Available on Uniswap \u0026 OpenSea *\r
* *\r
* Official Links: *\r
* - Website: https://eggs.wtf *\r
* - X (Twitter): https://x.com/eggs20721 *\r
* - Telegram: https://t.me/eggs20721 *\r
* *\r
****************************************************/\r
\r
\r
// SPDX-License-Identifier: MIT\r
pragma solidity ^0.8.19;\r
\r
import "./Metadata.sol";\r
\r
\r
\r
interface Receiver {\r
function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) external returns (bytes4);\r
}\r
\r
interface Router {\r
function WETH() external pure returns (address);\r
function factory() external pure returns (address);\r
function addLiquidityETH(address, uint256, uint256, uint256, address, uint256) external payable returns (uint256, uint256, uint256);\r
}\r
\r
interface Factory {\r
function createPair(address, address) external returns (address);\r
}\r
\r
\r
contract Eggs {\r
\r
uint256 constant private UINT_MAX = type(uint256).max;\r
uint256 constant private TOTAL_SUPPLY = 256;\r
uint256 constant private LIQUIDITY_TOKENS = 128;\r
Router constant private ROUTER = Router(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);\r
\r
uint256 constant private M1 = 0x5555555555555555555555555555555555555555555555555555555555555555;\r
uint256 constant private M2 = 0x3333333333333333333333333333333333333333333333333333333333333333;\r
uint256 constant private M4 = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f;\r
uint256 constant private H01 = 0x0101010101010101010101010101010101010101010101010101010101010101;\r
bytes32 constant private TRANSFER_TOPIC = keccak256(bytes("Transfer(address,address,uint256)"));\r
bytes32 constant private APPROVAL_TOPIC = keccak256(bytes("Approval(address,address,uint256)"));\r
\r
uint256 constant public MINT_COST = 0.1 ether;\r
\r
uint8 constant public decimals = 0;\r
\r
struct User {\r
bytes32 mask;\r
mapping(address =\u003e uint256) allowance;\r
mapping(address =\u003e bool) approved;\r
}\r
\r
struct Info {\r
bytes32 salt;\r
address pair;\r
address owner;\r
Metadata metadata;\r
mapping(address =\u003e User) users;\r
mapping(uint256 =\u003e address) approved;\r
address[] holders;\r
}\r
Info private info;\r
\r
mapping(bytes4 =\u003e bool) public supportsInterface;\r
\r
\r
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\r
event ERC20Transfer(bytes32 indexed topic0, address indexed from, address indexed to, uint256 tokens) anonymous;\r
event Approval(address indexed owner, address indexed spender, uint256 indexed tokenId);\r
event ERC20Approval(bytes32 indexed topic0, address indexed owner, address indexed spender, uint256 tokens) anonymous;\r
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\r
\r
\r
modifier _onlyOwner() {\r
require(msg.sender == owner());\r
_;\r
}\r
\r
\r
constructor() payable {\r
require(msg.value \u003e 0);\r
info.owner = 0xee112A6CaAFf9d16D12433F5C952ce871Ca95418;\r
info.metadata = new Metadata();\r
supportsInterface[0x01ffc9a7] = true; // ERC-165\r
supportsInterface[0x80ac58cd] = true; // ERC-721\r
supportsInterface[0x5b5e139f] = true; // Metadata\r
info.salt = keccak256(abi.encodePacked("Salt:", blockhash(block.number - 1)));\r
}\r
\r
function setOwner(address _owner) external _onlyOwner {\r
info.owner = _owner;\r
}\r
\r
function setMetadata(Metadata _metadata) external _onlyOwner {\r
info.metadata = _metadata;\r
}\r
\r
\r
function initialize() external {\r
require(pair() == address(0x0));\r
address _this = address(this);\r
address _weth = ROUTER.WETH();\r
info.users[_this].mask = bytes32(UINT_MAX);\r
info.holders.push(_this);\r
emit ERC20Transfer(TRANSFER_TOPIC, address(0x0), _this, TOTAL_SUPPLY);\r
for (uint256 i = 0; i \u003c TOTAL_SUPPLY; i++) {\r
emit Transfer(address(0x0), _this, TOTAL_SUPPLY + i + 1);\r
}\r
_approveERC20(_this, address(ROUTER), LIQUIDITY_TOKENS);\r
info.pair = Factory(ROUTER.factory()).createPair(_weth, _this);\r
ROUTER.addLiquidityETH{value:_this.balance}(_this, LIQUIDITY_TOKENS, 0, 0, owner(), block.timestamp);\r
_transferERC20(_this, 0xee112A6CaAFf9d16D12433F5C952ce871Ca95418, 10); // marketing + giveaways\r
_transferERC20(_this, owner(), 10); // developer tokens\r
}\r
\r
function mint(uint256 _tokens) external payable {\r
address _this = address(this);\r
uint256 _available = balanceOf(_this);\r
require(_tokens \u003c= _available);\r
uint256 _cost = _tokens * MINT_COST;\r
require(msg.value \u003e= _cost);\r
_transferERC20(_this, msg.sender, _tokens);\r
payable(owner()).transfer(_cost);\r
if (msg.value \u003e _cost) {\r
payable(msg.sender).transfer(msg.value - _cost);\r
}\r
}\r
\r
function approve(address _spender, uint256 _tokens) external returns (bool) {\r
if (_tokens \u003e TOTAL_SUPPLY \u0026\u0026 _tokens \u003c= 2 * TOTAL_SUPPLY) {\r
_approveNFT(_spender, _tokens);\r
} else {\r
_approveERC20(msg.sender, _spender, _tokens);\r
}\r
return true;\r
}\r
\r
function setApprovalForAll(address _operator, bool _approved) external {\r
info.users[msg.sender].approved[_operator] = _approved;\r
emit ApprovalForAll(msg.sender, _operator, _approved);\r
}\r
\r
function transfer(address _to, uint256 _tokens) external returns (bool) {\r
_transferERC20(msg.sender, _to, _tokens);\r
return true;\r
}\r
\r
function transferFrom(address _from, address _to, uint256 _tokens) external returns (bool) {\r
if (_tokens \u003e TOTAL_SUPPLY \u0026\u0026 _tokens \u003c= 2 * TOTAL_SUPPLY) {\r
_transferNFT(_from, _to, _tokens);\r
} else {\r
uint256 _allowance = allowance(_from, msg.sender);\r
require(_allowance \u003e= _tokens);\r
if (_allowance != UINT_MAX) {\r
info.users[_from].allowance[msg.sender] -= _tokens;\r
}\r
_transferERC20(_from, _to, _tokens);\r
}\r
return true;\r
}\r
\r
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external {\r
safeTransferFrom(_from, _to, _tokenId, "");\r
}\r
\r
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory _data) public {\r
_transferNFT(_from, _to, _tokenId);\r
uint32 _size;\r
assembly {\r
_size := extcodesize(_to)\r
}\r
if (_size \u003e 0) {\r
require(Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data) == 0x150b7a02);\r
}\r
}\r
\r
function bulkTransfer(address _to, uint256[] memory _tokenIds) external {\r
_transferNFTs(_to, _tokenIds);\r
}\r
\r
\r
function owner() public view returns (address) {\r
return info.owner;\r
}\r
\r
function pair() public view returns (address) {\r
return info.pair;\r
}\r
\r
function holders() public view returns (address[] memory) {\r
return info.holders;\r
}\r
\r
function salt() external view returns (bytes32) {\r
return info.salt;\r
}\r
\r
function metadata() external view returns (address) {\r
return address(info.metadata);\r
}\r
\r
function name() external view returns (string memory) {\r
return info.metadata.name();\r
}\r
\r
function symbol() external view returns (string memory) {\r
return info.metadata.symbol();\r
}\r
\r
function tokenURI(uint256 _tokenId) public view returns (string memory) {\r
return info.metadata.tokenURI(_tokenId);\r
}\r
\r
function totalSupply() public pure returns (uint256) {\r
return TOTAL_SUPPLY;\r
}\r
\r
function maskOf(address _user) public view returns (bytes32) {\r
return info.users[_user].mask;\r
}\r
\r
function balanceOf(address _user) public view returns (uint256) {\r
return _popcount(maskOf(_user));\r
}\r
\r
function allowance(address _user, address _spender) public view returns (uint256) {\r
return info.users[_user].allowance[_spender];\r
}\r
\r
function ownerOf(uint256 _tokenId) public view returns (address) {\r
unchecked {\r
require(_tokenId \u003e TOTAL_SUPPLY \u0026\u0026 _tokenId \u003c= 2 * TOTAL_SUPPLY);\r
bytes32 _mask = bytes32(1 \u003c\u003c (_tokenId - TOTAL_SUPPLY - 1));\r
address[] memory _holders = holders();\r
for (uint256 i = 0; i \u003c _holders.length; i++) {\r
if (maskOf(_holders[i]) \u0026 _mask == _mask) {\r
return _holders[i];\r
}\r
}\r
return address(0x0);\r
}\r
}\r
\r
function getApproved(uint256 _tokenId) public view returns (address) {\r
require(_tokenId \u003e TOTAL_SUPPLY \u0026\u0026 _tokenId \u003c= 2 * TOTAL_SUPPLY);\r
return info.approved[_tokenId];\r
}\r
\r
function isApprovedForAll(address _owner, address _operator) public view returns (bool) {\r
return info.users[_owner].approved[_operator];\r
}\r
\r
function getToken(uint256 _tokenId) public view returns (address tokenOwner, address approved, string memory uri) {\r
return (ownerOf(_tokenId), getApproved(_tokenId), tokenURI(_tokenId));\r
}\r
\r
function getTokens(uint256[] memory _tokenIds) external view returns (address[] memory owners, address[] memory approveds, string[] memory uris) {\r
uint256 _length = _tokenIds.length;\r
owners = new address[](_length);\r
approveds = new address[](_length);\r
uris = new string[](_length);\r
for (uint256 i = 0; i \u003c _length; i++) {\r
(owners[i], approveds[i], uris[i]) = getToken(_tokenIds[i]);\r
}\r
}\r
\r
\r
function _approveERC20(address _owner, address _spender, uint256 _tokens) internal {\r
info.users[_owner].allowance[_spender] = _tokens;\r
emit ERC20Approval(APPROVAL_TOPIC, _owner, _spender, _tokens);\r
}\r
\r
function _approveNFT(address _spender, uint256 _tokenId) internal {\r
bytes32 _mask = bytes32(1 \u003c\u003c (_tokenId - TOTAL_SUPPLY - 1));\r
require(maskOf(msg.sender) \u0026 _mask == _mask);\r
info.approved[_tokenId] = _spender;\r
emit Approval(msg.sender, _spender, _tokenId);\r
}\r
\r
function _transferERC20(address _from, address _to, uint256 _tokens) internal {\r
unchecked {\r
bytes32 _mask;\r
uint256 _pos = 0;\r
uint256 _count = 0;\r
uint256 _n = uint256(maskOf(_from));\r
uint256[] memory _tokenIds = new uint256[](_tokens);\r
while (_n \u003e 0 \u0026\u0026 _count \u003c _tokens) {\r
if (_n \u0026 1 == 1) {\r
_mask |= bytes32(1 \u003c\u003c _pos);\r
_tokenIds[_count++] = TOTAL_SUPPLY + _pos + 1;\r
}\r
_pos++;\r
_n \u003e\u003e= 1;\r
}\r
require(_count == _tokens);\r
require(maskOf(_from) \u0026 _mask == _mask);\r
_transfer(_from, _to, _mask, _tokenIds);\r
}\r
}\r
\r
function _transferNFT(address _from, address _to, uint256 _tokenId) internal {\r
unchecked {\r
require(_tokenId \u003e TOTAL_SUPPLY \u0026\u0026 _tokenId \u003c= 2 * TOTAL_SUPPLY);\r
bytes32 _mask = bytes32(1 \u003c\u003c (_tokenId - TOTAL_SUPPLY - 1));\r
require(maskOf(_from) \u0026 _mask == _mask);\r
require(msg.sender == _from || msg.sender == getApproved(_tokenId) || isApprovedForAll(_from, msg.sender));\r
uint256[] memory _tokenIds = new uint256[](1);\r
_tokenIds[0] = _tokenId;\r
_transfer(_from, _to, _mask, _tokenIds);\r
}\r
}\r
\r
function _transferNFTs(address _to, uint256[] memory _tokenIds) internal {\r
unchecked {\r
bytes32 _mask;\r
for (uint256 i = 0; i \u003c _tokenIds.length; i++) {\r
_mask |= bytes32(1 \u003c\u003c (_tokenIds[i] - TOTAL_SUPPLY - 1));\r
}\r
require(_popcount(_mask) == _tokenIds.length);\r
require(maskOf(msg.sender) \u0026 _mask == _mask);\r
_transfer(msg.sender, _to, _mask, _tokenIds);\r
}\r
}\r
\r
function _transfer(address _from, address _to, bytes32 _mask, uint256[] memory _tokenIds) internal {\r
unchecked {\r
require(_tokenIds.length \u003e 0);\r
for (uint256 i = 0; i \u003c _tokenIds.length; i++) {\r
if (getApproved(_tokenIds[i]) != address(0x0)) {\r
info.approved[_tokenIds[i]] = address(0x0);\r
emit Approval(address(0x0), address(0x0), _tokenIds[i]);\r
}\r
emit Transfer(_from, _to, _tokenIds[i]);\r
}\r
info.users[_from].mask ^= _mask;\r
bool _from0 = maskOf(_from) == 0x0;\r
bool _to0 = maskOf(_to) == 0x0;\r
info.users[_to].mask |= _mask;\r
if (_from0) {\r
uint256 _index;\r
address[] memory _holders = holders();\r
for (uint256 i = 0; i \u003c _holders.length; i++) {\r
if (_holders[i] == _from) {\r
_index = i;\r
break;\r
}\r
}\r
if (_to0) {\r
info.holders[_index] = _to;\r
} else {\r
info.holders[_index] = _holders[_holders.length - 1];\r
info.holders.pop();\r
}\r
} else if (_to0) {\r
info.holders.push(_to);\r
}\r
require(maskOf(_from) \u0026 maskOf(_to) == 0x0);\r
emit ERC20Transfer(TRANSFER_TOPIC, _from, _to, _tokenIds.length);\r
}\r
}\r
\r
\r
function _popcount(bytes32 _b) internal pure returns (uint256) {\r
uint256 _n = uint256(_b);\r
if (_n == UINT_MAX) {\r
return 256;\r
}\r
unchecked {\r
_n -= (_n \u003e\u003e 1) \u0026 M1;\r
_n = (_n \u0026 M2) + ((_n \u003e\u003e 2) \u0026 M2);\r
_n = (_n + (_n \u003e\u003e 4)) \u0026 M4;\r
_n = (_n * H01) \u003e\u003e 248;\r
}\r
return _n;\r
}\r
}\r
\r
\r
contract Deploy {\r
Eggs immutable public eggs;\r
constructor() payable {\r
eggs = new Eggs{value:msg.value}();\r
eggs.initialize();\r
}\r
}"},"Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\r
pragma solidity ^0.8.19;\r
\r
interface CM {\r
function salt() external view returns (bytes32);\r
}\r
\r
contract Metadata {\r
\r
string public name = "Eggs";\r
string public symbol = "EGGS";\r
\r
string constant private TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\r
bytes3 constant private BG_COLOR = 0xd1d3dc;\r
uint256 constant private PADDING = 2;\r
\r
struct Size {\r
uint248 size;\r
uint8 chance;\r
}\r
Size[] private sizes;\r
\r
struct Color {\r
bytes3 primaryColor;\r
bytes3 outlineColor;\r
uint8 chance;\r
string name;\r
}\r
Color[] private colors;\r
\r
CM immutable public eggs;\r
\r
\r
constructor() {\r
eggs = CM(msg.sender);\r
\r
// sizes\r
sizes.push(Size(14, 120));\r
sizes.push(Size(16, 80));\r
sizes.push(Size(18, 50));\r
sizes.push(Size(20, 20));\r
sizes.push(Size(22, 10));\r
sizes.push(Size(24, 5));\r
\r
// colors\r
colors.push(Color(0x179629, 0x15491f, 100, "Slimy Green"));\r
colors.push(Color(0xc9a91c, 0x5f5120, 75, "Pacific Blue"));\r
colors.push(Color(0x009fff, 0x144d79, 55, "Orange Peel"));\r
colors.push(Color(0x3bb5cf, 0x235763, 35, "Old Gold"));\r
colors.push(Color(0x908070, 0x463f38, 25, "Slate Gray"));\r
colors.push(Color(0xac8fe6, 0x53466d, 15, "Charm Pink"));\r
colors.push(Color(0x2b2ca6, 0x191d52, 10, "Metallic Red"));\r
colors.push(Color(0xa95178, 0x522b3d, 5, "Royal Purple"));\r
}\r
\r
function tokenURI(uint256 _tokenId) external view returns (string memory) {\r
unchecked {\r
( , uint256 _size, uint256 _colorIndex) = _getTokenInfo(_tokenId);\r
string memory _json = string(abi.encodePacked(\u0027{"name":"EGG #\u0027, _uint2str(_tokenId), \u0027","description":"Experimental hybrid ERC-20 \u0026 ERC-721","external_url":"https://eggs.wtf/#/token/\u0027, _uint2str(_tokenId), \u0027",\u0027));\r
_json = string(abi.encodePacked(_json, \u0027"image":"\u0027, svgURI(_tokenId), \u0027","attributes":[\u0027));\r
_json = string(abi.encodePacked(_json, \u0027{"trait_type":"Size","value":\u0027, _uint2str(_size - 2 * PADDING), \u0027},\u0027));\r
_json = string(abi.encodePacked(_json, \u0027{"trait_type":"Color","value":"\u0027, colors[_colorIndex].name, \u0027"}\u0027));\r
_json = string(abi.encodePacked(_json, \u0027]}\u0027));\r
return string(abi.encodePacked(\u0027data:application/json;base64,\u0027, _encode(bytes(_json))));\r
}\r
}\r
\r
function svgURI(uint256 _tokenId) public view returns (string memory) {\r
return string(abi.encodePacked(\u0027data:image/svg+xml;base64,\u0027, _encode(bytes(getSVG(_tokenId)))));\r
}\r
\r
function bmpURI(uint256 _tokenId) public view returns (string memory) {\r
return string(abi.encodePacked(\u0027data:image/bmp;base64,\u0027, _encode(getBMP(_tokenId))));\r
}\r
\r
function getSVG(uint256 _tokenId) public view returns (string memory) {\r
return string(abi.encodePacked(\u0027\u003csvg xmlns="http://www.w3.org/2000/svg" version="1.1" preserveAspectRatio="xMidYMid meet" viewBox="0 0 512 512" width="100%" height="100%"\u003e\u003cdefs\u003e\u003cstyle type="text/css"\u003esvg{image-rendering:optimizeSpeed;image-rendering:-moz-crisp-edges;image-rendering:-o-crisp-edges;image-rendering:-webkit-optimize-contrast;image-rendering:pixelated;image-rendering:optimize-contrast;-ms-interpolation-mode:nearest-neighbor;background-color:\u0027, _col2str(BG_COLOR), \u0027;background-image:url(\u0027, bmpURI(_tokenId), \u0027);background-repeat:no-repeat;background-size:contain;background-position:50% 50%;}\u003c/style\u003e\u003c/defs\u003e\u003c/svg\u003e\u0027));\r
}\r
\r
function getBMP(uint256 _tokenId) public view returns (bytes memory) {\r
(bytes32 _seed, uint256 _size, uint256 _colorIndex) = _getTokenInfo(_tokenId);\r
return _getBMP(_makePalette(colors[_colorIndex].primaryColor, colors[_colorIndex].outlineColor), _convertToColors(_addOutline(_expandAndReflect(_step(_step(_getInitialState(_seed, _size)))))), _size);\r
}\r
\r
\r
function _getTokenInfo(uint256 _tokenId) internal view returns (bytes32 seed, uint256 size, uint256 colorIndex) {\r
unchecked {\r
seed = keccak256(abi.encodePacked("Seed:", _tokenId, eggs.salt()));\r
size = _sampleSize(seed);\r
colorIndex = _sampleColor(seed);\r
}\r
}\r
\r
function _sampleSize(bytes32 _seed) internal view returns (uint256 size) {\r
unchecked {\r
uint256 _total = 0;\r
for (uint256 i = 0; i \u003c sizes.length; i++) {\r
_total += sizes[i].chance;\r
}\r
uint256 _target = uint256(keccak256(abi.encodePacked("Size:", _seed))) % _total;\r
_total = 0;\r
for (uint256 i = 0; i \u003c sizes.length; i++) {\r
_total += sizes[i].chance;\r
if (_target \u003c _total) {\r
return sizes[i].size;\r
}\r
}\r
}\r
}\r
\r
function _sampleColor(bytes32 _seed) internal view returns (uint256 colorIndex) {\r
unchecked {\r
uint256 _total = 0;\r
for (uint256 i = 0; i \u003c colors.length; i++) {\r
_total += colors[i].chance;\r
}\r
uint256 _target = uint256(keccak256(abi.encodePacked("Color:", _seed))) % _total;\r
_total = 0;\r
for (uint256 i = 0; i \u003c colors.length; i++) {\r
_total += colors[i].chance;\r
if (_target \u003c _total) {\r
return i;\r
}\r
}\r
}\r
}\r
\r
function _getInitialState(bytes32 _seed, uint256 _size) internal pure returns (uint8[][] memory state) {\r
unchecked {\r
uint256 _rollingSeed = uint256(keccak256(abi.encodePacked("State:", _seed)));\r
state = new uint8[][](_size - 2 * PADDING - 2);\r
for (uint256 y = 0; y \u003c state.length; y++) {\r
state[y] = new uint8[](_size / 2 - PADDING - 1);\r
for (uint256 x = 0; x \u003c state[y].length; x++) {\r
state[y][x] = uint8(_rollingSeed % 2);\r
if (_rollingSeed \u003c type(uint16).max) {\r
_rollingSeed = uint256(keccak256(abi.encodePacked("Roll:", _seed, _rollingSeed)));\r
} else {\r
_rollingSeed /= 2;\r
}\r
}\r
}\r
}\r
}\r
\r
function _getNeighborhood(uint8[][] memory _state) internal pure returns (uint8[][] memory neighborhood) {\r
unchecked {\r
neighborhood = new uint8[][](_state.length);\r
for (uint256 y = 0; y \u003c _state.length; y++) {\r
neighborhood[y] = new uint8[](_state[y].length);\r
for (uint256 x = 0; x \u003c _state[y].length; x++) {\r
uint8 _count = 0;\r
if (y \u003e 0) {\r
_count += _state[y - 1][x];\r
}\r
if (y \u003c _state.length - 1) {\r
_count += _state[y + 1][x];\r
}\r
if (x \u003e 0) {\r
_count += _state[y][x - 1];\r
}\r
if (x \u003c _state[y].length - 1) {\r
_count += _state[y][x + 1];\r
}\r
neighborhood[y][x] = _count;\r
}\r
}\r
}\r
}\r
\r
function _step(uint8[][] memory _state) internal pure returns (uint8[][] memory newState) {\r
unchecked {\r
uint8[][] memory _neighborhood = _getNeighborhood(_state);\r
newState = new uint8[][](_state.length);\r
for (uint256 y = 0; y \u003c _state.length; y++) {\r
newState[y] = new uint8[](_state[y].length);\r
for (uint256 x = 0; x \u003c _state[y].length; x++) {\r
newState[y][x] = ((_state[y][x] == 0 \u0026\u0026 _neighborhood[y][x] \u003c= 1) || (_state[y][x] == 1 \u0026\u0026 (_neighborhood[y][x] == 2 || _neighborhood[y][x] == 3))) ? 1 : 0;\r
}\r
}\r
}\r
}\r
\r
function _expandAndReflect(uint8[][] memory _state) internal pure returns (uint8[][] memory newState) {\r
unchecked {\r
newState = new uint8[][](_state.length + 2 * PADDING + 2);\r
for (uint256 y = 0; y \u003c newState.length; y++) {\r
newState[y] = new uint8[](_state.length + 2 * PADDING + 2);\r
for (uint256 x = 0; x \u003c newState[y].length; x++) {\r
if (y \u003e PADDING \u0026\u0026 y \u003c= _state.length + PADDING \u0026\u0026 x \u003e PADDING \u0026\u0026 x \u003c= _state.length + PADDING) {\r
newState[y][x] = _state[y - PADDING - 1][x \u003e _state[y - PADDING - 1].length + PADDING ? _state.length + PADDING - x : x - PADDING - 1];\r
} else {\r
newState[y][x] = 0;\r
}\r
}\r
}\r
}\r
}\r
\r
function _addOutline(uint8[][] memory _state) internal pure returns (uint8[][] memory newState) {\r
unchecked {\r
uint8[][] memory _neighborhood = _getNeighborhood(_state);\r
newState = new uint8[][](_state.length);\r
for (uint256 y = 0; y \u003c _state.length; y++) {\r
newState[y] = new uint8[](_state[y].length);\r
for (uint256 x = 0; x \u003c _state[y].length; x++) {\r
newState[y][x] = _state[y][x] == 0 \u0026\u0026 _neighborhood[y][x] \u003e 0 ? 2 : _state[y][x];\r
}\r
}\r
}\r
}\r
\r
function _convertToColors(uint8[][] memory _state) internal pure returns (bytes memory cols) {\r
unchecked {\r
uint256 _scanline = _state[0].length;\r
if (_scanline % 4 != 0) {\r
_scanline += 4 - (_scanline % 4);\r
}\r
cols = new bytes(_state.length * _scanline);\r
for (uint256 y = 0; y \u003c _state.length; y++) {\r
for (uint256 x = 0; x \u003c _state[y].length; x++) {\r
cols[(_state.length - y - 1) * _scanline + x] = bytes1(_state[y][x]);\r
}\r
}\r
}\r
}\r
\r
function _makePalette(bytes3 _primaryColor, bytes3 _outlineColor) internal pure returns (bytes memory) {\r
unchecked {\r
return abi.encodePacked(BG_COLOR, bytes1(0), _primaryColor, bytes1(0), _outlineColor, bytes1(0));\r
}\r
}\r
\r
function _getBMP(bytes memory _palette, bytes memory _colors, uint256 _size) internal pure returns (bytes memory) {\r
unchecked {\r
uint32 _bufSize = 14 + 40 + uint32(_palette.length);\r
bytes memory _buf = new bytes(_bufSize - _palette.length);\r
_buf[0] = 0x42;\r
_buf[1] = 0x4d;\r
uint32 _tmp = _bufSize + uint32(_colors.length);\r
uint32 b;\r
for (uint i = 2; i \u003c 6; i++) {\r
assembly {\r
b := and(_tmp, 0xff)\r
_tmp := shr(8, _tmp)\r
}\r
_buf[i] = bytes1(uint8(b));\r
}\r
_tmp = _bufSize;\r
for (uint i = 10; i \u003c 14; i++) {\r
assembly {\r
b := and(_tmp, 0xff)\r
_tmp := shr(8, _tmp)\r
}\r
_buf[i] = bytes1(uint8(b));\r
}\r
_buf[14] = 0x28;\r
_tmp = uint32(_size);\r
for (uint i = 18; i \u003c 22; i++) {\r
assembly {\r
b := and(_tmp, 0xff)\r
_tmp := shr(8, _tmp)\r
}\r
_buf[i] = bytes1(uint8(b));\r
_buf[i + 4] = bytes1(uint8(b));\r
}\r
_buf[26] = 0x01;\r
_buf[28] = 0x08;\r
_tmp = uint32(_colors.length);\r
for (uint i = 34; i \u003c 38; i++) {\r
assembly {\r
b := and(_tmp, 0xff)\r
_tmp := shr(8, _tmp)\r
}\r
_buf[i] = bytes1(uint8(b));\r
}\r
_tmp = uint32(_palette.length / 4);\r
for (uint i = 46; i \u003c 50; i++) {\r
assembly {\r
b := and(_tmp, 0xff)\r
_tmp := shr(8, _tmp)\r
}\r
_buf[i] = bytes1(uint8(b));\r
_buf[i + 4] = bytes1(uint8(b));\r
}\r
return abi.encodePacked(_buf, _palette, _colors);\r
}\r
}\r
\r
function _uint2str(uint256 _value) internal pure returns (string memory) {\r
unchecked {\r
uint256 _digits = 1;\r
uint256 _n = _value;\r
while (_n \u003e 9) {\r
_n /= 10;\r
_digits++;\r
}\r
bytes memory _out = new bytes(_digits);\r
for (uint256 i = 0; i \u003c _out.length; i++) {\r
uint256 _dec = (_value / (10**(_out.length - i - 1))) % 10;\r
_out[i] = bytes1(uint8(_dec) + 48);\r
}\r
return string(_out);\r
}\r
}\r
\r
function _col2str(bytes3 _col) internal pure returns (string memory str) {\r
unchecked {\r
str = "#";\r
for (uint256 i = 0; i \u003c 6; i++) {\r
uint256 _hex = (uint24(_col) \u003e\u003e (4 * (i + 1 - 2 * (i % 2)))) % 16;\r
bytes memory _char = new bytes(1);\r
_char[0] = bytes1(uint8(_hex) + (_hex \u003e 9 ? 87 : 48));\r
str = string(abi.encodePacked(str, string(_char)));\r
}\r
}\r
}\r
\r
function _encode(bytes memory _data) internal pure returns (string memory result) {\r
unchecked {\r
if (_data.length == 0) return \u0027\u0027;\r
string memory _table = TABLE;\r
uint256 _encodedLen = 4 * ((_data.length + 2) / 3);\r
result = new string(_encodedLen + 32);\r
\r
assembly {\r
mstore(result, _encodedLen)\r
let tablePtr := add(_table, 1)\r
let dataPtr := _data\r
let endPtr := add(dataPtr, mload(_data))\r
let resultPtr := add(result, 32)\r
\r
for {} lt(dataPtr, endPtr) {}\r
{\r
dataPtr := add(dataPtr, 3)\r
let input := mload(dataPtr)\r
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F)))))\r
resultPtr := add(resultPtr, 1)\r
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F)))))\r
resultPtr := add(resultPtr, 1)\r
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F)))))\r
resultPtr := add(resultPtr, 1)\r
mstore(resultPtr, shl(248, mload(add(tablePtr, and( input, 0x3F)))))\r
resultPtr := add(resultPtr, 1)\r
}\r
switch mod(mload(_data), 3)\r
case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }\r
case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }\r
}\r
return result;\r
}\r
}\r
}"}}
Submitted on: 2025-10-31 14:05:58
Comments
Log in to comment.
No comments yet.