-
Notifications
You must be signed in to change notification settings - Fork 49
/
YieldSourcePrizePool.sol
104 lines (86 loc) · 4.29 KB
/
YieldSourcePrizePool.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
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.6;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@pooltogether/yield-source-interface/contracts/IYieldSource.sol";
import "./PrizePool.sol";
/**
* @title PoolTogether V4 YieldSourcePrizePool
* @author PoolTogether Inc Team
* @notice The Yield Source Prize Pool uses a yield source contract to generate prizes.
* Funds that are deposited into the prize pool are then deposited into a yield source. (i.e. Aave, Compound, etc...)
*/
contract YieldSourcePrizePool is PrizePool {
using SafeERC20 for IERC20;
using Address for address;
/// @notice Address of the yield source.
IYieldSource public immutable yieldSource;
/// @dev Emitted when yield source prize pool is deployed.
/// @param yieldSource Address of the yield source.
event Deployed(address indexed yieldSource);
/// @notice Emitted when stray deposit token balance in this contract is swept
/// @param amount The amount that was swept
event Swept(uint256 amount);
/// @notice Deploy the Prize Pool and Yield Service with the required contract connections
/// @param _owner Address of the Yield Source Prize Pool owner
/// @param _yieldSource Address of the yield source
constructor(address _owner, IYieldSource _yieldSource) PrizePool(_owner) {
require(
address(_yieldSource) != address(0),
"YieldSourcePrizePool/yield-source-not-zero-address"
);
yieldSource = _yieldSource;
// A hack to determine whether it's an actual yield source
(bool succeeded, bytes memory data) = address(_yieldSource).staticcall(
abi.encodePacked(_yieldSource.depositToken.selector)
);
address resultingAddress;
if (data.length > 0) {
resultingAddress = abi.decode(data, (address));
}
require(succeeded && resultingAddress != address(0), "YieldSourcePrizePool/invalid-yield-source");
emit Deployed(address(_yieldSource));
}
/// @notice Sweeps any stray balance of deposit tokens into the yield source.
/// @dev This becomes prize money
function sweep() external nonReentrant onlyOwner {
uint256 balance = _token().balanceOf(address(this));
_supply(balance);
emit Swept(balance);
}
/// @notice Determines whether the passed token can be transferred out as an external award.
/// @dev Different yield sources will hold the deposits as another kind of token: such a Compound's cToken. The
/// prize strategy should not be allowed to move those tokens.
/// @param _externalToken The address of the token to check
/// @return True if the token may be awarded, false otherwise
function _canAwardExternal(address _externalToken) internal view override returns (bool) {
IYieldSource _yieldSource = yieldSource;
return (
_externalToken != address(_yieldSource) &&
_externalToken != _yieldSource.depositToken()
);
}
/// @notice Returns the total balance (in asset tokens). This includes the deposits and interest.
/// @return The underlying balance of asset tokens
function _balance() internal override returns (uint256) {
return yieldSource.balanceOfToken(address(this));
}
/// @notice Returns the address of the ERC20 asset token used for deposits.
/// @return Address of the ERC20 asset token.
function _token() internal view override returns (IERC20) {
return IERC20(yieldSource.depositToken());
}
/// @notice Supplies asset tokens to the yield source.
/// @param _mintAmount The amount of asset tokens to be supplied
function _supply(uint256 _mintAmount) internal override {
_token().safeIncreaseAllowance(address(yieldSource), _mintAmount);
yieldSource.supplyTokenTo(_mintAmount, address(this));
}
/// @notice Redeems asset tokens from the yield source.
/// @param _redeemAmount The amount of yield-bearing tokens to be redeemed
/// @return The actual amount of tokens that were redeemed.
function _redeem(uint256 _redeemAmount) internal override returns (uint256) {
return yieldSource.redeemToken(_redeemAmount);
}
}