generated from wslyvh/nexth
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathRecipientToken.sol
137 lines (106 loc) · 3.72 KB
/
RecipientToken.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
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Math} from '@openzeppelin/contracts/utils/math/Math.sol';
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol';
import '../Common.sol';
contract RecipientToken is Ownable {
struct Conditions {
uint256 depositFee;
address tokenAddress;
address recipient;
}
mapping(uint256 => Conditions) internal _conditions;
mapping(uint256 => uint256) internal _totalDeposits;
mapping(uint256 => uint256) internal _totalFunded;
string internal _name;
constructor(address owner) Ownable(owner) {
_name = 'RecipientToken';
}
function initialize(uint256 id, bytes calldata data) external virtual onlyOwner returns (bool) {
Conditions memory conditions = abi.decode(data, (Conditions));
_conditions[id] = conditions;
return true;
}
function cancel(
uint256 id,
address owner,
address[] calldata registrations,
bytes calldata data
) external virtual onlyOwner returns (bool) {
IERC20 token = IERC20(_conditions[id].tokenAddress);
for (uint256 i = 0; i < registrations.length; i++) {
require(token.transfer(registrations[i], _conditions[id].depositFee));
}
_totalDeposits[id] = 0;
if (_totalFunded[id] > 0) {
require(token.transfer(owner, _totalFunded[id]));
_totalFunded[id] = 0;
}
return true;
}
function fund(uint256 id, address sender, bytes calldata data) external payable virtual onlyOwner returns (bool) {
if (msg.value > 0) revert IncorrectValue();
uint256 amount = abi.decode(data, (uint256));
if (amount == 0) revert IncorrectValue();
IERC20 token = IERC20(_conditions[id].tokenAddress);
require(token.transferFrom(sender, address(this), amount));
_totalFunded[id] += amount;
return true;
}
function register(
uint256 id,
address participant,
address sender,
bytes calldata data
) external payable virtual onlyOwner returns (bool) {
if (msg.value > 0) revert IncorrectValue();
IERC20 token = IERC20(_conditions[id].tokenAddress);
require(token.transferFrom(sender, address(this), _conditions[id].depositFee));
_totalDeposits[id] += _conditions[id].depositFee;
return true;
}
function checkin(
uint256 id,
address[] calldata attendees,
bytes calldata data
) external virtual onlyOwner returns (bool) {
return true;
}
function settle(
uint256 id,
address[] calldata attendees,
bytes calldata data
) external virtual onlyOwner returns (bool) {
(bool success, uint256 fundFee) = Math.tryDiv(_totalFunded[id], attendees.length);
if (!success) revert IncorrectValue();
uint256 totalPayouts = 0;
uint256 settlementFee = _conditions[id].depositFee + fundFee;
IERC20 token = IERC20(_conditions[id].tokenAddress);
for (uint256 i = 0; i < attendees.length; i++) {
require(token.transfer(attendees[i], settlementFee));
totalPayouts += _conditions[id].depositFee;
}
if (_totalDeposits[id] > totalPayouts) {
uint256 recipientFee = _totalDeposits[id] - totalPayouts;
require(token.transfer(_conditions[id].recipient, recipientFee));
}
_totalDeposits[id] = 0;
_totalFunded[id] = 0;
return true;
}
// View functions
// =======================
function name() external view returns (string memory) {
return _name;
}
function getConditions(uint256 id) external view returns (Conditions memory) {
return _conditions[id];
}
function getTotalDeposits(uint256 id) external view returns (uint256) {
return _totalDeposits[id];
}
function getTotalFunded(uint256 id) external view returns (uint256) {
return _totalFunded[id];
}
}