Files
assetxContracts/contracts/ytLp/core/YTRewardRouter.sol

158 lines
4.6 KiB
Solidity
Raw Permalink Normal View History

2025-12-18 13:07:35 +08:00
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../../interfaces/IYTPoolManager.sol";
import "../../interfaces/IYTVault.sol";
contract YTRewardRouter is Initializable, UUPSUpgradeable, ReentrancyGuardUpgradeable, PausableUpgradeable {
using SafeERC20 for IERC20;
2025-12-23 14:05:41 +08:00
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
2025-12-18 13:07:35 +08:00
error Forbidden();
error AlreadyInitialized();
error InvalidAddress();
error InvalidAmount();
error InsufficientOutput();
address public gov;
address public usdy;
address public ytLP;
address public ytPoolManager;
address public ytVault;
event Swap(
address indexed account,
address tokenIn,
address tokenOut,
uint256 amountIn,
uint256 amountOut
);
modifier onlyGov() {
if (msg.sender != gov) revert Forbidden();
_;
}
function initialize(
address _usdy,
address _ytLP,
address _ytPoolManager,
address _ytVault
) external initializer {
if (_usdy == address(0)) revert InvalidAddress();
if (_ytLP == address(0)) revert InvalidAddress();
if (_ytPoolManager == address(0)) revert InvalidAddress();
if (_ytVault == address(0)) revert InvalidAddress();
__ReentrancyGuard_init();
__UUPSUpgradeable_init();
__Pausable_init();
gov = msg.sender;
usdy = _usdy;
ytLP = _ytLP;
ytPoolManager = _ytPoolManager;
ytVault = _ytVault;
}
function _authorizeUpgrade(address newImplementation) internal override onlyGov {}
function pause() external onlyGov {
_pause();
}
function unpause() external onlyGov {
_unpause();
}
function addLiquidity(
address _token,
uint256 _amount,
uint256 _minUsdy,
uint256 _minYtLP
) external nonReentrant whenNotPaused returns (uint256) {
if (_amount == 0) revert InvalidAmount();
address account = msg.sender;
IERC20(_token).transferFrom(account, address(this), _amount);
2025-12-18 13:07:35 +08:00
IERC20(_token).approve(ytPoolManager, _amount);
uint256 ytLPAmount = IYTPoolManager(ytPoolManager).addLiquidityForAccount(
address(this),
account,
_token,
_amount,
_minUsdy,
_minYtLP
);
return ytLPAmount;
}
function removeLiquidity(
address _tokenOut,
uint256 _ytLPAmount,
uint256 _minOut,
address _receiver
) external nonReentrant whenNotPaused returns (uint256) {
if (_ytLPAmount == 0) revert InvalidAmount();
address account = msg.sender;
uint256 amountOut = IYTPoolManager(ytPoolManager).removeLiquidityForAccount(
account,
_tokenOut,
_ytLPAmount,
_minOut,
_receiver
);
return amountOut;
}
function swapYT(
address _tokenIn,
address _tokenOut,
uint256 _amountIn,
uint256 _minOut,
address _receiver
) external nonReentrant whenNotPaused returns (uint256) {
if (_amountIn == 0) revert InvalidAmount();
address account = msg.sender;
IERC20(_tokenIn).transferFrom(account, ytVault, _amountIn);
2025-12-18 13:07:35 +08:00
uint256 amountOut = IYTVault(ytVault).swap(_tokenIn, _tokenOut, _receiver);
if (amountOut < _minOut) revert InsufficientOutput();
emit Swap(account, _tokenIn, _tokenOut, _amountIn, amountOut);
return amountOut;
}
function getYtLPPrice() external view returns (uint256) {
return IYTPoolManager(ytPoolManager).getPrice(true);
}
function getAccountValue(address _account) external view returns (uint256) {
uint256 ytLPBalance = IERC20(ytLP).balanceOf(_account);
uint256 ytLPPrice = IYTPoolManager(ytPoolManager).getPrice(true);
return ytLPBalance * ytLPPrice / (10 ** 18);
}
uint256[50] private __gap;
2025-12-25 13:29:35 +08:00
}