/
Treasury.sol
83 lines (70 loc) · 3.28 KB
/
Treasury.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/access/Ownable.sol";
import "./../interfaces/IERC20Detailed.sol";
import "./../interfaces/ITreasuryOperated.sol";
import "./../interfaces/IRewardsPoolBase.sol";
import "./../SafeERC20Detailed.sol";
import "./../interfaces/IUniswapV2Router.sol";
contract Treasury is Ownable {
using SafeMath for uint256;
using SafeERC20Detailed for IERC20Detailed;
address public externalRewardToken;
mapping(address => uint256) public liquidityDrawn;
IUniswapV2Router public uniswapRouter;
constructor(address _uniswapRouter, address _externalRewardToken) public {
require(_uniswapRouter != address(0x0), "Treasury:: Uniswap router cannot be 0");
require(_externalRewardToken != address(0x0), "Treasury:: External reward token not set");
uniswapRouter = IUniswapV2Router(_uniswapRouter);
externalRewardToken = _externalRewardToken;
}
function withdrawLiquidity(address[] calldata rewardPools, uint256[] calldata amounts) public onlyOwner {
require(rewardPools.length == amounts.length, "withdrawLiquidity:: pools and amounts do not match");
for (uint256 i = 0; i < rewardPools.length; i++) {
liquidityDrawn[rewardPools[i]] = liquidityDrawn[rewardPools[i]].add(amounts[i]);
ITreasuryOperated(rewardPools[i]).withdrawStake(amounts[i]);
}
}
function returnLiquidity(address[] calldata rewardPools, uint[] calldata externalRewards) public onlyOwner {
require(rewardPools.length == externalRewards.length, "returnLiquidity:: pools and external tokens do not match");
for (uint256 i = 0; i < rewardPools.length; i++) {
address stakingToken = IRewardsPoolBase(rewardPools[i]).stakingToken();
IERC20Detailed(stakingToken).safeTransfer(rewardPools[i], liquidityDrawn[rewardPools[i]]);
liquidityDrawn[rewardPools[i]] = 0;
if(externalRewards[i] == 0) {
continue;
}
IERC20Detailed(externalRewardToken).safeApprove(rewardPools[i], externalRewards[i]);
ITreasuryOperated(rewardPools[i]).notifyExternalReward(externalRewards[i]);
}
}
function addUniswapLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
uint256 deadline
) external onlyOwner returns (uint256 amountA, uint256 amountB, uint256 liquidity) {
IERC20Detailed(tokenA).safeApprove(address(uniswapRouter), amountADesired);
IERC20Detailed(tokenB).safeApprove(address(uniswapRouter), amountBDesired);
return uniswapRouter.addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin, address(this), deadline);
}
function removeUniswapLiquidity(
address tokenA,
address tokenB,
address lpToken,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
uint256 deadline
) external onlyOwner returns (uint256 amountA, uint256 amountB) {
IERC20Detailed(lpToken).safeApprove(address(uniswapRouter), liquidity);
return uniswapRouter.removeLiquidity(tokenA, tokenB, liquidity, amountAMin, amountBMin, address(this), deadline);
}
function withdrawToken(address token, uint256 amount) external onlyOwner {
IERC20Detailed(token).safeTransfer(msg.sender, amount);
}
}