pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract DBKExchangeVault is ReentrancyGuard {
address public immutable dbkToken;
address public immutable usdcToken;
AggregatorV3Interface public immutable usdOracle;
AggregatorV3Interface public immutable usdcUsdOracle;
uint256 public constant PEG_PRICE = 1e18;
uint256 public constant MAX_DRIFT = 1e16;
uint256 public feeBasisPoints = 100;
event SwapExecuted(address indexed user, uint256 inputAmount, uint256 dbkReceived, uint256 fee);
event SwapFailed(address indexed user, uint256 inputAmount, string reason);
constructor(
address _dbkToken,
address _usdcToken,
address _usdOracle,
address _usdcUsdOracle
) {
dbkToken = _dbkToken;
usdcToken = _usdcToken;
usdOracle = AggregatorV3Interface(_usdOracle);
usdcUsdOracle = AggregatorV3Interface(_usdcUsdOracle);
}
function swapForDBK(uint256 inputAmount) external nonReentrant {
require(inputAmount > 0, "Input must be positive");
IERC20(usdcToken).transferFrom(msg.sender, address(this), inputAmount);
(, int256 usdcUsdPrice, , , ) = usdcUsdOracle.latestRoundData();
require(usdcUsdPrice > 0, "Invalid oracle price");
uint256 inputUsdValue = (inputAmount * uint256(usdcUsdPrice)) / 1e18;
(, int256 dbkUsdPrice, , , ) = usdOracle.latestRoundData();
require(dbkUsdPrice > 0, "Invalid DBK oracle");
uint256 expectedDbkUsd = (inputUsdValue * uint256(dbkUsdPrice)) / 1e18;
uint256 pegCheck = uint256(dbkUsdPrice) * 1e18;
require(pegCheck >= PEG_PRICE - MAX_DRIFT && pegCheck <= PEG_PRICE + MAX_DRIFT, "Peg deviation: Transaction invalid");
uint256 feeUsd = (inputUsdValue * feeBasisPoints) / 10000;
uint256 dbkAmount = inputUsdValue - feeUsd;
require(IERC20(dbkToken).transfer(msg.sender, dbkAmount), "DBK transfer failed");
emit SwapExecuted(msg.sender, inputAmount, dbkAmount, feeUsd);
}
function setFee(uint256 _feeBasisPoints) external {
require(_feeBasisPoints <= 500, "Fee too high");
feeBasisPoints = _feeBasisPoints;
}
receive() external payable {
revert("Unsupported: Use swapForDBK for pegged pairs only");
}
}