{"sources":{"src/ClausComputeFeeProgram.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\nimport {IProgram, ProgramTypes} from \"./IClausTradeProgram.sol\";\n\ninterface IComputeClaims {\n    function balanceOf(address owner, uint256 id) external view returns (uint256);\n    function unlock(bytes calldata data) external returns (bytes memory);\n    function burn(address from, uint256 id, uint256 amount) external;\n    function take(address currency, address to, uint256 amount) external;\n}\n\n/// @notice Allocates 0.1 percentage point FROM the existing 1.3% owner share.\n/// @dev Installed as a fixed module, the sealed hook mints the module's claims\n/// directly here. The fixed 2.3% aggregate rate and other allocations do not rise.\n/// The public claim interface matches the prepared funding runner. Every claim\n/// goes to the existing fixed operator wallet; there is no caller-set recipient.\ncontract ClausComputeFeeProgram is IProgram {\n    address public constant MANAGER = 0x000000000004444c5dc75cB358380D2e3dE08A90;\n    address public immutable active;\n    constructor(address beneficiary) { if(beneficiary==address(0)) revert InvalidClaim(); active=beneficiary; }\n    uint256 public constant COMPUTE_PIPS = 1_000;\n    uint256 public constant DIRECT_OWNER_PIPS = 12_000;\n    uint256 public constant TOTAL_OWNER_PIPS = DIRECT_OWNER_PIPS + COMPUTE_PIPS;\n    uint256 public constant TOTAL_PIPS = 23_000;\n\n    uint256 public totalClaimed;\n    uint256 private claiming;\n    uint256 private constant CALLBACK_CONSUMED = type(uint256).max;\n\n    error InvalidClaim();\n    error InvalidCallback();\n    event ComputeFundingClaimed(address indexed recipient, uint256 amount);\n\n    function quote(address, bool, int256, uint160, uint128, bytes calldata)\n        external pure returns (uint256[6] memory)\n    {\n        // Treasury, platform, buyback, staked LP, staked NFT, compute.\n        return [DIRECT_OWNER_PIPS, 3_000, 1_500, 2_000, 3_500, COMPUTE_PIPS];\n    }\n\n    /// @dev The fixed host authenticates and consumes its receipts. This\n    /// callback is deliberately side-effect-free: receipt delivery cannot depend\n    /// on a provider, bridge, oracle, ETH recipient or funding worker being up.\n    function onTrade(ProgramTypes.Trade calldata, bytes calldata)\n        external pure returns (bytes4)\n    {\n        return IProgram.onTrade.selector;\n    }\n\n    function balances() external view returns (uint256 activeAmount, uint256 treasuryAmount) {\n        return (IComputeClaims(MANAGER).balanceOf(address(this), 0), 0);\n    }\n\n    /// @notice Redeem only this program's already received ETH claims.\n    /// Anyone may trigger a batch, always to the same fixed operator account.\n    function claimActive(uint256 amount) external {\n        if (claiming != 0 || amount == 0 || amount == CALLBACK_CONSUMED\n            || amount > IComputeClaims(MANAGER).balanceOf(address(this), 0)) revert InvalidClaim();\n        claiming = amount;\n        IComputeClaims(MANAGER).unlock(abi.encode(amount));\n        claiming = 0;\n        totalClaimed += amount;\n        emit ComputeFundingClaimed(active, amount);\n    }\n\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        if (msg.sender != MANAGER || claiming == 0 || claiming == CALLBACK_CONSUMED || data.length != 32) revert InvalidCallback();\n        uint256 amount = abi.decode(data, (uint256));\n        if (amount != claiming) revert InvalidCallback();\n        // Retain the outer lock while preventing a second callback.\n        claiming = CALLBACK_CONSUMED;\n        IComputeClaims(MANAGER).burn(address(this), 0, amount);\n        IComputeClaims(MANAGER).take(address(0), active, amount);\n        return \"\";\n    }\n}\n\n"},"src/ClausGovernance.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\nimport {ComputeProtectedProgram} from \"./ComputeProtectedProgram.sol\";\nimport {ClausComputeFeeProgram} from \"./ClausComputeFeeProgram.sol\";\n\ninterface IClausToken {\n    function owner() external view returns (address);\n    function pendingOwner() external view returns (address);\n    function acceptOwnership() external;\n    function transferOwnership(address) external;\n    function updateMetadata(string calldata, string calldata, string calldata) external;\n}\ninterface IClausHost {\n    function setModule(address) external;\n}\n\n/// @notice Separates ecosystem administration from the founder's personal key.\n/// @dev No arbitrary call, delegatecall, approval, transfer or signature entrypoint.\n/// Program logic is unrestricted; the existing personal/compute fee boundary\n/// is applied by the factory-created adapter, outside that program.\ncontract ClausGovernance {\n    address public constant TOKEN = 0x1b54E762aa34CF6E28E9C082F2848e28E45DA6b8;\n    address public constant HOST = 0xea0436465676eA7001535Bfe2E5cbd4b137b7f91;\n    address public constant FOUNDER = 0xBb145cA83272c3806D4dDc75cA1D5514789cF1C5;\n    address public immutable compute;\n    address public operator;\n    mapping(address => bool) public approvedAdapter;\n    mapping(address => address) public adapterFor;\n    event OperatorChanged(address indexed previous, address indexed current);\n    event AdapterCreated(address indexed program, address indexed adapter);\n    error Unauthorized();\n    error InvalidAddress();\n\n    constructor(address initialOperator) {\n        if (initialOperator == address(0) || initialOperator == FOUNDER ||\n            initialOperator == TOKEN || initialOperator == HOST) revert InvalidAddress();\n        operator = initialOperator;\n        compute = address(new ClausComputeFeeProgram(initialOperator));\n    }\n    modifier onlyOperator() {\n        if (msg.sender != operator) revert Unauthorized();\n        _;\n    }\n    /// The founder can revoke a compromised operating signer without giving\n    /// any autonomous signer access to the founder's funds.\n    function setOperator(address next) external {\n        if (msg.sender != FOUNDER) revert Unauthorized();\n        if (next == address(0) || next == FOUNDER || next == address(this) ||\n            next == TOKEN || next == HOST) revert InvalidAddress();\n        emit OperatorChanged(operator, next);\n        operator = next;\n    }\n    function acceptControl() external {\n        if (msg.sender != FOUNDER && msg.sender != operator) revert Unauthorized();\n        if (IClausToken(TOKEN).pendingOwner() != address(this)) revert Unauthorized();\n        IClausToken(TOKEN).acceptOwnership();\n    }\n    /// Optional founder recovery is a two-step ownership transfer. An\n    /// operating signer cannot rename its authority or redirect ownership.\n    function returnControl() external {\n        if (msg.sender != FOUNDER) revert Unauthorized();\n        IClausToken(TOKEN).transferOwnership(FOUNDER);\n    }\n    function createAdapter(address program) external returns (address adapter) {\n        adapter = adapterFor[program];\n        if (adapter != address(0)) return adapter;\n        if (program == compute || program == address(this) ||\n            approvedAdapter[program]) revert InvalidAddress();\n        adapter = address(new ComputeProtectedProgram(program, program.codehash, compute));\n        approvedAdapter[adapter] = true;\n        adapterFor[program] = adapter;\n        emit AdapterCreated(program, adapter);\n    }\n    function setModule(address module) external onlyOperator {\n        // The fallback preserves the personal share and operating revenue.\n        if (module != compute && !approvedAdapter[module]) revert InvalidAddress();\n        IClausHost(HOST).setModule(module);\n    }\n    function updateMetadata(string calldata name, string calldata symbol, string calldata uri)\n        external onlyOperator\n    {\n        IClausToken(TOKEN).updateMetadata(name, symbol, uri);\n    }\n}\n"},"src/ComputeProtectedProgram.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\ninterface IProgramManager { function transfer(address to,uint256 id,uint256 amount) external returns(bool); }\nimport {IProgram, ProgramTypes} from \"./IClausTradeProgram.sol\";\ninterface IReceiptHost { function pending(uint256) external view returns(bytes32); }\n\n/// @notice Fixed allocation boundary for Claus' reviewed program lane.\n/// @dev Installed only through the fixed governance factory. The personal\n/// fee recipient and its 1.2% allocation remain outside program authority.\ncontract ComputeProtectedProgram is IProgram {\n    address public constant HOST=0xea0436465676eA7001535Bfe2E5cbd4b137b7f91;\n    address public constant MANAGER=0x000000000004444c5dc75cB358380D2e3dE08A90;\n    address public immutable COMPUTE;\n    uint256 public constant TREASURY_PIPS=12_000;\n    uint256 public constant COMPUTE_PIPS=1_000;\n    uint256 public constant MAX_PLAN_PIPS=149_000;\n    address public immutable program;\n    bytes32 public immutable programCodeHash;\n    mapping(uint256=>bool) public computeSettled;\n    error InvalidProgram(); error InvalidReceipt();\n    event ComputeSettled(uint256 indexed receiptId,uint256 amount);\n\n    constructor(address target,bytes32 codeHash,address compute) {\n        if(compute.code.length==0) revert InvalidProgram();\n        COMPUTE=compute;\n        if(target==address(0)||target==HOST||target==MANAGER||target==compute||target==address(this)\n            ||target.code.length==0||target.codehash!=codeHash) revert InvalidProgram();\n        program=target; programCodeHash=codeHash;\n    }\n    function defaults() private pure returns(uint256[6] memory) {\n        return [TREASURY_PIPS,3_000,1_500,2_000,3_500,COMPUTE_PIPS];\n    }\n    function quote(address sender,bool buy,int256 amountSpecified,uint160 price,uint128 liquidity,bytes calldata data)\n        external view returns(uint256[6] memory a)\n    {\n        if(program.codehash!=programCodeHash) return defaults();\n        bytes memory input=abi.encodeCall(IProgram.quote,(sender,buy,amountSpecified,price,liquidity,data));\n        address target=program; bool ok;\n        assembly(\"memory-safe\") {\n            ok:=staticcall(50000,target,add(input,32),mload(input),a,192)\n            ok:=and(ok,eq(returndatasize(),192))\n        }\n        if(!ok) return defaults();\n        a[0]=TREASURY_PIPS;\n        uint256 sum=TREASURY_PIPS;\n        for(uint256 i=1;i<6;i++) {\n            if(a[i]>MAX_PLAN_PIPS) return defaults();\n            sum+=a[i];\n        }\n        if(sum+COMPUTE_PIPS>MAX_PLAN_PIPS) return defaults();\n        // Compute replaces one tenth of a percentage point of the old owner\n        // share. An inner program's own allocation remains available to it.\n        a[5]+=COMPUTE_PIPS;\n    }\n    function computeAmount(ProgramTypes.Trade calldata trade) public pure returns(uint256 amount) {\n        if((trade.buy&&trade.amount0>0)||(!trade.buy&&trade.amount0<0)) revert InvalidReceipt();\n        // The core records pool deltas before hook fees: buy gross is the ETH\n        // spent by the pool plus the fee, sell gross is the pool's ETH output.\n        uint256 gross=trade.buy?uint256(-int256(trade.amount0))+trade.feeEth:uint256(int256(trade.amount0));\n        amount=gross*COMPUTE_PIPS/1_000_000;\n        if(amount>trade.moduleFeeEth) revert InvalidReceipt();\n    }\n    /// @notice Settle compute even when the inner program cannot execute.\n    /// Anyone may submit an original pending receipt, once, to a fixed collector.\n    function settleCompute(ProgramTypes.Trade calldata trade) public {\n        if(trade.module!=address(this)) revert InvalidReceipt();\n        if(msg.sender!=HOST&&IReceiptHost(HOST).pending(trade.id)!=keccak256(abi.encode(trade))) revert InvalidReceipt();\n        if(computeSettled[trade.id]) return;\n        uint256 amount=computeAmount(trade);\n        computeSettled[trade.id]=true;\n        if(amount!=0&&!IProgramManager(MANAGER).transfer(COMPUTE,0,amount)) revert InvalidReceipt();\n        emit ComputeSettled(trade.id,amount);\n    }\n    function onTrade(ProgramTypes.Trade calldata trade,bytes calldata data) external returns(bytes4) {\n        if(msg.sender!=HOST||trade.module!=address(this)||program.codehash!=programCodeHash) revert InvalidReceipt();\n        settleCompute(trade);\n        uint256 programFee=trade.moduleFeeEth-computeAmount(trade);\n        if(programFee!=0&&!IProgramManager(MANAGER).transfer(program,0,programFee)) revert InvalidReceipt();\n        ProgramTypes.Trade memory inner=trade;\n        inner.moduleFeeEth=programFee;\n        if(IProgram(program).onTrade(inner,data)!=IProgram.onTrade.selector) revert InvalidReceipt();\n        return IProgram.onTrade.selector;\n    }\n}\n"},"src/IClausTradeProgram.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\nlibrary ProgramTypes {\n    struct Trade {\n        uint256 id; address module; address sender; bool buy;\n        int128 amount0; int128 amount1; uint256 feeEth;\n        uint256 moduleFeeEth; uint256 blockNumber; uint256 timestamp; bytes32 dataHash;\n    }\n}\ninterface IProgram {\n    function quote(address, bool, int256, uint160, uint128, bytes calldata)\n        external view returns (uint256[6] memory);\n    function onTrade(ProgramTypes.Trade calldata, bytes calldata) external returns (bytes4);\n}\n"}},"matchId":"56615148","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-10-20T17:03:05Z","match":"exact_match","chainId":"1","address":"0x180eAE784dEe739FBab432B06f78bF9a98Aae334"}