chore: sync submodule state (parent ref update)
Made-with: Cursor
This commit is contained in:
@@ -5,6 +5,7 @@ import "@openzeppelin/contracts/access/AccessControl.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
|
||||
import "../reserve/IReserveSystem.sol";
|
||||
|
||||
/**
|
||||
* @title DODO PMM Pool Interface
|
||||
@@ -83,6 +84,9 @@ contract DODOPMMIntegration is AccessControl, ReentrancyGuard {
|
||||
mapping(address => PoolConfig) public poolConfigs;
|
||||
address[] public allPools;
|
||||
|
||||
/// @notice Optional ReserveSystem for oracle-backed mid price (base/quote in reserve system)
|
||||
IReserveSystem public reserveSystem;
|
||||
|
||||
event PoolCreated(
|
||||
address indexed pool,
|
||||
address indexed baseToken,
|
||||
@@ -105,6 +109,7 @@ contract DODOPMMIntegration is AccessControl, ReentrancyGuard {
|
||||
address trader
|
||||
);
|
||||
event PoolRemoved(address indexed pool);
|
||||
event ReserveSystemSet(address indexed reserveSystem);
|
||||
|
||||
constructor(
|
||||
address admin,
|
||||
@@ -222,6 +227,99 @@ contract DODOPMMIntegration is AccessControl, ReentrancyGuard {
|
||||
emit PoolCreated(pool, compliantUSDC, officialUSDC, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Create DODO PMM pool for cUSDT/cUSDC pair (public liquidity per VAULT_SYSTEM_MASTER_TECHNICAL_PLAN §4)
|
||||
* @param lpFeeRate Liquidity provider fee rate (basis points, 3 = 0.03%)
|
||||
* @param initialPrice Initial price (1e18 = $1 for stablecoin pairs)
|
||||
* @param k Slippage factor (0.5e18 = 50%, lower = less slippage)
|
||||
* @param isOpenTWAP Enable TWAP oracle for price discovery
|
||||
*/
|
||||
function createCUSDTCUSDCPool(
|
||||
uint256 lpFeeRate,
|
||||
uint256 initialPrice,
|
||||
uint256 k,
|
||||
bool isOpenTWAP
|
||||
) external onlyRole(POOL_MANAGER_ROLE) returns (address pool) {
|
||||
require(pools[compliantUSDT][compliantUSDC] == address(0), "DODOPMMIntegration: pool exists");
|
||||
|
||||
pool = IDODOVendingMachine(dodoVendingMachine).createDVM(
|
||||
compliantUSDT, // baseToken (cUSDT)
|
||||
compliantUSDC, // quoteToken (cUSDC)
|
||||
lpFeeRate,
|
||||
initialPrice,
|
||||
k,
|
||||
isOpenTWAP
|
||||
);
|
||||
|
||||
pools[compliantUSDT][compliantUSDC] = pool;
|
||||
pools[compliantUSDC][compliantUSDT] = pool;
|
||||
isRegisteredPool[pool] = true;
|
||||
allPools.push(pool);
|
||||
|
||||
poolConfigs[pool] = PoolConfig({
|
||||
pool: pool,
|
||||
baseToken: compliantUSDT,
|
||||
quoteToken: compliantUSDC,
|
||||
lpFeeRate: lpFeeRate,
|
||||
i: initialPrice,
|
||||
k: k,
|
||||
isOpenTWAP: isOpenTWAP,
|
||||
createdAt: block.timestamp
|
||||
});
|
||||
|
||||
emit PoolCreated(pool, compliantUSDT, compliantUSDC, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Create DODO PMM pool for any base/quote token pair (generic)
|
||||
* @param baseToken Base token address
|
||||
* @param quoteToken Quote token address
|
||||
* @param lpFeeRate Liquidity provider fee rate (basis points, 3 = 0.03%)
|
||||
* @param initialPrice Initial price (1e18 = $1 for stablecoins)
|
||||
* @param k Slippage factor (0.5e18 = 50%, lower = less slippage)
|
||||
* @param isOpenTWAP Enable TWAP oracle for price discovery
|
||||
*/
|
||||
function createPool(
|
||||
address baseToken,
|
||||
address quoteToken,
|
||||
uint256 lpFeeRate,
|
||||
uint256 initialPrice,
|
||||
uint256 k,
|
||||
bool isOpenTWAP
|
||||
) external onlyRole(POOL_MANAGER_ROLE) returns (address pool) {
|
||||
require(baseToken != address(0), "DODOPMMIntegration: zero base");
|
||||
require(quoteToken != address(0), "DODOPMMIntegration: zero quote");
|
||||
require(baseToken != quoteToken, "DODOPMMIntegration: same token");
|
||||
require(pools[baseToken][quoteToken] == address(0), "DODOPMMIntegration: pool exists");
|
||||
|
||||
pool = IDODOVendingMachine(dodoVendingMachine).createDVM(
|
||||
baseToken,
|
||||
quoteToken,
|
||||
lpFeeRate,
|
||||
initialPrice,
|
||||
k,
|
||||
isOpenTWAP
|
||||
);
|
||||
|
||||
pools[baseToken][quoteToken] = pool;
|
||||
pools[quoteToken][baseToken] = pool;
|
||||
isRegisteredPool[pool] = true;
|
||||
allPools.push(pool);
|
||||
|
||||
poolConfigs[pool] = PoolConfig({
|
||||
pool: pool,
|
||||
baseToken: baseToken,
|
||||
quoteToken: quoteToken,
|
||||
lpFeeRate: lpFeeRate,
|
||||
i: initialPrice,
|
||||
k: k,
|
||||
isOpenTWAP: isOpenTWAP,
|
||||
createdAt: block.timestamp
|
||||
});
|
||||
|
||||
emit PoolCreated(pool, baseToken, quoteToken, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Add liquidity to a DODO PMM pool
|
||||
* @param pool Pool address
|
||||
@@ -347,7 +445,70 @@ contract DODOPMMIntegration is AccessControl, ReentrancyGuard {
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Get current pool price
|
||||
* @notice Swap cUSDT for cUSDC via cUSDT/cUSDC DODO PMM pool (public liquidity pair per Master Plan §4)
|
||||
*/
|
||||
function swapCUSDTForUSDC(
|
||||
address pool,
|
||||
uint256 amountIn,
|
||||
uint256 minAmountOut
|
||||
) external nonReentrant returns (uint256 amountOut) {
|
||||
require(isRegisteredPool[pool], "DODOPMMIntegration: pool not registered");
|
||||
require(poolConfigs[pool].baseToken == compliantUSDT && poolConfigs[pool].quoteToken == compliantUSDC, "DODOPMMIntegration: invalid pool");
|
||||
require(amountIn > 0, "DODOPMMIntegration: zero amount");
|
||||
|
||||
IERC20(compliantUSDT).safeTransferFrom(msg.sender, pool, amountIn);
|
||||
amountOut = IDODOPMMPool(pool).sellBase(amountIn);
|
||||
require(amountOut >= minAmountOut, "DODOPMMIntegration: insufficient output");
|
||||
IERC20(compliantUSDC).safeTransfer(msg.sender, amountOut);
|
||||
emit SwapExecuted(pool, compliantUSDT, compliantUSDC, amountIn, amountOut, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Swap cUSDC for cUSDT via cUSDT/cUSDC DODO PMM pool
|
||||
*/
|
||||
function swapUSDCForCUSDT(
|
||||
address pool,
|
||||
uint256 amountIn,
|
||||
uint256 minAmountOut
|
||||
) external nonReentrant returns (uint256 amountOut) {
|
||||
require(isRegisteredPool[pool], "DODOPMMIntegration: pool not registered");
|
||||
require(poolConfigs[pool].baseToken == compliantUSDT && poolConfigs[pool].quoteToken == compliantUSDC, "DODOPMMIntegration: invalid pool");
|
||||
require(amountIn > 0, "DODOPMMIntegration: zero amount");
|
||||
|
||||
IERC20(compliantUSDC).safeTransferFrom(msg.sender, pool, amountIn);
|
||||
amountOut = IDODOPMMPool(pool).sellQuote(amountIn);
|
||||
require(amountOut >= minAmountOut, "DODOPMMIntegration: insufficient output");
|
||||
IERC20(compliantUSDT).safeTransfer(msg.sender, amountOut);
|
||||
emit SwapExecuted(pool, compliantUSDC, compliantUSDT, amountIn, amountOut, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Set optional ReserveSystem for oracle-backed mid price
|
||||
* @param reserveSystem_ ReserveSystem address (address(0) to disable)
|
||||
*/
|
||||
function setReserveSystem(address reserveSystem_) external onlyRole(DEFAULT_ADMIN_ROLE) {
|
||||
reserveSystem = IReserveSystem(reserveSystem_);
|
||||
emit ReserveSystemSet(reserveSystem_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Get pool price: oracle (ReserveSystem) if configured and available, else pool getMidPrice()
|
||||
* @param pool Pool address
|
||||
* @return price Price in 18 decimals (quote per base; 1e18 = $1 for stablecoins)
|
||||
*/
|
||||
function getPoolPriceOrOracle(address pool) public view returns (uint256 price) {
|
||||
require(isRegisteredPool[pool], "DODOPMMIntegration: pool not registered");
|
||||
if (address(reserveSystem) != address(0)) {
|
||||
PoolConfig memory config = poolConfigs[pool];
|
||||
try reserveSystem.getConversionPrice(config.baseToken, config.quoteToken) returns (uint256 oraclePrice) {
|
||||
if (oraclePrice > 0) return oraclePrice;
|
||||
} catch { }
|
||||
}
|
||||
return IDODOPMMPool(pool).getMidPrice();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Get current pool price (pool mid only; use getPoolPriceOrOracle for oracle-backed price)
|
||||
* @param pool Pool address
|
||||
* @return price Current mid price (1e18 = $1 for stablecoins)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user