// SPDX-License-Identifier: MIT pragma solidity ^0.8.23; import "@openzeppelin/contracts/access/Ownable.sol"; /** * @title AereSolverRegistry * @notice Allowlist of solvers permitted to call AereSettlement.settle(). * * Phase 1 (current): owner-curated allowlist. Foundation adds vetted solvers. * Phase 2 (later): permissionless solver entry with bonded stake — anyone * can become a solver by posting an AERE bond; the bond is slashable for * misbehavior (settling at unfavorable clearing prices, censoring orders, * etc). Slashing logic deferred to Phase 2 audit. * * Mirror of CoW Protocol's GPv2AllowListAuthentication pattern. */ contract AereSolverRegistry is Ownable { mapping(address => bool) public isSolver; address[] public solvers; event SolverAdded(address indexed solver); event SolverRemoved(address indexed solver); function addSolver(address solver) external onlyOwner { require(solver != address(0), "Registry: zero address"); require(!isSolver[solver], "Registry: already a solver"); isSolver[solver] = true; solvers.push(solver); emit SolverAdded(solver); } function removeSolver(address solver) external onlyOwner { require(isSolver[solver], "Registry: not a solver"); isSolver[solver] = false; for (uint256 i = 0; i < solvers.length; i++) { if (solvers[i] == solver) { solvers[i] = solvers[solvers.length - 1]; solvers.pop(); break; } } emit SolverRemoved(solver); } function solverCount() external view returns (uint256) { return solvers.length; } }