158 lines
4.6 KiB
Solidity
158 lines
4.6 KiB
Solidity
// 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;
|
|
|
|
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
constructor() {
|
|
_disableInitializers();
|
|
}
|
|
|
|
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).safeTransferFrom(account, address(this), _amount);
|
|
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).safeTransferFrom(account, ytVault, _amountIn);
|
|
|
|
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;
|
|
} |