This repository has been archived by the owner on Jul 13, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathPoolWithMStable.sol
102 lines (76 loc) · 2.94 KB
/
PoolWithMStable.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
pragma solidity 0.5.16;
import { IMasset } from "@mstable/protocol/contracts/interfaces/IMasset.sol";
import { IMStableHelper } from "@mstable/protocol/contracts/interfaces/IMStableHelper.sol";
import { ISavingsContract } from "@mstable/protocol/contracts/interfaces/ISavingsContract.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import { Ownable } from "@openzeppelin/contracts/ownership/Ownable.sol";
// Allows participants to stake mUSD and have the
// interest from SAVE be distributed to a specified beneficiary
contract PoolWithMStable is Ownable {
using SafeERC20 for IERC20;
IERC20 public mUSD;
ISavingsContract public save;
IMStableHelper public helper;
mapping(address => uint256) public gifts;
uint256 totalGifts = 0;
event GiftStaked(address indexed staker, uint256 amount);
event GiftWithdrawn(address indexed staker, uint256 amount);
event InterestCollected(uint256 amount);
constructor(
IERC20 _mUSD,
ISavingsContract _save,
IMStableHelper _helper,
address _beneficiary
)
public
Ownable()
{
mUSD = _mUSD;
save = _save;
helper = _helper;
_transferOwnership(_beneficiary);
mUSD.safeApprove(address(save), uint256(-1));
}
// Stake an amount of mUSD and deposit into SAVE
function stakeGift(
uint256 _amount
)
external
{
// Either we are depositing mUSD or we can mint as follows
// IMasset(_mUSD).mint(<bAsset>, <bAssetQuanity>);
mUSD.safeTransferFrom(msg.sender, address(this), _amount);
save.depositSavings(_amount);
gifts[msg.sender] += _amount;
totalGifts += _amount;
emit GiftStaked(msg.sender, _amount);
}
// Withdraw the staked mUSD
function withdrawGift(
uint256 _amount
)
external
{
uint256 giftBalance = gifts[msg.sender];
require(_amount <= giftBalance, "Not enough balance");
gifts[msg.sender] -= _amount;
totalGifts -= _amount;
uint256 creditsToRedeem = helper.getSaveRedeemInput(save, _amount);
save.redeem(creditsToRedeem);
// Either we return the mUSD or we could redeem into something
// bAsset = helper.getRedeemBasset();
// IMasset(mUSD).redeem(<bAsset>, <bAssetQuanity>);
mUSD.transfer(msg.sender, _amount);
emit GiftWithdrawn(msg.sender, _amount);
}
// Distribute any of the accrued interest to the beneficiary
function collectInterest() external {
uint256 currentBalance = helper.getSaveBalance(save, address(this));
uint256 delta = currentBalance - totalGifts;
uint256 creditsToRedeem = helper.getSaveRedeemInput(save, delta);
save.redeem(creditsToRedeem);
mUSD.transfer(owner(), delta);
emit InterestCollected(delta);
}
}