89 lines
3.4 KiB
Solidity
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);
|
|
}
|
|
}
|