// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import "./interfaces/ILotteryDependencies.sol"; /// @notice Checks membership in one immutable registry, not transaction-origin attestation. /// @dev The deployer must authenticate the registry and its issuer powers independently. /// A positive balance does not identify a unique human or the software used to send a transaction. contract AgentIdMembershipVerifier is IAgenticPurchaseVerifier { address public immutable registry; uint256 public immutable registryChainId; error InvalidConfig(); constructor(address registry_, uint256 chainId_) { if (registry_.code.length == 0 || chainId_ != block.chainid) revert InvalidConfig(); registry = registry_; registryChainId = chainId_; } function verify(Purchase calldata purchase, bytes calldata proof) external view returns (bool) { if (proof.length != 0 || block.chainid != registryChainId || purchase.chainId != registryChainId || purchase.round != msg.sender || purchase.buyer == address(0) || block.timestamp > purchase.deadline) return false; bytes memory callData = abi.encodeWithSelector(bytes4(0x70a08231), purchase.buyer); address target = registry; bool success; uint256 balanceValue; // Copy at most one ABI word. Empty, short and oversized responses all fail closed; // a malicious registry cannot force the caller to allocate its entire return buffer. assembly ("memory-safe") { mstore(0, 0) success := staticcall(gas(), target, add(callData, 32), mload(callData), 0, 32) if iszero(eq(returndatasize(), 32)) { success := 0 } balanceValue := mload(0) } return success && balanceValue > 0; } }