// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/*
:..........:.....................................................................................::.
:...............................................................................................:...
:..................................................................................................:
:...................................................................................................
:...............................................................................................::.:
:..................................................................................................:
:...................................................................................................
:.................................................................................................:.
:..................................................................................................:
:.................................................................................................::
:.................................................................................................::
:...........................................::....................................................::
:.......................................=:=#%%%##%#++=:..........................................:..
:.....................................-*+:.-%#+=:.=#%%#*-.........................................::
:.....................................+=+::+#=:#%=.:#%%%%+:........................................:
:.................................:-==##+#%%#=:=+...=%%%##=........................................:
:..............................-+*%%%%%%%%%%%#-.....=%%%%%#+....................................::::
...........................-*%#+++===-=--+%%%%%*===#%%%%%%%#.....................................:::
........................................:*%%%%%%%%%%%%%%#%%%......................................::
:.......................................=#%%%%%%%%%%%%%%%%%%...................................:::::
:.......................................#%%%#%%#%%%%%%%%%%%#.....................................:::
:................................:-....=*%%%%%%%%%%%%%%%%%%%+..................................:::::
:................................:.....=+%%%%%%%%%%%%%%#%%%%#.....................................::
:.....................................::*%%%%%%%%%%%%%%%%%%%%-...................................:::
:.....................................:.##%%%%%%%%%%%%%%%%%%%#-.................................:.::
:........::.............................##%%%%%%%%%%%%%%##%%%#-..................................:::
:......................................:+%%%%%%%%%%%%%%%#%%%%#-...............................::::::
:.......................................-%%%%%%%%%%%%%%%%##%%%*-.................................:::
:.......................................=%%%%%%%%%%%%%%%%%%%%%#=:...............................:.::
:.......................................=#%%%%%%%%%%%%%%%%%%%%%#-.................................::
.........................................-%%%%%%%%%%%%%%%%%%%%%#-..................................:
.........................................-#%%%%%%%%%%%%%%%%%%%%#=..................................:
..........................................-#%%%%%%%%%%%%%%%%%%%*:.................................::
:..........................................=##%%%%%%%%%%%%%%#%%#=..................................:
:............................................:*#%%###########%%%#=:..............................:..
:..............................................-=+%#%%%#####%##%%%*-.............................:.:
:...........................................::...:%#==+*%**=::+#*##%*-............................::
:................................................-%*.::+%-.....-++**#*#+:.........................::
.................................................=#-...+%=......-+++:+==*+:........................:
.................................................+%:...+%-.......-::+::=.:::........................
.................................................*%....=#-...........=..............................
.................................................##....=#-.......................................:::
................................................:#*....-#-......................................:..:
................................................:%=....-*-.......................................:::
................................................-#:....-*-....................................::.:::
................................................=#.....-*:.........................................:
...............................................:*=.....-+:..........................................
............................................:-*#%#+::-+**+:.........................................
.........................................:-+*+***%+#****#*#==----::.:..............................:
..........................................-:.-=::-.::=::-:.:........................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
*/
import "https://raw.githubusercontent.com/Vectorized/solady/main/src/auth/Ownable.sol";
import "https://raw.githubusercontent.com/Vectorized/solady/main/src/tokens/ERC721.sol";
//special thanks to @bantg for his ridiculous Legible Math library which inspired this whole thing
abstract contract ERCSevenTwentyOne is ERC721 {}
/*──────────── 16‑bit signed numerator | 16‑bit unsigned denominator ──────────*/
type LM is uint32;
uint32 constant _DEN_MASK = 0xFFFF;
int256 constant _LIM = 32_767;
/*─────────── custom errors ───────────*/
error NotInteger(int256 num, int256 den);
error OutOfRange(int256 value);
error Overflow();
/*─────────── helpers ───────────*/
function _split(LM _f) pure returns (int256 num, int256 den) {
uint32 raw = LM.unwrap(_f);
// high 16 bits → signed numerator
num = int256(int16(uint16(raw >> 16)));
// low 16 bits → unsigned denominator, then widen safely
den = int256(uint256(uint16(raw & _DEN_MASK)));
}
function _gcd(int256 _x, int256 _y) pure returns (int256) {
while (_y != 0) (_x, _y) = (_y, _x % _y);
return _x >= 0 ? _x : -_x;
}
function _encode(int256 _n, int256 _d) pure returns (LM) {
if (_d <= 0 || _d > _LIM || _n < -_LIM || _n > _LIM) revert Overflow();
// pack a 16-bit signed numerator and 16-bit unsigned denominator into 32 bits
// ensure shift occurs on a 32-bit value so bits are not truncated
uint32 numBits = uint32(uint16(int16(_n)));
uint32 denBits = uint32(uint16(uint256(_d)));
uint32 packed = (numBits << 16) | denBits;
return LM.wrap(packed);
}
function _reduce(int256 _n, int256 _d) pure returns (LM) {
int256 _g = _gcd(_n, _d);
return _encode(_n / _g, _d / _g);
}
/*─────────── operator overloads ───────────*/
function _plus(LM _x, LM _y) pure returns (LM) {
(int256 nx, int256 dx) = _split(_x);
(int256 ny, int256 dy) = _split(_y);
return _reduce(nx * dy + ny * dx, dx * dy);
}
function _minus(LM _x, LM _y) pure returns (LM) {
(int256 nx, int256 dx) = _split(_x);
(int256 ny, int256 dy) = _split(_y);
return _reduce(nx * dy - ny * dx, dx * dy);
}
function _times(LM _x, LM _y) pure returns (LM) {
(int256 nx, int256 dx) = _split(_x);
(int256 ny, int256 dy) = _split(_y);
return _reduce(nx * ny, dx * dy);
}
function _over(LM _x, LM _y) pure returns (LM) {
(int256 nx, int256 dx) = _split(_x);
(int256 ny, int256 dy) = _split(_y);
if (ny == 0) revert();
return _reduce(nx * dy, dx * ny);
}
/* Make the symbols work everywhere */
using {_plus as +, _minus as -, _times as *, _over as / } for LM global;
/*─────────── public helpers ───────────*/
library LegibleMath {
struct Fraction {
int256 num;
int256 den;
}
function literally(LM _f) internal pure returns (int256) {
(int256 _n, int256 _d) = _split(_f);
if (_n % _d != 0) revert NotInteger(_n, _d);
int256 val = _n / _d;
if (val < -11 || val > 11) revert OutOfRange(val);
return val;
}
function toFraction(LM _f) internal pure returns (int256 num, int256 den) {
(num, den) = _split(_f);
}
}
using LegibleMath for LM global;
/*─────────── compile‑time packed constants ──────────*/
/* (num << 16) | den */
LM constant a = LM.wrap(0xfffd0050); // -3 / 80
LM constant e = LM.wrap(0x00010001); // 1 / 1
LM constant f = LM.wrap(0x00050009); // 5 / 9
LM constant g = LM.wrap(0x0008001b); // 8 / 27
LM constant h = LM.wrap(0x0003000a); // 3 / 10
LM constant i = LM.wrap(0x00090001); // 9 / 1
LM constant l = LM.wrap(0x000b0001); // 11 / 1
LM constant n = LM.wrap(0x00010001); // 1 / 1
LM constant o = LM.wrap(0x00010001); // 1 / 1
LM constant r = LM.wrap(0x00010001); // 1 / 1
LM constant s = LM.wrap(0x00070001); // 7 / 1
LM constant t = LM.wrap(0x000a0001); // 10 / 1
LM constant u = LM.wrap(0x00240005); // 36 / 5
LM constant v = LM.wrap(0x00010001); // 1 / 1
LM constant w = LM.wrap(0x00010005); // 1 / 5
LM constant x = LM.wrap(0x00020015); // 2 / 21
LM constant z = LM.wrap(0x00000001); // 0 / 1
abstract contract LegibleKeccak {
function keccak(bytes memory input) internal pure returns (uint256) {
return uint256(keccak256(input));
}
}
contract ZegsEggs is ERCSevenTwentyOne, LegibleKeccak, Ownable {
constructor(string memory tokenZeroMetadata) {
_initializeOwner(msg.sender);
_mint(msg.sender, zero);
tokenMetadata[zero] = tokenZeroMetadata;
}
function name() public pure override returns (string memory) { return "Zeg's Eggs"; }
function symbol() public pure override returns (string memory) { return "ZEGG"; }
uint zero = uint((z * e * r * o).literally());
uint one = uint((o * n * e).literally());
uint two = uint((t * w * o).literally());
uint three = uint((t * h * r * e * e).literally());
uint four = uint((f * o * u * r).literally());
uint five = uint((f * i * v * e).literally());
uint six = uint((s * i * x).literally());
uint seven = uint((s * e * v * e * n).literally());
uint eight = uint((e * i * g * h * t).literally());
uint nine = uint((n * i * n * e).literally());
uint ten = uint((t * e * n).literally());
uint eleven = uint((e * l * e * v * e * n).literally());
uint nineteen = two + eight + nine;
uint public sixtynine = eleven * six + three;
uint public fourtwenty = three * four * five * seven;
uint twofiftysix = eight * eight * four;
uint thousand = ten * ten * ten;
uint million = thousand * thousand;
uint public MAP_SIZE = eleven * ten * ten + eleven;
uint public ENTRY_FEE = eleven * million * million * thousand;
uint public HUNT_DURATION_BLOCKS = eleven * ten * ten + eleven;
uint public EGG_COUNT = eleven;
address ZERO_ADDRESS;
enum GamePhase {
PreHunt, // zero
HuntActive, // one
HuntEnded // two
}
struct Player {
address addr;
uint x;
uint y;
}
struct Egg {
uint x;
uint y;
bool claimed;
bool revealed;
address winner;
}
Player[] public players;
mapping(address => uint) public entriesByAddress;
mapping(uint => Egg) public eggs;
mapping(uint => string) internal tokenMetadata;
mapping(uint => mapping(uint => bool)) coordsTaken;
uint public gameStartBlock;
bool public gameStarted;
bool public gameFinalized;
GamePhase public gamePhase = GamePhase.PreHunt;
event PlayerGuessed(address indexed player, uint x, uint y);
event EggRevealed(uint eggIndex, uint eggX, uint eggY);
modifier onlyDuringGame() {
require(gameStarted, "Game not started");
require(block.number <= gameStartBlock + HUNT_DURATION_BLOCKS, "Game ended");
_;
}
modifier onlyAfterGame() {
require(gameStarted, "Game not started");
require(block.number > gameStartBlock + HUNT_DURATION_BLOCKS, "Game still active");
_;
}
function startGame() external onlyOwner {
require(!gameStarted, "Game already started");
gameStartBlock = block.number;
gameStarted = true;
gamePhase = GamePhase.HuntActive;
}
function setZeroAddress(address _zeroAddress) external onlyOwner {
ZERO_ADDRESS = _zeroAddress;
}
function getBlocksUntilGameOver() external view returns (uint) {
if (block.number >= gameStartBlock + HUNT_DURATION_BLOCKS) return zero;
return (gameStartBlock + HUNT_DURATION_BLOCKS) - block.number;
}
function whereIsTheEgg(uint xCoord, uint yCoord) external payable onlyDuringGame {
require(entriesByAddress[msg.sender] < three, "Maximum guesses reached");
require((msg.value == ENTRY_FEE), "Incorrect entry fee");
require(players.length < eleven * ten * ten + eleven, "Max players reached");
require((xCoord <= MAP_SIZE && yCoord <= MAP_SIZE), "Invalid coordinates");
require(!coordsTaken[xCoord][yCoord], "That spot has already been claimed.");
coordsTaken[xCoord][yCoord] = true;
players.push(Player(msg.sender, xCoord, yCoord));
entriesByAddress[msg.sender]++;
emit PlayerGuessed(msg.sender, xCoord, yCoord);
}
function getAllPlayerGuesses()
external
view
returns (address[] memory addrs, uint[] memory xs, uint[] memory ys)
{
uint len = players.length;
addrs = new address[](len);
xs = new uint[](len);
ys = new uint[](len);
for (uint index = zero; index < len; index++) {
Player memory player = players[index];
addrs[index] = player.addr;
xs[index] = player.x;
ys[index] = player.y;
}
}
function revealEgg(uint eggId) external {
require(gameStarted, "Game not started");
require(eggId >= one && eggId <= eleven, "Invalid egg ID");
require(!eggs[eggId].revealed, "Already revealed");
uint revealBase = gameStartBlock + HUNT_DURATION_BLOCKS;
uint xBlock = revealBase + eggId + one; // offset for X
uint yBlock = revealBase + eggId + two; // offset for Y
require(block.number > yBlock, "Too early to reveal");
require(block.number <= yBlock + twofiftysix, "Reveal window expired");
uint eggX = uint(keccak(abi.encodePacked(blockhash(xBlock), "EGG", eggId, address(this)))) % MAP_SIZE;
uint eggY = uint(keccak(abi.encodePacked(blockhash(yBlock), "EGG", eggId, address(this)))) % MAP_SIZE;
eggs[eggId] = Egg({x: eggX, y: eggY, revealed: true, claimed: false, winner: address(ZERO_ADDRESS)});
emit EggRevealed(eggId, eggX, eggY);
if (gamePhase == GamePhase.HuntActive) {
gamePhase = GamePhase.HuntEnded;
}
if (!gameFinalized) {
gameFinalized = true;
}
}
function getEggCoords(uint eggId) external view returns (uint xCoord, uint yCoord) {
Egg memory egg = eggs[eggId];
require(gameFinalized, "Game not finalized");
require(egg.revealed, "Egg not revealed yet");
require(eggId >= one && eggId <= eleven, "Invalid egg ID");
return (egg.x, egg.y);
}
function getWinner(uint eggId) public view returns (address) {
Egg memory egg = eggs[eggId];
require(gameFinalized, "Game not finalized");
require(egg.revealed, "Egg mot revealed yet");
require(eggId >= one && eggId <= eleven, "Invalid egg ID");
uint closestIndex = zero;
uint minDistance = type(uint).max;
for (uint index = zero; index < players.length; index++) {
Player memory player = players[index];
uint dx = player.x > egg.x ? player.x - egg.x : egg.x - player.x;
uint dy = player.y > egg.y ? player.y - egg.y : egg.y - player.y;
uint dist = dx * dx + dy * dy;
if (dist < minDistance) {
minDistance = dist;
closestIndex = index;
}
}
return players[closestIndex].addr;
}
function ownerClaimEgg(uint eggId) public onlyOwner {
Egg memory egg = eggs[eggId];
require(gameFinalized, "Game not finalized");
require(!egg.claimed, "Egg already claimed");
require(egg.revealed, "Egg not yet revealed");
address winner = getWinner(eggId);
egg.winner = winner;
egg.claimed = true;
eggs[eggId] = egg;
_mint(winner, eggId);
}
function ownerClaimAll() external onlyOwner {
for (uint eggId = one; eggId <= eleven; eggId++) {
if (!eggs[eggId].claimed) {
ownerClaimEgg(eggId);
}
}
}
function getGuessCount() external view returns (uint) {
return players.length;
}
function isGameActive() external view returns (bool) {
return gameStarted && block.number <= gameStartBlock + HUNT_DURATION_BLOCKS && !gameFinalized;
}
mapping(address => bool) public canRead;
address[] public readers;
function iCanRead() external {
require(entriesByAddress[msg.sender] > zero, "Only hunters can sign.");
require(!canRead[msg.sender], "Already signed.");
canRead[msg.sender] = true;
readers.push(msg.sender);
}
function getReaders() external view returns (address[] memory) {
return readers;
}
function updateMetadata(uint tokenId, string memory metadata) external onlyOwner {
require(tokenId <= eleven, "Nonexistent token");
tokenMetadata[tokenId] = metadata;
}
function tokenURI(uint tokenId) public view override returns (string memory) {
require(_exists(tokenId), "Nonexistent token");
require(tokenId <= eleven, "Nonexistent token");
return tokenMetadata[tokenId];
}
function withdraw() external onlyOwner {
require(address(this).balance > zero, "No ETH to withdraw");
(bool success,) = payable(owner()).call{value: address(this).balance}("");
require(success, "Withdraw failed");
}
receive() external payable {}
}
{
"compilationTarget": {
"contracts/zegseggs.sol": "ZegsEggs"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"string","name":"tokenZeroMetadata","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountBalanceOverflow","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[{"internalType":"int256","name":"num","type":"int256"},{"internalType":"int256","name":"den","type":"int256"}],"name":"NotInteger","type":"error"},{"inputs":[],"name":"NotOwnerNorApproved","type":"error"},{"inputs":[{"internalType":"int256","name":"value","type":"int256"}],"name":"OutOfRange","type":"error"},{"inputs":[],"name":"Overflow","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TokenDoesNotExist","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"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":false,"internalType":"uint256","name":"eggIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"eggX","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"eggY","type":"uint256"}],"name":"EggRevealed","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":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"x","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"y","type":"uint256"}],"name":"PlayerGuessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"EGG_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ENTRY_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HUNT_DURATION_BLOCKS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAP_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"canRead","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"eggs","outputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"bool","name":"revealed","type":"bool"},{"internalType":"address","name":"winner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"entriesByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fourtwenty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gameFinalized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gamePhase","outputs":[{"internalType":"enum ZegsEggs.GamePhase","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gameStartBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gameStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllPlayerGuesses","outputs":[{"internalType":"address[]","name":"addrs","type":"address[]"},{"internalType":"uint256[]","name":"xs","type":"uint256[]"},{"internalType":"uint256[]","name":"ys","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlocksUntilGameOver","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"eggId","type":"uint256"}],"name":"getEggCoords","outputs":[{"internalType":"uint256","name":"xCoord","type":"uint256"},{"internalType":"uint256","name":"yCoord","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuessCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReaders","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"eggId","type":"uint256"}],"name":"getWinner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"iCanRead","outputs":[],"stateMutability":"nonpayable","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":"isGameActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerClaimAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"eggId","type":"uint256"}],"name":"ownerClaimEgg","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"players","outputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"readers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"eggId","type":"uint256"}],"name":"revealEgg","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"isApproved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_zeroAddress","type":"address"}],"name":"setZeroAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sixtynine","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startGame","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":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"metadata","type":"string"}],"name":"updateMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"xCoord","type":"uint256"},{"internalType":"uint256","name":"yCoord","type":"uint256"}],"name":"whereIsTheEgg","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]