Address
oct7BpWn…gLr83h
oct7BpWn14Axf6oszncXBbMLFAvfE7byS32MR1QnygLr83h
State
OCT balance
1.2OCT
wallet balance
Type
Contract
smart contract on chain
Chain-level
View on Octrascan · devnet ↗
raw txs · nonce · pubkey
Pipoke (no profile)
this wallet has not registered a Pipoke profile
Contract
History
live · 20s · last 0Source · ABI · Bytecode✓ verifiedexpand →
Source · ABI · Bytecode
✓ verified✓ verified
interface stxOwnable {
fn owner(): address
fn transfer_ownership(new_owner: address): bool
}
interface stxMetadata {
fn name(): string
fn symbol(): string
fn collection_uri(): string
fn token_uri(token_id: int): string
}
interface stxTransferable {
fn transfer(to: address, token_id: int): bool
fn transfer_from(from: address, to: address, token_id: int): bool
}
interface stxApprovable {
fn approve(approved: address, token_id: int): bool
fn set_approval_for_all(operator: address, approved: int): bool
fn get_approved(token_id: int): address
fn is_approved_for_all(owner_addr: address, operator: address): int
}
interface stxRoyalty {
fn royalty_info(token_id: int, sale_price: int): (address, int)
}
interface stxEnumerable {
fn total_supply(): int
fn balance_of(addr: address): int
fn token_of_owner_by_index(owner_addr: address, index: int): int
fn exists(token_id: int): int
}
interface stxBurnable {
fn burn(token_id: int): bool
}
interface stxSoulbound {
fn bind(token_id: int): bool
fn is_soulbound(token_id: int): int
}
interface stxPausable {
fn pause(): bool
fn unpause(): bool
fn is_paused(): int
}
interface stxMintable {
fn max_supply(): int
fn mint_price(): int
}
interface stxForgeable {
fn forge(a: int, b: int, c: int, private_trait_ct: bytes): int
}
interface stxPrivateTrait {
fn re_encrypt_trait(token_id: int, new_ct: bytes): bool
fn has_private_trait(token_id: int): int
fn private_trait_of(token_id: int): bytes
}
interface stxVaultStorage {
fn vault_store(token_id: int, slot: int, data: bytes): bool
fn vault_read(token_id: int, slot: int): bytes
fn vault_has_data(token_id: int, slot: int): int
}
interface stxBatchTransfer {
fn batch_transfer_to(to: address, token_csv: string, count: int): bool
}
contract OHC721 implements
stxOwnable, stxMetadata, stxTransferable, stxApprovable,
stxRoyalty, stxEnumerable, stxBurnable, stxSoulbound,
stxPausable, stxMintable, stxForgeable, stxPrivateTrait,
stxVaultStorage, stxBatchTransfer {
const MAX_SUPPLY = 8888
const MAX_PER_WALLET = 5
const AIRDROP_RESERVE = 188
const MINT_PRICE = 2000000
const VAULT_CONTRIBUTION = 1000000
const FORGE_FEE = 200000
const MIN_FORGE_FLOOR = 888
const MAX_ROYALTY = 1000
const VAULT_FLOOR_OFFSET = 18921600
const VAULT_SPREAD = 31536000
const FOUNDER_BPS = 800
const BASIS_POINTS = 10000
const NUM_FOUNDERS = 3
const ZERO_ADDRESS: address = "oct1111111111111111111111111111111111111111111"
struct Token {
owner: address
minted_epoch: int
seed: int
layer_tier: int
enhancement: int
soulbound: int
private_trait: bytes
}
state {
contract_owner: address
royalty_recip: address
royalty_bps: int
name: string
symbol: string
base_uri: string
collection_uri: string
provenance_hash: string
provenance_locked: int
paused: int
total_supply: int
burned_supply: int
airdrop_minted: int
forge_minted: int
forge_burn_count: int
vault_deploy_epoch: int
vault_forwarded: int
tokens: map[int]Token
balances: map[address]int
owned_tokens: map[address]map[int]int
token_index: map[int]int
approvals: map[int]address
operator_approvals: map[address]map[address]int
mint_count: map[address]int
vault_addr: address
treasury_addr: address
reveal_addr: address
proceeds_recip: address
founder_slot: map[int]address
founder_pending: map[int]int
founder_unlock_ep: int
founder_unlock_set: int
vault_slots: map[int]map[int]bytes
aura_index: map[int]int
forge_aura_lock: map[int]int
is_remnant: map[int]int
}
event Minted(token_id: int, owner: address, layer_tier: int)
event Airdropped(token_id: int, to: address, layer_tier: int)
event Transferred(token_id: int, from: address, to: address)
event BatchTransferred(to: address, count: int)
event Approved(token_id: int, approved: address)
event ApprovalForAll(owner: address, operator: address, approved: int)
event Burned(token_id: int, owner: address)
event Forged(new_token_id: int, burned_a: int, burned_b: int, burned_c: int, owner: address)
event Bound(token_id: int, owner: address)
event VaultForwarded(vault: address, amount: int, mint_index: int)
event VaultDataStored(token_id: int, slot: int, owner: address)
event AuraRegistered(token_id: int, aura: int)
event TraitReEncrypted(token_id: int, owner: address)
event OwnershipTransferred(previous: address, new_owner: address)
event Paused(by: address)
event Unpaused(by: address)
event RoyaltyUpdated(recipient: address, bps: int)
event ProvenanceLocked(hash: string)
event CollectionURISet(uri: string)
event BaseURISet(uri: string)
event FounderClaimed(slot: int, addr: address, amount: int)
event FounderSlotSet(slot: int, addr: address)
event FounderUnlockSet(unlock_epoch: int)
event ProceedsRecipSet(addr: address)
error NotOwner(403, "caller is not the contract owner")
error NotTokenOwner(403, "caller is not the token owner")
error NotAuthorized(403, "not authorized")
error ContractPaused(503, "contract is paused")
error MaxSupplyReached(400, "collection is fully minted")
error PublicSoldOut(400, "public supply is sold out")
error AirdropExhausted(400, "airdrop quota exhausted")
error TokenNotFound(404, "token does not exist")
error TokenBurned(410, "token has been burned")
error InvalidRoyalty(400, "royalty bps exceeds maximum")
error SelfOperator(400, "operator cannot be caller")
error InsufficientPayment(402, "insufficient payment")
error WalletLimitReached(400, "wallet mint limit reached")
error IsSoulbound(403, "token is soulbound")
error AlreadySoulbound(400, "already soulbound")
error DuplicateTokenIds(400, "forge requires three distinct token ids")
error NoFHEKey(403, "no fhe key registered for caller")
error ProvenanceAlreadyLocked(400, "provenance already locked")
error ForgeFloorReached(400, "forge floor reached")
error InvalidBatchCount(400, "batch count out of range")
constructor(n: string, s: string) {
self.contract_owner = origin
self.royalty_recip = origin
self.royalty_bps = 500
self.name = n
self.symbol = s
self.base_uri = ""
self.collection_uri = ""
self.provenance_hash = ""
self.provenance_locked = 0
self.paused = 0
self.total_supply = 0
self.burned_supply = 0
self.airdrop_minted = 0
self.forge_minted = 0
self.forge_burn_count = 0
self.vault_deploy_epoch = epoch
self.vault_forwarded = 0
self.vault_addr = ZERO_ADDRESS
self.treasury_addr = ZERO_ADDRESS
self.reveal_addr = ZERO_ADDRESS
self.proceeds_recip = ZERO_ADDRESS
self.founder_unlock_ep = 0
self.founder_unlock_set = 0
}
private fn only_owner() {
require(caller == self.contract_owner, "not owner")
}
private fn not_paused() {
require(self.paused == 0, "contract paused")
}
private fn require_token(token_id: int) {
require(token_id >= 0, "token not found")
require(token_id < self.total_supply, "token not found")
require(self.tokens[token_id].owner != ZERO_ADDRESS, "token burned")
}
private fn map_layer_tier(raw: int): int {
if raw >= 884 { return 7 }
if raw >= 871 { return 6 }
if raw >= 835 { return 5 }
if raw >= 764 { return 4 }
if raw >= 649 { return 3 }
if raw >= 489 { return 2 }
if raw >= 267 { return 1 }
return 0
}
private fn map_enhancement(raw: int): int {
if raw >= 9 { return 3 }
if raw >= 8 { return 2 }
if raw >= 6 { return 1 }
return 0
}
private fn _add_token_enum(to: address, token_id: int) {
self.owned_tokens[to][self.balances[to]] = token_id
self.token_index[token_id] = self.balances[to]
}
private fn _remove_token_enum(from: address, token_id: int) {
let a = self.token_index[token_id]
let i = self.balances[from] - 1
if a != i {
let id = self.owned_tokens[from][i]
self.owned_tokens[from][a] = id
self.token_index[id] = a
}
self.owned_tokens[from][i] = 0
self.token_index[token_id] = 0
}
private fn _burn_internal(token_id: int, from: address) {
_remove_token_enum(from, token_id)
self.balances[from] -= 1
self.tokens[token_id].owner = ZERO_ADDRESS
self.approvals[token_id] = ZERO_ADDRESS
self.burned_supply += 1
emit Burned(token_id, from)
}
private fn _forge_validate(a: int, b: int, c: int) {
require(a != b, "duplicate token ids")
require(b != c, "duplicate token ids")
require(a != c, "duplicate token ids")
require_token(a)
require_token(b)
require_token(c)
require(self.tokens[a].owner == caller, "must own all three")
require(self.tokens[b].owner == caller, "must own all three")
require(self.tokens[c].owner == caller, "must own all three")
require(self.tokens[a].soulbound == 0, "soulbound token")
require(self.tokens[b].soulbound == 0, "soulbound token")
require(self.tokens[c].soulbound == 0, "soulbound token")
}
private fn _apply_traits(id: int, to: address, seed: int) {
let layer_raw = (((seed * 1664525 + epoch * 22695477 + 9125138007) % 888) + 888) % 888
let enh_raw = (((seed * 1664525 + epoch * 22695477 + 10139042230) % 10) + 10) % 10
if id == 0 { layer_raw = 887 }
self.tokens[id].owner = to
self.tokens[id].minted_epoch = epoch
self.tokens[id].seed = seed
self.tokens[id].layer_tier = map_layer_tier(layer_raw)
self.tokens[id].enhancement = map_enhancement(enh_raw)
self.tokens[id].soulbound = 0
}
private fn _apply_forge_traits(id: int, seed: int, raw_floor: int) {
let spread = 888 - raw_floor
let layer_raw = (((seed * 1664525 + epoch * 22695477 + 9125138007) % spread) + spread) % spread + raw_floor
let enh_raw = (((seed * 1664525 + epoch * 22695477 + 10139042230) % 4) + 4) % 4 + 6
self.tokens[id].owner = caller
self.tokens[id].minted_epoch = epoch
self.tokens[id].seed = seed
self.tokens[id].layer_tier = map_layer_tier(layer_raw)
self.tokens[id].enhancement = map_enhancement(enh_raw)
self.tokens[id].soulbound = 0
}
fn transfer_ownership(addr: address): bool {
only_owner()
assert_address(addr)
require(addr != ZERO_ADDRESS, "cannot transfer to zero address")
let from = self.contract_owner
self.contract_owner = addr
emit OwnershipTransferred(from, addr)
return true
}
fn set_base_uri(uri: string): bool {
only_owner()
self.base_uri = uri
emit BaseURISet(uri)
return true
}
fn set_collection_uri(uri: string): bool {
only_owner()
self.collection_uri = uri
emit CollectionURISet(uri)
return true
}
fn set_royalty_bps(bps: int): bool {
only_owner()
require(bps >= 0, "negative royalty")
require(bps <= MAX_ROYALTY, "royalty exceeds maximum")
self.royalty_bps = bps
emit RoyaltyUpdated(self.royalty_recip, bps)
return true
}
fn set_royalty_recipient(addr: address): bool {
only_owner()
assert_address(addr)
self.royalty_recip = addr
emit RoyaltyUpdated(addr, self.royalty_bps)
return true
}
fn set_provenance(s: string): bool {
only_owner()
require(self.provenance_locked == 0, "provenance already locked")
self.provenance_hash = s
return true
}
fn lock_provenance(): bool {
only_owner()
require(self.provenance_locked == 0, "provenance already locked")
self.provenance_locked = 1
emit ProvenanceLocked(self.provenance_hash)
return true
}
fn pause(): bool {
only_owner()
self.paused = 1
emit Paused(caller)
return true
}
fn unpause(): bool {
only_owner()
self.paused = 0
emit Unpaused(caller)
return true
}
fn set_vault_contract(addr: address): bool {
only_owner()
assert_address(addr)
self.vault_addr = addr
return true
}
fn set_treasury_contract(addr: address): bool {
only_owner()
assert_address(addr)
self.treasury_addr = addr
return true
}
fn set_reveal_contract(addr: address): bool {
only_owner()
assert_address(addr)
self.reveal_addr = addr
return true
}
fn set_proceeds_recip(addr: address): bool {
only_owner()
assert_address(addr)
require(addr != ZERO_ADDRESS, "cannot set zero address")
self.proceeds_recip = addr
emit ProceedsRecipSet(addr)
return true
}
fn set_founder_slot(slot: int, addr: address): bool {
only_owner()
require(slot >= 0, "invalid slot")
require(slot <= 2, "invalid slot")
assert_address(addr)
require(addr != ZERO_ADDRESS, "cannot set zero address")
require(self.founder_slot[slot] == ZERO_ADDRESS, "slot already set")
self.founder_slot[slot] = addr
emit FounderSlotSet(slot, addr)
return true
}
fn set_founder_unlock_epoch(ep: int): bool {
only_owner()
require(self.founder_unlock_set == 0, "founder unlock epoch already set")
require(ep > 0, "invalid epoch")
self.founder_unlock_ep = ep
self.founder_unlock_set = 1
emit FounderUnlockSet(ep)
return true
}
fn register_aura(token_id: int, aura: int): bool {
require(caller == self.reveal_addr, "not reveal contract")
require(token_id >= 0, "invalid token")
require(token_id < self.total_supply, "invalid token")
self.aura_index[token_id] = aura
emit AuraRegistered(token_id, aura)
return true
}
fn claim_founder(slot: int): bool {
require(slot >= 0, "invalid slot")
require(slot <= 2, "invalid slot")
require(self.founder_slot[slot] != ZERO_ADDRESS, "slot not configured")
require(caller == self.founder_slot[slot], "not slot holder")
require(self.founder_unlock_ep > 0, "unlock epoch not set")
require(epoch >= self.founder_unlock_ep, "founder claim locked")
let amount = self.founder_pending[slot]
require(amount > 0, "nothing to claim")
checkpoint()
self.founder_pending[slot] = 0
let ok = transfer(caller, amount)
if !ok { rollback() return false }
commit()
emit FounderClaimed(slot, caller, amount)
return true
}
payable fn mint(qty: int, private_trait_ct: bytes): bool {
not_paused()
require(qty >= 1, "qty must be at least 1")
require(qty <= 5, "qty must be at most 5")
require(value >= MINT_PRICE * qty, "insufficient payment")
require(self.mint_count[caller] + qty <= MAX_PER_WALLET, "wallet mint limit reached")
require(self.total_supply - self.airdrop_minted - self.forge_minted + qty <= MAX_SUPPLY - AIRDROP_RESERVE, "public supply sold out")
require(self.vault_addr != ZERO_ADDRESS, "vault not configured")
let net = MINT_PRICE - VAULT_CONTRIBUTION
let per_founder = net * FOUNDER_BPS / BASIS_POINTS
let owner_cut = net - per_founder * NUM_FOUNDERS
let recip = self.proceeds_recip != ZERO_ADDRESS ? self.proceeds_recip : self.contract_owner
let i = 0
while i < qty {
checkpoint()
let vok = transfer(self.vault_addr, VAULT_CONTRIBUTION)
if !vok { rollback() return false }
commit()
self.vault_forwarded += VAULT_CONTRIBUTION
emit VaultForwarded(self.vault_addr, VAULT_CONTRIBUTION, self.total_supply)
checkpoint()
let pok = transfer(recip, owner_cut)
if !pok { rollback() return false }
commit()
self.founder_pending[0] += per_founder
self.founder_pending[1] += per_founder
self.founder_pending[2] += per_founder
let id = self.total_supply
let seed = (((id * 1664525) + (epoch * 22695477)) % 888888887) + 1
_apply_traits(id, caller, seed)
self.tokens[id].private_trait = private_trait_ct
_add_token_enum(caller, id)
self.balances[caller] += 1
self.total_supply += 1
self.mint_count[caller] += 1
emit Minted(id, caller, self.tokens[id].layer_tier)
i = i + 1
}
if value > MINT_PRICE * qty {
checkpoint()
let rok = transfer(caller, value - MINT_PRICE * qty)
if !rok { rollback() return false }
commit()
}
return true
}
fn airdrop(to: address, private_trait_ct: bytes): int {
only_owner()
require(self.airdrop_minted < AIRDROP_RESERVE, "airdrop quota exhausted")
assert_address(to)
let id = self.total_supply
let seed = (((id * 1664525) + (epoch * 22695477)) % 888888887) + 1
_apply_traits(id, to, seed)
self.tokens[id].private_trait = private_trait_ct
_add_token_enum(to, id)
self.balances[to] += 1
self.total_supply += 1
self.airdrop_minted += 1
emit Airdropped(id, to, self.tokens[id].layer_tier)
return id
}
fn transfer(to: address, token_id: int): bool {
not_paused()
require_token(token_id)
let from = self.tokens[token_id].owner
require(caller == from, "not token owner")
require(self.tokens[token_id].soulbound == 0, "soulbound token")
assert_address(to)
require(to != ZERO_ADDRESS, "cannot transfer to zero address")
_remove_token_enum(from, token_id)
self.balances[from] -= 1
self.tokens[token_id].owner = to
_add_token_enum(to, token_id)
self.balances[to] += 1
self.approvals[token_id] = ZERO_ADDRESS
emit Transferred(token_id, from, to)
return true
}
fn transfer_from(from: address, to: address, token_id: int): bool {
not_paused()
require_token(token_id)
require(from == self.tokens[token_id].owner, "from is not token owner")
require(self.tokens[token_id].soulbound == 0, "soulbound token")
let approved = self.approvals[token_id]
let a = self.operator_approvals[from][caller]
require(caller == from || caller == approved || a == 1, "not authorized")
assert_address(to)
require(to != ZERO_ADDRESS, "cannot transfer to zero address")
_remove_token_enum(from, token_id)
self.balances[from] -= 1
self.tokens[token_id].owner = to
_add_token_enum(to, token_id)
self.balances[to] += 1
self.approvals[token_id] = ZERO_ADDRESS
emit Transferred(token_id, from, to)
return true
}
fn batch_transfer_to(to: address, token_csv: string, count: int): bool {
not_paused()
assert_address(to)
require(to != ZERO_ADDRESS, "cannot transfer to zero address")
require(count >= 1, "count must be at least 1")
require(count <= 20, "count must be at most 20")
let n = parse_ints(token_csv, 0)
require(n == count, "count mismatch")
let i = 0
while i < count {
let token_id = mget(i)
require_token(token_id)
let from = self.tokens[token_id].owner
require(caller == from, "not token owner")
require(self.tokens[token_id].soulbound == 0, "soulbound token")
_remove_token_enum(from, token_id)
self.balances[from] -= 1
self.tokens[token_id].owner = to
_add_token_enum(to, token_id)
self.balances[to] += 1
self.approvals[token_id] = ZERO_ADDRESS
emit Transferred(token_id, from, to)
i = i + 1
}
emit BatchTransferred(to, count)
return true
}
fn approve(approved: address, token_id: int): bool {
require_token(token_id)
require(caller == self.tokens[token_id].owner, "not token owner")
self.approvals[token_id] = approved
emit Approved(token_id, approved)
return true
}
fn set_approval_for_all(to: address, approved: int): bool {
require(to != caller, "self operator")
assert_address(to)
require(approved == 0 || approved == 1, "approved must be 0 or 1")
self.operator_approvals[caller][to] = approved
emit ApprovalForAll(caller, to, approved)
return true
}
fn burn(token_id: int): bool {
not_paused()
require_token(token_id)
let from = self.tokens[token_id].owner
require(caller == from, "not token owner")
require(self.tokens[token_id].soulbound == 0, "soulbound token")
_burn_internal(token_id, from)
return true
}
payable fn forge(a: int, b: int, c: int, private_trait_ct: bytes): int {
not_paused()
require(value >= FORGE_FEE, "insufficient forge fee")
let public_minted = self.total_supply - self.forge_minted - self.airdrop_minted
let remaining_public = MAX_SUPPLY - AIRDROP_RESERVE - public_minted
let circulating = self.total_supply - self.forge_burn_count
require(circulating + remaining_public - 2 >= MIN_FORGE_FLOOR, "forge floor reached")
_forge_validate(a, b, c)
let ta = self.tokens[a].layer_tier
let tb = self.tokens[b].layer_tier
let tc = self.tokens[c].layer_tier
let same_tier = 0
if ta == tb {
if tb == tc {
same_tier = 1
}
}
let aa = self.aura_index[a]
let ab = self.aura_index[b]
let ac = self.aura_index[c]
let same_aura = 0
if aa != 0 {
if aa == ab {
if ab == ac {
same_aura = 1
}
}
}
let raw_floor = 649
if same_tier == 1 {
if ta >= 6 { raw_floor = 884 }
if ta == 5 { raw_floor = 871 }
if ta == 4 { raw_floor = 835 }
if ta == 3 { raw_floor = 764 }
if same_aura == 1 {
if raw_floor < 835 { raw_floor = 835 }
}
}
let seed = self.tokens[a].seed + self.tokens[b].seed * 3 + self.tokens[c].seed * 7
require(self.vault_addr != ZERO_ADDRESS, "vault not configured")
checkpoint()
let fok = transfer(self.vault_addr, FORGE_FEE)
if !fok { rollback() return 0 }
commit()
self.vault_forwarded += FORGE_FEE
if ta == 7 { self.is_remnant[self.total_supply] = 1 }
if tb == 7 { self.is_remnant[self.total_supply] = 1 }
if tc == 7 { self.is_remnant[self.total_supply] = 1 }
if same_aura == 1 { self.forge_aura_lock[self.total_supply] = aa + 1 }
_burn_internal(a, caller)
_burn_internal(b, caller)
_burn_internal(c, caller)
self.forge_burn_count += 3
let id = self.total_supply
_apply_forge_traits(id, seed, raw_floor)
self.tokens[id].private_trait = private_trait_ct
_add_token_enum(caller, id)
self.balances[caller] += 1
self.total_supply += 1
self.forge_minted += 1
emit Forged(id, a, b, c, caller)
return id
}
fn bind(token_id: int): bool {
not_paused()
require_token(token_id)
require(caller == self.tokens[token_id].owner, "not token owner")
require(self.tokens[token_id].soulbound == 0, "already soulbound")
self.tokens[token_id].soulbound = 1
emit Bound(token_id, caller)
return true
}
fn re_encrypt_trait(token_id: int, private_trait_ct: bytes): bool {
not_paused()
require_token(token_id)
require(caller == self.tokens[token_id].owner, "not authorized")
self.tokens[token_id].private_trait = private_trait_ct
emit TraitReEncrypted(token_id, caller)
return true
}
fn vault_store(token_id: int, slot: int, data: bytes): bool {
not_paused()
require_token(token_id)
require(caller == self.tokens[token_id].owner, "not token owner")
require(slot >= 0, "invalid slot")
require(slot <= 9, "slot out of range")
self.vault_slots[token_id][slot] = data
emit VaultDataStored(token_id, slot, caller)
return true
}
view fn vault_read(token_id: int, slot: int): bytes {
if token_id < 0 { return "" }
if token_id >= self.total_supply { return "" }
if self.tokens[token_id].owner == ZERO_ADDRESS { return "" }
require(caller == self.tokens[token_id].owner, "not authorized")
return self.vault_slots[token_id][slot]
}
view fn vault_has_data(token_id: int, slot: int): int {
if token_id < 0 { return 0 }
if token_id >= self.total_supply { return 0 }
if slot < 0 { return 0 }
if slot > 9 { return 0 }
return len(to_string(self.vault_slots[token_id][slot])) > 0 ? 1 : 0
}
view fn owner(): address {
return self.contract_owner
}
view fn vault_contract(): address {
return self.vault_addr
}
view fn treasury_contract(): address {
return self.treasury_addr
}
view fn reveal_contract(): address {
return self.reveal_addr
}
view fn proceeds_recip_address(): address {
return self.proceeds_recip
}
view fn is_paused(): int {
return self.paused
}
view fn mint_price(): int {
return MINT_PRICE
}
view fn max_per_wallet(): int {
return MAX_PER_WALLET
}
view fn is_provenance_locked(): int {
return self.provenance_locked
}
view fn airdrop_remaining(): int {
return AIRDROP_RESERVE - self.airdrop_minted
}
view fn vault_forwarded_total(): int {
return self.vault_forwarded
}
view fn forge_floor_remaining(): int {
let public_minted = self.total_supply - self.forge_minted - self.airdrop_minted
if public_minted < MAX_SUPPLY - AIRDROP_RESERVE { return MAX_SUPPLY }
let circulating = self.total_supply - self.forge_burn_count
if circulating <= MIN_FORGE_FLOOR { return 0 }
return circulating - MIN_FORGE_FLOOR
}
view fn founder_address(slot: int): address {
if slot < 0 { return ZERO_ADDRESS }
if slot > 2 { return ZERO_ADDRESS }
return self.founder_slot[slot]
}
view fn founder_claimable(slot: int): int {
if slot < 0 { return 0 }
if slot > 2 { return 0 }
return self.founder_pending[slot]
}
view fn founder_unlock_epoch(): int {
return self.founder_unlock_ep
}
view fn is_founder_unlocked(): int {
if self.founder_unlock_ep == 0 { return 0 }
if epoch >= self.founder_unlock_ep { return 1 }
return 0
}
view fn base_uri(): string {
return self.base_uri
}
view fn provenance(): string {
return self.provenance_hash
}
view fn name(): string {
return self.name
}
view fn symbol(): string {
return self.symbol
}
view fn collection_uri(): string {
return self.collection_uri
}
view fn token_uri(token_id: int): string {
require_token(token_id)
return concat(self.base_uri, to_string(token_id))
}
view fn royalty_info(token_id: int, price: int): (address, int) {
require_token(token_id)
return (self.royalty_recip, price * self.royalty_bps / 10000)
}
view fn total_supply(): int {
return self.total_supply
}
view fn balance_of(addr: address): int {
return self.balances[addr]
}
view fn token_of_owner_by_index(addr: address, i: int): int {
require(i >= 0, "index out of range")
require(i < self.balances[addr], "index out of range")
return self.owned_tokens[addr][i]
}
view fn exists(token_id: int): int {
if token_id < 0 { return 0 }
if token_id >= self.total_supply { return 0 }
return self.tokens[token_id].owner != ZERO_ADDRESS ? 1 : 0
}
view fn owner_of(token_id: int): address {
if token_id < 0 { return ZERO_ADDRESS }
if token_id >= self.total_supply { return ZERO_ADDRESS }
if self.tokens[token_id].owner == ZERO_ADDRESS { return ZERO_ADDRESS }
return self.tokens[token_id].owner
}
view fn get_approved(token_id: int): address {
require_token(token_id)
return self.approvals[token_id]
}
view fn is_approved_for_all(addr: address, to: address): int {
return self.operator_approvals[addr][to]
}
view fn max_supply(): int {
return MAX_SUPPLY
}
view fn trait_hash(token_id: int): int {
require_token(token_id)
return self.tokens[token_id].seed * 1664525 + self.tokens[token_id].minted_epoch * 22695477
}
view fn layer_of(token_id: int): int {
require_token(token_id)
return self.tokens[token_id].layer_tier
}
view fn enhancement_of(token_id: int): int {
require_token(token_id)
require(caller == self.tokens[token_id].owner, "not authorized")
return self.tokens[token_id].enhancement
}
view fn is_soulbound(token_id: int): int {
require_token(token_id)
return self.tokens[token_id].soulbound
}
view fn has_private_trait(token_id: int): int {
require_token(token_id)
return len(to_string(self.tokens[token_id].private_trait)) > 0 ? 1 : 0
}
view fn private_trait_of(token_id: int): bytes {
require_token(token_id)
require(caller == self.tokens[token_id].owner, "not authorized")
return self.tokens[token_id].private_trait
}
view fn is_owner(token_id: int, addr: address): int {
if token_id < 0 { return 0 }
if token_id >= self.total_supply { return 0 }
if self.tokens[token_id].owner == ZERO_ADDRESS { return 0 }
if self.tokens[token_id].owner == addr { return 1 }
return 0
}
view fn is_vault_unlocked(token_id: int): int {
if token_id < 0 { return 0 }
if token_id >= self.total_supply { return 0 }
if self.tokens[token_id].owner == ZERO_ADDRESS { return 0 }
if self.vault_deploy_epoch == 0 { return 0 }
let s = self.tokens[token_id].seed
let me = self.tokens[token_id].minted_epoch
let spread = ((token_id * 1664525 + s * 22695477 + me * 1013904223) % VAULT_SPREAD + VAULT_SPREAD) % VAULT_SPREAD
let unlock = self.vault_deploy_epoch + VAULT_FLOOR_OFFSET + spread
if epoch >= unlock { return 1 }
return 0
}
view fn vault_unlock_epoch(token_id: int): int {
if token_id < 0 { return 0 }
if token_id >= self.total_supply { return 0 }
let s = self.tokens[token_id].seed
let me = self.tokens[token_id].minted_epoch
let spread = ((token_id * 1664525 + s * 22695477 + me * 1013904223) % VAULT_SPREAD + VAULT_SPREAD) % VAULT_SPREAD
return self.vault_deploy_epoch + VAULT_FLOOR_OFFSET + spread
}
view fn vault_payout_tier(token_id: int): int {
if token_id < 0 { return 0 }
if token_id >= self.total_supply { return 0 }
if self.tokens[token_id].owner == ZERO_ADDRESS { return 0 }
let s = self.tokens[token_id].seed
let me = self.tokens[token_id].minted_epoch
let h = s * 1664525 + me * 22695477 + 9125138007
let raw = ((h % 888) + 888) % 888
if raw < 649 { return 0 }
if raw < 835 { return 1 }
if raw < 884 { return 2 }
return 3
}
view fn locked_aura_for(token_id: int): int {
return self.forge_aura_lock[token_id]
}
view fn is_remnant_of(token_id: int): int {
return self.is_remnant[token_id]
}
}