The on-chain clock spring of the Genesis Conductor machine. Not a reasoning engine — a tempo governor, policy anchor, and settlement witness.
<aside> 🔗
Canonical cluster anchors (previewable). Yennefer cluster · TAEX · Retraining loop · §6.17 · Integrations registry · Integrative Flow.
‣ · ‣ · ‣ · ‣ · ‣ · TAEX Intent Router — Agent-Based Routing with Dissonance Memory MCP · ‣ · ‣ · ‣
</aside>
$e^{i\pi} + 1 = 0$ governs the off-chain agent ensemble. On-chain, only the escapement lives — the fail-closed cadence kernel that stores tension, releases one admissible cycle per tick, and blocks re-entry until settlement.
| Clock Metaphor | Function | Enforcement |
|---|---|---|
| Spring | windSpring() |
Stored execution energy. No energy → no tick. |
| Ratchet | armTick() |
Capsule hash current, expected delta positive, proof exists, spacing respected. |
| Escapement | releaseTick() |
One cycle per tick. Decrements energy. Updates timing. |
| Face | Events + canArmNextTick() |
Public state + commitment chain. |
| Ledger | settleCycle() |
Immutable settlement. Receipts + realized delta before next tick. |
| Jam release | cancelStaleCycle() |
Guardian fail-safe after stale window. |
euler-cycle-attestor/
├── foundry.toml
├── .env.example
├── src/
│ └── EulerCycleAttestor.sol
├── script/
│ ├── Deploy.s.sol
│ └── ConfigureSpring.s.sol
├── test/
│ ├── EulerCycleAttestor.t.sol
│ └── EulerCycleAttestor.invariants.t.sol
└── README.md
foundry.toml[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.24"
optimizer = true
optimizer_runs = 200
evm_version = "cancun"
[profile.default.fuzz]
runs = 512
[rpc_endpoints]
base = "<https://mainnet.base.org>"
base_sepolia = "<https://sepolia.base.org>"
local = "<http://127.0.0.1:8545>"
[etherscan]
base = { key = "${BASESCAN_API_KEY}", chain = 8453 }
.env.exampleDEPLOYER_PRIVATE_KEY=
BASESCAN_API_KEY=
ADMIN_ADDRESS=
src/EulerCycleAttestor.sol// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract EulerCycleAttestor is AccessControl, Pausable, ReentrancyGuard {
bytes32 public constant POLICY_ROLE = keccak256("POLICY_ROLE");
bytes32 public constant CLOCKKEEPER_ROLE = keccak256("CLOCKKEEPER_ROLE");
bytes32 public constant SETTLER_ROLE = keccak256("SETTLER_ROLE");
bytes32 public constant GUARDIAN_ROLE = keccak256("GUARDIAN_ROLE");
enum CycleState { None, Armed, Executed, Settled, Cancelled }
struct PolicyCapsule {
bytes32 capsuleHash;
uint64 version;
bool proofRequired;
bool active;
}
struct SpringConfig {
uint64 minTickSpacing;
uint32 staleAfter;
uint16 maxTicksPerWind;
uint128 maxGasValueWei;
}
struct SpringState {
uint64 epoch;
uint32 tick;
uint64 lastReleaseAt;
uint16 remainingEnergy;
bool windingOpen;
}
struct Cycle {
bytes32 cycleId;
bytes32 runId;
uint32 tick;
address executor;
CycleState state;
uint64 armedAt;
uint64 executedAt;
uint64 settledAt;
bytes32 capsuleHash;
bytes32 preStateHash;
bytes32 quoteHash;
bytes32 routeHash;
bytes32 proofHash;
bytes32 execCommitment;
bytes32 receiptsHash;
bytes32 postStateHash;
bytes32 reportHash;
int256 expectedDeltaWei;
int256 realizedDeltaWei;
uint128 gasBoundWei;
}
PolicyCapsule public capsule;
SpringConfig public springConfig;
SpringState public spring;
bytes32 public activeCycleId;
mapping(bytes32 => Cycle) public cycles;
bytes32[] public cycleIndex;
event CapsuleSet(bytes32 indexed capsuleHash, uint64 version, bool proofRequired);
event SpringConfigured(uint64 minTickSpacing, uint32 staleAfter, uint16 maxTicksPerWind, uint128 maxGasValueWei);
event SpringWound(uint64 indexed epoch, uint16 energyAdded, uint16 totalEnergy);
event TickArmed(bytes32 indexed cycleId, bytes32 indexed runId, uint32 indexed tick, bytes32 capsuleHash, int256 expectedDeltaWei, uint128 gasBoundWei);
event TickReleased(bytes32 indexed cycleId, uint32 indexed tick, address indexed executor, bytes32 execCommitment);
event CycleSettled(bytes32 indexed cycleId, uint32 indexed tick, int256 realizedDeltaWei, bytes32 receiptsHash, bytes32 postStateHash);
event CycleCancelled(bytes32 indexed cycleId, uint32 indexed tick, string reason);
error NoActiveCapsule();
error SpringNotWound();
error TickTooEarly(uint64 nowTs, uint64 earliestTs);
error LiveCycleExists(bytes32 cycleId);
error NoLiveCycle();
error InvalidState(CycleState expected, CycleState actual);
error ProofRequired();
error NonPositiveExpectedDelta(int256 expectedDeltaWei);
error GasBoundTooHigh(uint128 gasBoundWei, uint128 maxAllowedWei);
error CapsuleMismatch(bytes32 supplied, bytes32 active);
error StaleWindowNotReached(uint64 nowTs, uint64 cancelAt);
constructor(address admin) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(POLICY_ROLE, admin);
_grantRole(CLOCKKEEPER_ROLE, admin);
_grantRole(SETTLER_ROLE, admin);
_grantRole(GUARDIAN_ROLE, admin);
springConfig = SpringConfig({
minTickSpacing: 4,
staleAfter: 300,
maxTicksPerWind: 16,
maxGasValueWei: type(uint128).max
});
}
function setCapsule(bytes32 capsuleHash, uint64 version, bool proofRequired)
external onlyRole(POLICY_ROLE)
{
require(capsuleHash != bytes32(0), "capsule hash = 0");
capsule = PolicyCapsule(capsuleHash, version, proofRequired, true);
emit CapsuleSet(capsuleHash, version, proofRequired);
}
function configureSpring(
uint64 minTickSpacing, uint32 staleAfter,
uint16 maxTicksPerWind, uint128 maxGasValueWei
) external onlyRole(POLICY_ROLE) {
require(minTickSpacing > 0, "spacing=0");
require(maxTicksPerWind > 0, "ticks/wind=0");
springConfig = SpringConfig(minTickSpacing, staleAfter, maxTicksPerWind, maxGasValueWei);
emit SpringConfigured(minTickSpacing, staleAfter, maxTicksPerWind, maxGasValueWei);
}
function windSpring(uint16 energy) external onlyRole(CLOCKKEEPER_ROLE) whenNotPaused {
require(energy > 0, "energy=0");
require(energy <= springConfig.maxTicksPerWind, "energy too high");
if (!spring.windingOpen) {
spring.epoch += 1;
spring.windingOpen = true;
}
spring.remainingEnergy += energy;
emit SpringWound(spring.epoch, energy, spring.remainingEnergy);
}
function armTick(
bytes32 runId, bytes32 suppliedCapsuleHash,
bytes32 preStateHash, bytes32 quoteHash,
bytes32 routeHash, bytes32 proofHash,
int256 expectedDeltaWei, uint128 gasBoundWei
) external onlyRole(CLOCKKEEPER_ROLE) whenNotPaused returns (bytes32 cycleId) {
if (!capsule.active) revert NoActiveCapsule();
if (suppliedCapsuleHash != capsule.capsuleHash)
revert CapsuleMismatch(suppliedCapsuleHash, capsule.capsuleHash);
if (activeCycleId != bytes32(0)) revert LiveCycleExists(activeCycleId);
if (spring.remainingEnergy == 0) revert SpringNotWound();
if (expectedDeltaWei <= 0) revert NonPositiveExpectedDelta(expectedDeltaWei);
if (capsule.proofRequired && proofHash == bytes32(0)) revert ProofRequired();
if (gasBoundWei > springConfig.maxGasValueWei)
revert GasBoundTooHigh(gasBoundWei, springConfig.maxGasValueWei);
uint64 earliest = spring.lastReleaseAt + springConfig.minTickSpacing;
if (spring.lastReleaseAt != 0 && block.timestamp < earliest)
revert TickTooEarly(uint64(block.timestamp), earliest);
uint32 nextTick = spring.tick + 1;
cycleId = keccak256(abi.encodePacked(
block.chainid, address(this), spring.epoch, nextTick, runId, preStateHash, routeHash
));
Cycle storage c = cycles[cycleId];
c.cycleId = cycleId;
c.runId = runId;
c.tick = nextTick;
c.executor = msg.sender;
c.state = CycleState.Armed;
c.armedAt = uint64(block.timestamp);
c.capsuleHash = suppliedCapsuleHash;
c.preStateHash = preStateHash;
c.quoteHash = quoteHash;
c.routeHash = routeHash;
c.proofHash = proofHash;
c.expectedDeltaWei = expectedDeltaWei;
c.gasBoundWei = gasBoundWei;
activeCycleId = cycleId;
cycleIndex.push(cycleId);
emit TickArmed(cycleId, runId, nextTick, suppliedCapsuleHash, expectedDeltaWei, gasBoundWei);
}
function releaseTick(bytes32 cycleId, bytes32 execCommitment)
external onlyRole(CLOCKKEEPER_ROLE) whenNotPaused
{
if (activeCycleId == bytes32(0)) revert NoLiveCycle();
Cycle storage c = cycles[cycleId];
if (c.state != CycleState.Armed) revert InvalidState(CycleState.Armed, c.state);
c.state = CycleState.Executed;
c.executedAt = uint64(block.timestamp);
c.execCommitment = execCommitment;
spring.tick = c.tick;
spring.lastReleaseAt = uint64(block.timestamp);
spring.remainingEnergy -= 1;
if (spring.remainingEnergy == 0) spring.windingOpen = false;
emit TickReleased(cycleId, c.tick, msg.sender, execCommitment);
}
function settleCycle(
bytes32 cycleId, bytes32 receiptsHash, bytes32 postStateHash,
bytes32 reportHash, int256 realizedDeltaWei
) external onlyRole(SETTLER_ROLE) whenNotPaused nonReentrant {
if (activeCycleId == bytes32(0)) revert NoLiveCycle();
Cycle storage c = cycles[cycleId];
if (c.state != CycleState.Executed) revert InvalidState(CycleState.Executed, c.state);
c.state = CycleState.Settled;
c.settledAt = uint64(block.timestamp);
c.receiptsHash = receiptsHash;
c.postStateHash = postStateHash;
c.reportHash = reportHash;
c.realizedDeltaWei = realizedDeltaWei;
activeCycleId = bytes32(0);
emit CycleSettled(cycleId, c.tick, realizedDeltaWei, receiptsHash, postStateHash);
}
function cancelStaleCycle(bytes32 cycleId, string calldata reason)
external onlyRole(GUARDIAN_ROLE) whenNotPaused
{
if (activeCycleId == bytes32(0)) revert NoLiveCycle();
Cycle storage c = cycles[cycleId];
uint64 cancelAt = c.armedAt + springConfig.staleAfter;
if (block.timestamp < cancelAt)
revert StaleWindowNotReached(uint64(block.timestamp), cancelAt);
if (c.state != CycleState.Armed && c.state != CycleState.Executed)
revert InvalidState(CycleState.Armed, c.state);
c.state = CycleState.Cancelled;
activeCycleId = bytes32(0);
emit CycleCancelled(cycleId, c.tick, reason);
}
function canArmNextTick() external view returns (bool ok, string memory why) {
if (!capsule.active) return (false, "no active capsule");
if (activeCycleId != bytes32(0)) return (false, "live cycle exists");
if (spring.remainingEnergy == 0) return (false, "spring not wound");
uint64 earliest = spring.lastReleaseAt + springConfig.minTickSpacing;
if (spring.lastReleaseAt != 0 && block.timestamp < earliest)
return (false, "tick spacing not satisfied");
return (true, "ok");
}
function cycleCount() external view returns (uint256) { return cycleIndex.length; }
function pause() external onlyRole(GUARDIAN_ROLE) { _pause(); }
function unpause() external onlyRole(GUARDIAN_ROLE) { _unpause(); }
}
test/EulerCycleAttestor.t.sol