UtopiaLandCity

0xb93ee2b0996c3a0577ec4e3a776d81d4e4fcbed2

Verification
Verified
v0.8.26+commit.8a97fa7a
Type
Contract
12,753 bytes
ABI entries
88
40 read · 14 write
License
none

Contract information

Address
0xb93ee2b0996c3a0577ec4e3a776d81d4e4fcbed2
Chain
Robinhood Chain (4663)
Compiler
v0.8.26+commit.8a97fa7a
Optimization
Enabled
Creation tx
0xc9c086aff3…0ba60a46af

Token

Name
utopia land
Symbol
PLOT
Decimals
Holders
130

Read contract (40)

BPS()uint256
MAX_BATCH()uint256
MAX_RATE()uint256
MAX_REWARD_DURATION()uint256
MIN_REWARD_DURATION()uint256
PLOTS()uint256
SIDE()uint256
WAD()uint256
YEAR()uint256
apyBpsOf(uint256)uint256
availablePayout(uint256)uint256
balanceOf(address)uint256
claimable(uint256)uint256
claimableMany(uint256[])uint256[], uint256[]
eligibilityRegistry()address
getApproved(uint256)address
isApprovedForAll(address, address)bool
isEligible(address)bool
lastClaim(uint256)uint64
maxRewardForSale(uint256)uint256
name()string
owner()address
ownerOf(uint256)address
ownershipBitmap()uint256[4]
pendingOwner()address
plotsOf(address)uint256[4]
plotsPacked()uint256[1024]
priceOf(uint256)uint256
reserveAvailable(uint256)uint256
reserveCommitment(uint256)uint256
reserveRequiredForAllOpenPlots()uint256[5]
rewardEnd()uint64
supportsInterface(bytes4)bool
symbol()string
tokenIndexOf(uint256)uint256
tokenURI(uint256)string
tokens(uint256)address
tokensPerEthWad(uint256)uint256
totalCommittedByToken(uint256)uint256
totalOwedByToken(uint256)uint256

Events (10)

ApprovalApprovalForAllBoughtClaimedEthWithdrawnMigratedOwnershipTransferStartedOwnershipTransferredSurplusStockWithdrawnTransfer

ABI

