Files
smom-dbis-138/contracts/dex/PrivatePoolRegistry.sol
2026-03-02 12:14:09 -08:00

89 lines
3.4 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "@openzeppelin/contracts/access/AccessControl.sol";
/**
* @title PrivatePoolRegistry
* @notice Registry of private XAU-anchored stabilization pools (Master Plan Phase 2).
* @dev Only the Stabilizer (or whitelisted keeper) should execute swaps for rebalancing.
* Liquidity provision can be restricted via STABILIZER_LP_ROLE when enforced by a wrapper or runbook.
*/
contract PrivatePoolRegistry is AccessControl {
bytes32 public constant STABILIZER_LP_ROLE = keccak256("STABILIZER_LP_ROLE");
/// @dev Canonical key: (token0, token1) where token0 < token1
mapping(address => mapping(address => address)) private _pools;
event PrivatePoolRegistered(
address indexed tokenA,
address indexed tokenB,
address indexed pool
);
event PrivatePoolRemoved(
address indexed tokenA,
address indexed tokenB,
address indexed pool
);
constructor(address admin) {
require(admin != address(0), "PrivatePoolRegistry: zero admin");
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}
/**
* @notice Register a private pool for a token pair.
* @param tokenA First token (order used for storage; getPrivatePool is order-agnostic)
* @param tokenB Second token
* @param poolAddress DODO pool address (e.g. from DODOPMMIntegration.createPool)
*/
function register(
address tokenA,
address tokenB,
address poolAddress
) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(tokenA != address(0) && tokenB != address(0), "PrivatePoolRegistry: zero token");
require(poolAddress != address(0), "PrivatePoolRegistry: zero pool");
require(tokenA != tokenB, "PrivatePoolRegistry: same token");
(address t0, address t1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(_pools[t0][t1] == address(0), "PrivatePoolRegistry: pool already set");
_pools[t0][t1] = poolAddress;
emit PrivatePoolRegistered(tokenA, tokenB, poolAddress);
}
/**
* @notice Remove a private pool registration (e.g. migration).
*/
function unregister(address tokenA, address tokenB) external onlyRole(DEFAULT_ADMIN_ROLE) {
(address t0, address t1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
address pool = _pools[t0][t1];
require(pool != address(0), "PrivatePoolRegistry: not registered");
delete _pools[t0][t1];
emit PrivatePoolRemoved(tokenA, tokenB, pool);
}
/**
* @notice Get the private pool for a token pair (order-agnostic).
* @param tokenIn One of the pair
* @param tokenOut The other
* @return pool The registered pool address, or address(0) if none
*/
function getPrivatePool(address tokenIn, address tokenOut) external view returns (address pool) {
if (tokenIn == tokenOut) return address(0);
(address t0, address t1) = tokenIn < tokenOut ? (tokenIn, tokenOut) : (tokenOut, tokenIn);
return _pools[t0][t1];
}
/**
* @notice Check if an address is allowed to add liquidity (has STABILIZER_LP_ROLE).
* @dev Use in a wrapper or runbook; DODOPMMIntegration.addLiquidity does not check this.
*/
function isLpAllowed(address account) external view returns (bool) {
return hasRole(STABILIZER_LP_ROLE, account);
}
}