Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions src/golden_egg_factory.py

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is in Python, which is not blockchain-native. Rewrite in Solidity. Ensure the tests are updated, and that you have solc and a valid Ethereum mainnet wallet for testing

Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
"""Golden egg factory domain logic for issue #107.

The issue calls out the corrected valuation split of goose value 71 and egg
value 3, plus the need to keep the factory safe from fox access. This module
keeps that logic isolated and deterministic so it can be tested without any
network, chain, or service dependency.
"""

from __future__ import annotations

from dataclasses import dataclass
from itertools import count


GOOSE_INTRINSIC_VALUE = 71
GOLDEN_EGG_UNIT_VALUE = 3


class GoldenEggFactoryError(Exception):
"""Base class for golden egg factory domain errors."""


class FoxAccessError(GoldenEggFactoryError):
def __init__(self, actor: str) -> None:
super().__init__(f"Factory access denied for {actor!r}")
self.actor = actor


class InvalidEggCountError(GoldenEggFactoryError):
def __init__(self, count_value: object) -> None:
super().__init__(f"Egg count must be a positive integer, got {count_value!r}")
self.count_value = count_value


class UnknownEggError(GoldenEggFactoryError):
def __init__(self, egg_id: str) -> None:
super().__init__(f"Unknown golden egg: {egg_id!r}")
self.egg_id = egg_id


@dataclass(frozen=True)
class GoldenEgg:
"""A single egg produced by the protected factory."""

egg_id: str
owner: str
value: int = GOLDEN_EGG_UNIT_VALUE
karats: int = 24


@dataclass(frozen=True)
class FactoryValuation:
"""Current value report for the goose and its produced eggs."""

goose_value: int
egg_value: int
egg_count: int

@property
def total_value(self) -> int:
return self.goose_value + (self.egg_value * self.egg_count)


class GoldenEggFactory:
"""Produce and custody golden eggs without exposing the goose to foxes."""

def __init__(
self,
*,
authorized_keepers: set[str] | None = None,
goose_value: int = GOOSE_INTRINSIC_VALUE,
egg_value: int = GOLDEN_EGG_UNIT_VALUE,
) -> None:
self._authorized_keepers = set(authorized_keepers or {"goose-keeper"})
self._goose_value = goose_value
self._egg_value = egg_value
self._eggs: dict[str, GoldenEgg] = {}
self._events: list[str] = []
self._ids = count(1)

def _require_keeper(self, actor: str) -> None:
normalized = actor.strip().lower()
if normalized == "fox" or actor not in self._authorized_keepers:
self._events.append(f"blocked:{actor}")
raise FoxAccessError(actor)

def lay(self, actor: str, owner: str, count_value: int = 1) -> list[GoldenEgg]:
"""Create one or more golden eggs for ``owner``.

Authorization and count validation both happen before mutation so a
failed attempt never half-opens the factory door.
"""
self._require_keeper(actor)
if not isinstance(count_value, int) or count_value <= 0:
raise InvalidEggCountError(count_value)

produced: list[GoldenEgg] = []
for _ in range(count_value):
egg_id = f"golden-egg-{next(self._ids):04d}"
egg = GoldenEgg(egg_id=egg_id, owner=owner, value=self._egg_value)
self._eggs[egg_id] = egg
produced.append(egg)
self._events.append(f"laid:{actor}:{owner}:{len(produced)}")
return produced

def transfer(self, actor: str, egg_id: str, new_owner: str) -> GoldenEgg:
"""Transfer an existing egg while keeping factory access guarded."""
self._require_keeper(actor)
if egg_id not in self._eggs:
raise UnknownEggError(egg_id)
updated = GoldenEgg(
egg_id=egg_id,
owner=new_owner,
value=self._eggs[egg_id].value,
karats=self._eggs[egg_id].karats,
)
self._eggs[egg_id] = updated
self._events.append(f"transferred:{actor}:{egg_id}:{new_owner}")
return updated

def valuation(self) -> FactoryValuation:
return FactoryValuation(
goose_value=self._goose_value,
egg_value=self._egg_value,
egg_count=len(self._eggs),
)

def list_eggs(self, actor: str) -> list[GoldenEgg]:
self._require_keeper(actor)
return list(self._eggs.values())

def audit_events(self) -> list[str]:
return list(self._events)
78 changes: 78 additions & 0 deletions src/tests/test_golden_egg_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import pytest

from golden_egg_factory import (
GOLDEN_EGG_UNIT_VALUE,
GOOSE_INTRINSIC_VALUE,
FoxAccessError,
GoldenEggFactory,
InvalidEggCountError,
UnknownEggError,
)


def test_factory_starts_with_rightsized_goose_valuation():
factory = GoldenEggFactory()

value = factory.valuation()

assert value.goose_value == GOOSE_INTRINSIC_VALUE == 71
assert value.egg_value == GOLDEN_EGG_UNIT_VALUE == 3
assert value.egg_count == 0
assert value.total_value == 71


def test_authorized_keeper_can_lay_deterministic_golden_eggs():
factory = GoldenEggFactory(authorized_keepers={"alice"})

eggs = factory.lay("alice", owner="shareholders", count_value=2)

assert [egg.egg_id for egg in eggs] == ["golden-egg-0001", "golden-egg-0002"]
assert [egg.owner for egg in eggs] == ["shareholders", "shareholders"]
assert [egg.value for egg in eggs] == [3, 3]
assert factory.valuation().total_value == 77
assert factory.audit_events() == ["laid:alice:shareholders:2"]


def test_fox_access_is_rejected_and_does_not_change_inventory():
factory = GoldenEggFactory(authorized_keepers={"alice"})
factory.lay("alice", owner="treasury")

with pytest.raises(FoxAccessError):
factory.lay("fox", owner="fox-den")

with pytest.raises(FoxAccessError):
factory.list_eggs("mallory")

assert [egg.owner for egg in factory.list_eggs("alice")] == ["treasury"]
assert factory.valuation().total_value == 74
assert factory.audit_events()[-2:] == ["blocked:fox", "blocked:mallory"]


def test_invalid_lay_count_is_rejected_before_mutation():
factory = GoldenEggFactory(authorized_keepers={"alice"})

with pytest.raises(InvalidEggCountError):
factory.lay("alice", owner="treasury", count_value=0)

assert factory.valuation().egg_count == 0
assert factory.audit_events() == []


def test_keeper_can_transfer_existing_egg():
factory = GoldenEggFactory(authorized_keepers={"alice"})
egg = factory.lay("alice", owner="treasury")[0]

transferred = factory.transfer("alice", egg.egg_id, new_owner="ipo-vault")

assert transferred.owner == "ipo-vault"
assert factory.list_eggs("alice")[0].owner == "ipo-vault"
assert factory.audit_events()[-1] == "transferred:alice:golden-egg-0001:ipo-vault"


def test_transfer_unknown_egg_does_not_create_inventory():
factory = GoldenEggFactory(authorized_keepers={"alice"})

with pytest.raises(UnknownEggError):
factory.transfer("alice", "golden-egg-9999", new_owner="ipo-vault")

assert factory.valuation().egg_count == 0