[
  {
    "inputs": [
      {
        "internalType": "contract IERC20[5]",
        "name": "tokens_",
        "type": "address[5]"
      },
      {
        "internalType": "uint256[5]",
        "name": "rates_",
        "type": "uint256[5]"
      },
      {
        "internalType": "contract IUtopiaEligibility",
        "name": "eligibilityRegistry_",
        "type": "address"
      },
      {
        "internalType": "uint64",
        "name": "rewardEnd_",
        "type": "uint64"
      },
      {
        "internalType": "address",
        "name": "initialOwner",
        "type": "address"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "inputs": [],
    "name": "BatchTooLarge",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "sender",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      },
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      }
    ],
    "name": "ERC721IncorrectOwner",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "operator",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "ERC721InsufficientApproval",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "approver",
        "type": "address"
      }
    ],
    "name": "ERC721InvalidApprover",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "operator",
        "type": "address"
      }
    ],
    "name": "ERC721InvalidOperator",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      }
    ],
    "name": "ERC721InvalidOwner",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "receiver",
        "type": "address"
      }
    ],
    "name": "ERC721InvalidReceiver",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "sender",
        "type": "address"
      }
    ],
    "name": "ERC721InvalidSender",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "ERC721NonexistentToken",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "EthTransferFailed",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "tokenIndex",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "required",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "available",
        "type": "uint256"
      }
    ],
    "name": "InsufficientReserve",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "InsufficientSurplus",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "InvalidConfig",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "InvalidPlot",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "NotEligible",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "NotMinted",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "NotPlotOwner",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      }
    ],
    "name": "OwnableInvalidOwner",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "account",
        "type": "address"
      }
    ],
    "name": "OwnableUnauthorizedAccount",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "ProgramEnded",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "ReentrancyGuardReentrantCall",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "token",
        "type": "address"
      }
    ],
    "name": "SafeERC20FailedOperation",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "WrongPayment",
    "type": "error"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "approved",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "tokenId",
        "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": "approved",
        "type": "bool"
      }
    ],
    "name": "ApprovalForAll",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "buyer",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "price",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "rewardReserved",
        "type": "uint256"
      }
    ],
    "name": "Bought",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "address",
        "name": "token",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "paid",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "stillOwed",
        "type": "uint256"
      }
    ],
    "name": "Claimed",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "EthWithdrawn",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "to",
        "type": "address"
      }
    ],
    "name": "Migrated",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "previousOwner",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "newOwner",
        "type": "address"
      }
    ],
    "name": "OwnershipTransferStarted",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "previousOwner",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "newOwner",
        "type": "address"
      }
    ],
    "name": "OwnershipTransferred",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "token",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "SurplusStockWithdrawn",
    "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": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "Transfer",
    "type": "event"
  },
  {
    "inputs": [],
    "name": "BPS",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "MAX_BATCH",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "MAX_RATE",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "MAX_REWARD_DURATION",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "MIN_REWARD_DURATION",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "PLOTS",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "SIDE",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "WAD",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "YEAR",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "acceptOwnership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "approve",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      }
    ],
    "name": "apyBpsOf",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "pure",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      }
    ],
    "name": "availablePayout",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      }
    ],
    "name": "balanceOf",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      }
    ],
    "name": "buy",
    "outputs": [],
    "stateMutability": "payable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      }
    ],
    "name": "claim",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256[]",
        "name": "ids",
        "type": "uint256[]"
      }
    ],
    "name": "claimMany",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      }
    ],
    "name": "claimable",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256[]",
        "name": "ids",
        "type": "uint256[]"
      }
    ],
    "name": "claimableMany",
    "outputs": [
      {
        "internalType": "uint256[]",
        "name": "claimableAmounts",
        "type": "uint256[]"
      },
      {
        "internalType": "uint256[]",
        "name": "availableAmounts",
        "type": "uint256[]"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "eligibilityRegistry",
    "outputs": [
      {
        "internalType": "contract IUtopiaEligibility",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "getApproved",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "operator",
        "type": "address"
      }
    ],
    "name": "isApprovedForAll",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "account",
        "type": "address"
      }
    ],
    "name": "isEligible",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "lastClaim",
    "outputs": [
      {
        "internalType": "uint64",
        "name": "",
        "type": "uint64"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      }
    ],
    "name": "maxRewardForSale",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "contract ILandOwners",
        "name": "oldLand",
        "type": "address"
      },
      {
        "internalType": "uint256[]",
        "name": "ids",
        "type": "uint256[]"
      }
    ],
    "name": "migrateOwners",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "name",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "owner",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "ownerOf",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "ownershipBitmap",
    "outputs": [
      {
        "internalType": "uint256[4]",
        "name": "",
        "type": "uint256[4]"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "pendingOwner",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "who",
        "type": "address"
      }
    ],
    "name": "plotsOf",
    "outputs": [
      {
        "internalType": "uint256[4]",
        "name": "",
        "type": "uint256[4]"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "plotsPacked",
    "outputs": [
      {
        "internalType": "uint256[1024]",
        "name": "out",
        "type": "uint256[1024]"
      }
    ],
    "stateMutability": "pure",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      }
    ],
    "name": "priceOf",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "pure",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "renounceOwnership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "tokenIndex",
        "type": "uint256"
      }
    ],
    "name": "reserveAvailable",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "reserveCommitment",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "reserveRequiredForAllOpenPlots",
    "outputs": [
      {
        "internalType": "uint256[5]",
        "name": "out",
        "type": "uint256[5]"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "rewardEnd",
    "outputs": [
      {
        "internalType": "uint64",
        "name": "",
        "type": "uint64"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "from",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "safeTransferFrom",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "from",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "tokenId",
        "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": "approved",
        "type": "bool"
      }
    ],
    "name": "setApprovalForAll",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "bytes4",
        "name": "interfaceId",
        "type": "bytes4"
      }
    ],
    "name": "supportsInterface",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "symbol",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      }
    ],
    "name": "tokenIndexOf",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "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": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "tokens",
    "outputs": [
      {
        "internalType": "contract IERC20",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "tokensPerEthWad",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "totalCommittedByToken",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "totalOwedByToken",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "from",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "transferFrom",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "newOwner",
        "type": "address"
      }
    ],
    "name": "transferOwnership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address payable",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "withdrawEth",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "tokenIndex",
        "type": "uint256"
      },
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "withdrawSurplusStock",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  }
]

Source code

// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {IUtopiaEligibility} from "./UtopiaEligibility.sol";

