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

221 lines
6.3 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";
/**
* @title YTRewardRouter
* @notice
* @dev UUPS可升级合约
*/
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();
_;
}
/**
* @notice
* @param _usdy USDY代币地址
* @param _ytLP ytLP代币地址
* @param _ytPoolManager YTPoolManager地址
* @param _ytVault YTVault地址
*/
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;
}
/**
* @notice gov可调用
* @param newImplementation
*/
function _authorizeUpgrade(address newImplementation) internal override onlyGov {}
/**
* @notice gov可调用
* @dev
*/
function pause() external onlyGov {
_pause();
}
/**
* @notice gov可调用
*/
function unpause() external onlyGov {
_unpause();
}
/**
* @notice
2025-12-24 16:41:26 +08:00
* @param _token YT代币或USDC地址
2025-12-18 13:07:35 +08:00
* @param _amount
* @param _minUsdy USDY数量
* @param _minYtLP ytLP数量
* @return ytLPAmount ytLP数量
*/
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;
}
/**
* @notice
* @param _tokenOut
* @param _ytLPAmount ytLP数量
* @param _minOut
* @param _receiver
* @return amountOut
*/
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;
}
/**
* @notice YT代币互换
* @param _tokenIn
* @param _tokenOut
* @param _amountIn
* @param _minOut
* @param _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;
}
/**
* @notice ytLP价格
* @return ytLP价格18
*/
function getYtLPPrice() external view returns (uint256) {
return IYTPoolManager(ytPoolManager).getPrice(true);
}
/**
* @notice
* @param _account
* @return ytLP价值USDY计价
*/
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);
}
/**
* @dev
* 50slot = 50 * 32 bytes = 1600 bytes
*/
uint256[50] private __gap;
}