forked from calvinheath/wheat-v1-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPancakeSwapBuyback.sol
157 lines (135 loc) · 6.18 KB
/
PancakeSwapBuyback.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.6.0;
import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import { IExchange } from "./IExchange.sol";
import { WhitelistGuard } from "./WhitelistGuard.sol";
import { Transfers } from "./modules/Transfers.sol";
contract PancakeSwapBuyback is ReentrancyGuard, WhitelistGuard
{
using SafeMath for uint256;
uint256 constant DEFAULT_REWARD_BUYBACK1_SHARE = 70e16; // 70%
uint256 constant DEFAULT_REWARD_BUYBACK2_SHARE = 15e16; // 15%
uint256 constant DEFAULT_REWARD_YIELD_SHARE = 15e16; // 15%
address constant public FURNACE = 0x000000000000000000000000000000000000dEaD;
address public immutable rewardToken;
address public immutable routingToken;
address public immutable buybackToken1;
address public immutable buybackToken2;
address public exchange;
address public treasury;
address public yield;
uint256 public rewardBuyback1Share = DEFAULT_REWARD_BUYBACK1_SHARE;
uint256 public rewardBuyback2Share = DEFAULT_REWARD_BUYBACK2_SHARE;
uint256 public rewardYieldShare = DEFAULT_REWARD_YIELD_SHARE;
uint256 public lastGulpTime;
constructor (address _rewardToken, address _routingToken, address _buybackToken1, address _buybackToken2,
address _treasury, address _yield, address _exchange) public
{
rewardToken = _rewardToken;
routingToken = _routingToken;
buybackToken1 = _buybackToken1;
buybackToken2 = _buybackToken2;
treasury = _treasury;
yield = _yield;
exchange = _exchange;
}
function pendingBuyback() external view returns (uint256 _buybackAmount)
{
return Transfers._getBalance(rewardToken);
}
function pendingBurning() external view returns (uint256 _burning1, uint256 _burning2)
{
require(exchange != address(0), "exchange not set");
uint256 _balance = Transfers._getBalance(rewardToken);
if (routingToken != rewardToken) {
_balance = IExchange(exchange).calcConversionFromInput(rewardToken, routingToken, _balance);
}
uint256 _amount1 = _balance.mul(rewardBuyback1Share) / 1e18;
uint256 _amount2 = _balance.mul(rewardBuyback2Share) / 1e18;
_burning1 = IExchange(exchange).calcConversionFromInput(routingToken, buybackToken1, _amount1);
uint256 _amount3 = IExchange(exchange).calcConversionFromInput(routingToken, buybackToken2, _amount2);
_burning2 = _amount3 / 2;
return (_burning1, _burning2);
}
function gulp(uint256 _minBurning1, uint256 _minBurning2) external onlyEOAorWhitelist nonReentrant
{
require(exchange != address(0), "exchange not set");
if (routingToken != rewardToken) {
uint256 _balance = Transfers._getBalance(rewardToken);
Transfers._approveFunds(rewardToken, exchange, _balance);
IExchange(exchange).convertFundsFromInput(rewardToken, routingToken, _balance, 1);
}
uint256 _balance = Transfers._getBalance(routingToken);
uint256 _amount1 = _balance.mul(rewardBuyback1Share) / 1e18;
uint256 _amount2 = _balance.mul(rewardBuyback2Share) / 1e18;
uint256 _burning = _amount1 + _amount2;
uint256 _sending = _balance - _burning;
Transfers._approveFunds(routingToken, exchange, _burning);
IExchange(exchange).convertFundsFromInput(routingToken, buybackToken1, _amount1, 1);
IExchange(exchange).convertFundsFromInput(routingToken, buybackToken2, _amount2, 1);
uint256 _burning1 = Transfers._getBalance(buybackToken1);
uint256 _amount3 = Transfers._getBalance(buybackToken2);
uint256 _burning2 = _amount3 / 2;
uint256 _sending2 = _amount3 - _burning2;
require(_burning1 >= _minBurning1, "high slippage");
require(_burning2 >= _minBurning2, "high slippage");
_burn(buybackToken1, _burning1);
_burn(buybackToken2, _burning2);
_send(buybackToken2, treasury, _sending2);
_send(routingToken, yield, _sending);
lastGulpTime = now;
}
function recoverLostFunds(address _token) external onlyOwner nonReentrant
{
require(_token != rewardToken, "invalid token");
uint256 _balance = Transfers._getBalance(_token);
Transfers._pushFunds(_token, treasury, _balance);
}
function setExchange(address _newExchange) external onlyOwner nonReentrant
{
address _oldExchange = exchange;
exchange = _newExchange;
emit ChangeExchange(_oldExchange, _newExchange);
}
function setTreasury(address _newTreasury) external onlyOwner nonReentrant
{
require(_newTreasury != address(0), "invalid address");
address _oldTreasury = treasury;
treasury = _newTreasury;
emit ChangeTreasury(_oldTreasury, _newTreasury);
}
function setYield(address _newYield) external onlyOwner nonReentrant
{
require(_newYield != address(0), "invalid address");
address _oldYield = yield;
yield = _newYield;
emit ChangeYield(_oldYield, _newYield);
}
function setRewardSplit(uint256 _newRewardBuyback1Share, uint256 _newRewardBuyback2Share, uint256 _newRewardYieldShare) external onlyOwner nonReentrant
{
require(_newRewardBuyback1Share <= 1e18, "invalid rate");
require(_newRewardBuyback2Share <= 1e18, "invalid rate");
require(_newRewardYieldShare <= 1e18, "invalid rate");
require(_newRewardBuyback1Share + _newRewardBuyback2Share + _newRewardYieldShare == 1e18, "invalid split");
uint256 _oldRewardBuyback1Share = rewardBuyback1Share;
uint256 _oldRewardBuyback2Share = rewardBuyback2Share;
uint256 _oldRewardYieldShare = rewardYieldShare;
rewardBuyback1Share = _newRewardBuyback1Share;
rewardBuyback2Share = _newRewardBuyback2Share;
rewardYieldShare = _newRewardYieldShare;
emit ChangeRewardSplit(_oldRewardBuyback1Share, _oldRewardBuyback2Share, _oldRewardYieldShare, _newRewardBuyback1Share, _newRewardBuyback2Share, _newRewardYieldShare);
}
function _burn(address _token, uint256 _amount) internal
{
Transfers._pushFunds(_token, FURNACE, _amount);
}
function _send(address _token, address _to, uint256 _amount) internal
{
Transfers._pushFunds(_token, _to, _amount);
}
event ChangeExchange(address _oldExchange, address _newExchange);
event ChangeTreasury(address _oldTreasury, address _newTreasury);
event ChangeYield(address _oldYield, address _newYield);
event ChangeRewardSplit(uint256 _oldRewardBuyback1Share, uint256 _oldRewardBuyback2Share, uint256 _oldRewardYieldShare, uint256 _newRewardBuyback1Share, uint256 _newRewardBuyback2Share, uint256 _newRewardYieldShare);
}