/// @title UtopiaLandMainnet
/// @notice Production land deeds bought with ETH and backed by finite,
/// pre-reserved Robinhood Stock Token rewards.
/// @dev Every purchase, deed transfer, and reward claim is eligibility-gated.
/// Reward rates and the program deadline are immutable. Stock Token funds that
/// are committed to sold plots cannot be withdrawn by the owner.
interface ILandOwners {
    function ownerOf(uint256 tokenId) external view returns (address);
}

contract UtopiaLandCity is ERC721, Ownable2Step, ReentrancyGuard {
    using SafeERC20 for IERC20;

    uint256 public constant SIDE = 32;
    uint256 public constant PLOTS = 1024;
    uint256 public constant YEAR = 365 days;
    uint256 public constant BPS = 10_000;
    uint256 public constant WAD = 1e18;
    uint256 public constant MAX_RATE = 1_000e18;
    uint256 public constant MAX_BATCH = 64;
    uint256 public constant MIN_REWARD_DURATION = 30 days;
    uint256 public constant MAX_REWARD_DURATION = 730 days;

    IERC20[5] public tokens;
    uint256[5] public tokensPerEthWad;
    IUtopiaEligibility public immutable eligibilityRegistry;
    uint64 public immutable rewardEnd;

    mapping(uint256 => uint64) public lastClaim;
    mapping(uint256 => uint256) public reserveCommitment;
    uint256[5] public totalCommittedByToken;
    // Kept for the common dashboard interface. This contract fails closed
    // instead of creating unbacked debt, so every value remains zero.
    uint256[5] public totalOwedByToken;

    uint256[4] private _ownershipBits;
    mapping(address => uint256[4]) private _ownerBits;

    event Bought(uint256 indexed id, address indexed buyer, uint256 price, uint256 rewardReserved);
    event Claimed(uint256 indexed id, address indexed to, address token, uint256 paid, uint256 stillOwed);
    event EthWithdrawn(address indexed to, uint256 amount);
    event SurplusStockWithdrawn(address indexed token, address indexed to, uint256 amount);
    event Migrated(uint256 indexed id, address indexed to);

    error InvalidConfig();
    error InvalidPlot();
    error WrongPayment();
    error NotPlotOwner();
    error NotMinted();
    error NotEligible();
    error ProgramEnded();
    error InsufficientReserve(uint256 tokenIndex, uint256 required, uint256 available);
    error InsufficientSurplus();
    error BatchTooLarge();
    error EthTransferFailed();

    constructor(
        IERC20[5] memory tokens_,
        uint256[5] memory rates_,
        IUtopiaEligibility eligibilityRegistry_,
        uint64 rewardEnd_,
        address initialOwner
    ) ERC721("utopia land", "PLOT") Ownable(initialOwner) {
        if (address(eligibilityRegistry_) == address(0)) revert InvalidConfig();
        if (rewardEnd_ < block.timestamp + MIN_REWARD_DURATION || rewardEnd_ > block.timestamp + MAX_REWARD_DURATION) {
            revert InvalidConfig();
        }

        for (uint256 i = 0; i < 5; i++) {
            address token = address(tokens_[i]);
            if (token == address(0) || token.code.length == 0 || rates_[i] == 0 || rates_[i] > MAX_RATE) {
                revert InvalidConfig();
            }
            if (IERC20Metadata(token).decimals() != 18) revert InvalidConfig();
            for (uint256 j = 0; j < i; j++) {
                if (token == address(tokens_[j])) revert InvalidConfig();
            }
        }

        tokens = tokens_;
        tokensPerEthWad = rates_;
        eligibilityRegistry = eligibilityRegistry_;
        rewardEnd = rewardEnd_;
    }

    // ---- plot attributes ----

    function priceOf(uint256 id) public pure returns (uint256) {
        if (id >= PLOTS) revert InvalidPlot();
        uint256 x = id % SIDE;
        uint256 y = id / SIDE;
        uint256 r = uint256(keccak256(abi.encodePacked("utopia/price/v1", id)));
        uint256 base = 0.0005 ether + (r % 0.002 ether);
        uint256 premium = (0.0025 ether * 300) / (300 + x * x + y * y);
        uint256 raw = base + premium;
        return raw - (raw % 1e13);
    }

    /// @notice Reference reward rate, not an investment APY or return promise.
    function apyBpsOf(uint256 id) public pure returns (uint256) {
        if (id >= PLOTS) revert InvalidPlot();
        return 310 + (uint256(keccak256(abi.encodePacked("utopia/apy/v1", id))) % 271);
    }

    /// @notice District-based reward stock: a center circle plus four quarters,
    /// matching the map. tokens = [TSLA, AAPL, NVDA, MSFT, AMZN].
    /// silicon heights (center) = NVDA; the four corners are the other stocks.
    function tokenIndexOf(uint256 id) public pure returns (uint256) {
        if (id >= PLOTS) revert InvalidPlot();
        int256 dx = 2 * int256(id % SIDE) - 31; // 2*(x - 15.5)
        int256 dy = 2 * int256(id / SIDE) - 31; // 2*(y - 15.5)
        if (dx * dx + dy * dy < 256) return 2; // center circle (r<8) -> NVDA
        if (dx < 0 && dy < 0) return 0; // upper-left  -> TSLA
        if (dx >= 0 && dy < 0) return 1; // upper-right -> AAPL
        if (dx < 0 && dy >= 0) return 3; // lower-left  -> MSFT
        return 4; // lower-right -> AMZN
    }

    function isEligible(address account) public view returns (bool) {
        try eligibilityRegistry.isEligible(account) returns (bool eligible) {
            return eligible;
        } catch {
            return false;
        }
    }

    // ---- finite reserve accounting ----

    function _rewardBetween(uint256 id, uint256 start, uint256 end) internal view returns (uint256) {
        if (end <= start) return 0;
        uint256 annualizedEth = Math.mulDiv(priceOf(id), apyBpsOf(id) * (end - start), BPS * YEAR);
        return Math.mulDiv(annualizedEth, tokensPerEthWad[tokenIndexOf(id)], WAD);
    }

    function maxRewardForSale(uint256 id) public view returns (uint256) {
        if (id >= PLOTS) revert InvalidPlot();
        if (block.timestamp >= rewardEnd) return 0;
        return _rewardBetween(id, block.timestamp, rewardEnd);
    }

    function reserveAvailable(uint256 tokenIndex) public view returns (uint256) {
        if (tokenIndex >= 5) revert InvalidConfig();
        uint256 balance = tokens[tokenIndex].balanceOf(address(this));
        uint256 committed = totalCommittedByToken[tokenIndex];
        return balance > committed ? balance - committed : 0;
    }

    /// @notice Additional reserves needed to make every currently open plot
    /// purchasable at this timestamp. Useful for the release preflight.
    function reserveRequiredForAllOpenPlots() external view returns (uint256[5] memory out) {
        if (block.timestamp >= rewardEnd) return out;
        for (uint256 id = 0; id < PLOTS; id++) {
            if (_ownerOf(id) == address(0)) out[tokenIndexOf(id)] += maxRewardForSale(id);
        }
    }

    // ---- buy / claim ----

    function buy(uint256 id) external payable nonReentrant {
        if (block.timestamp >= rewardEnd) revert ProgramEnded();
        if (!isEligible(msg.sender)) revert NotEligible();
        uint256 price = priceOf(id);
        if (msg.value != price) revert WrongPayment();
        if (_ownerOf(id) != address(0)) revert InvalidPlot();

        uint256 idx = tokenIndexOf(id);
        uint256 required = maxRewardForSale(id);
        uint256 available = reserveAvailable(idx);
        if (available < required) revert InsufficientReserve(idx, required, available);

        lastClaim[id] = uint64(block.timestamp);
        reserveCommitment[id] = required;
        totalCommittedByToken[idx] += required;
        _safeMint(msg.sender, id);
        emit Bought(id, msg.sender, price, required);
    }

    function claimable(uint256 id) public view returns (uint256) {
        if (_ownerOf(id) == address(0)) return 0;
        uint256 end = block.timestamp < rewardEnd ? block.timestamp : rewardEnd;
        return _rewardBetween(id, lastClaim[id], end);
    }

    function availablePayout(uint256 id) public view returns (uint256) {
        uint256 amount = claimable(id);
        uint256 balance = tokens[tokenIndexOf(id)].balanceOf(address(this));
        return amount < balance ? amount : balance;
    }

    function claimableMany(uint256[] calldata ids)
        external
        view
        returns (uint256[] memory claimableAmounts, uint256[] memory availableAmounts)
    {
        if (ids.length > MAX_BATCH) revert BatchTooLarge();
        claimableAmounts = new uint256[](ids.length);
        availableAmounts = new uint256[](ids.length);
        for (uint256 i = 0; i < ids.length; i++) {
            claimableAmounts[i] = claimable(ids[i]);
            availableAmounts[i] = availablePayout(ids[i]);
        }
    }

    function claim(uint256 id) external nonReentrant {
        _claim(id);
    }

    function claimMany(uint256[] calldata ids) external nonReentrant {
        if (ids.length > MAX_BATCH) revert BatchTooLarge();
        for (uint256 i = 0; i < ids.length; i++) {
            _claim(ids[i]);
        }
    }

    function _claim(uint256 id) internal {
        address plotOwner = _ownerOf(id);
        if (plotOwner == address(0)) revert NotMinted();
        if (plotOwner != msg.sender) revert NotPlotOwner();
        if (!isEligible(msg.sender)) revert NotEligible();

        uint256 amount = claimable(id);
        uint256 idx = tokenIndexOf(id);
        uint256 previousCommitment = reserveCommitment[id];
        uint256 released;

        if (block.timestamp >= rewardEnd) {
            released = previousCommitment;
            reserveCommitment[id] = 0;
            lastClaim[id] = rewardEnd;
        } else {
            released = amount;
            reserveCommitment[id] = previousCommitment - amount;
            lastClaim[id] = uint64(block.timestamp);
        }
        totalCommittedByToken[idx] -= released;

        if (amount > 0) tokens[idx].safeTransfer(msg.sender, amount);
        emit Claimed(id, msg.sender, address(tokens[idx]), amount, 0);
    }

    // ---- frontend hydration views ----

    function ownershipBitmap() external view returns (uint256[4] memory) {
        return _ownershipBits;
    }

    function plotsOf(address who) external view returns (uint256[4] memory) {
        return _ownerBits[who];
    }

    /// @notice price (bits 0..127) | rewardBps << 128 | tokenIdx << 144.
    function plotsPacked() external pure returns (uint256[1024] memory out) {
        for (uint256 id = 0; id < PLOTS; id++) {
            out[id] = priceOf(id) | (apyBpsOf(id) << 128) | (tokenIndexOf(id) << 144);
        }
    }

    function _update(address to, uint256 tokenId, address auth) internal override returns (address from) {
        if (to != address(0) && !isEligible(to)) revert NotEligible();
        from = super._update(to, tokenId, auth);

        uint256 word = tokenId >> 8;
        uint256 mask = uint256(1) << (tokenId & 255);
        if (from == address(0)) _ownershipBits[word] |= mask;
        else _ownerBits[from][word] &= ~mask;
        if (to == address(0)) _ownershipBits[word] &= ~mask;
        else _ownerBits[to][word] |= mask;
    }

    // ---- migration ----

    /// @notice Re-mint deeds from a prior utopia contract to their current
    /// owners so buyers keep their plots across a redeploy. Each migrated plot
    /// reserves its full reward like a sale, so fund the treasury first. Owners
    /// must already be eligible. Skips plots already minted here or absent on
    /// the old contract; reverts if a plot's reward reserve is short.
    function migrateOwners(ILandOwners oldLand, uint256[] calldata ids) external onlyOwner {
        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            if (id >= PLOTS || _ownerOf(id) != address(0)) continue;
            address to;
            try oldLand.ownerOf(id) returns (address a) {
                to = a;
            } catch {
                continue;
            }
            if (to == address(0)) continue;

            uint256 idx = tokenIndexOf(id);
            uint256 required = maxRewardForSale(id);
            uint256 available = reserveAvailable(idx);
            if (available < required) revert InsufficientReserve(idx, required, available);

            lastClaim[id] = uint64(block.timestamp);
            reserveCommitment[id] = required;
            totalCommittedByToken[idx] += required;
            _mint(to, id);
            emit Migrated(id, to);
        }
    }

    // ---- admin ----

    function withdrawEth(address payable to, uint256 amount) external onlyOwner nonReentrant {
        if (to == address(0)) revert InvalidConfig();
        (bool ok,) = to.call{value: amount}("");
        if (!ok) revert EthTransferFailed();
        emit EthWithdrawn(to, amount);
    }

    function withdrawSurplusStock(uint256 tokenIndex, address to, uint256 amount) external onlyOwner nonReentrant {
        if (to == address(0) || tokenIndex >= 5) revert InvalidConfig();
        if (amount > reserveAvailable(tokenIndex)) revert InsufficientSurplus();
        tokens[tokenIndex].safeTransfer(to, amount);
        emit SurplusStockWithdrawn(address(tokens[tokenIndex]), to, amount);
    }
}
Chain explorer2923msChain node76ms