-
Notifications
You must be signed in to change notification settings - Fork 1
/
KyotoHub.sol
188 lines (162 loc) · 6.62 KB
/
KyotoHub.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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// SPDX-License-Identifier: MIT
pragma solidity =0.8.17;
/// @title Kyoto Hub
/// Protocol Version 1.1
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol";
import {Errors} from "./libraries/Errors.sol";
import {Events} from "./libraries/Events.sol";
import {DataTypes} from "./libraries/DataTypes.sol";
import {IKyotoHub} from "./interfaces/IKyotoHub.sol";
// To Do: Add vendor
contract KyotoHub is IKyotoHub, Pausable, Ownable2Step {
using EnumerableSet for EnumerableSet.AddressSet;
uint256 public constant MAX_FEE = 500;
uint256 public constant PRECISION_FACTOR = 10_000;
// mapping for prferences
mapping(address => DataTypes.Preferences) private recipientPreferences;
EnumerableSet.AddressSet private whitelistedInputTokens;
EnumerableSet.AddressSet private whitelistedOutputTokens;
mapping(address => uint256) public partnerDiscounts;
constructor() Ownable2Step() {}
/**
* @notice sets the sender's receiving preferences.
* @param _preferences the sender's given preferences
* Note: slippageAllowed is inversed. For example, 9_900 is 1% slippage
* Requirements:
* - '_preferences.slippageAllowed' is not 0% (i.e. >= 10,000) or 100% (i.e. 0)
* - '_preferences.tokenAddress' is a valid output token found in whitelistedOutputTokens
*/
function setPreferences(DataTypes.Preferences calldata _preferences) external whenNotPaused {
if ((_preferences.slippageAllowed == 0) || (_preferences.slippageAllowed >= PRECISION_FACTOR)) {
revert Errors.InvalidRecipientSlippage();
}
if (!(whitelistedOutputTokens.contains(_preferences.tokenAddress))) revert Errors.InvalidRecipientToken();
recipientPreferences[msg.sender] = _preferences;
emit Events.PreferencesSet(msg.sender, _preferences.tokenAddress, _preferences.slippageAllowed);
}
//////////////////////////////
/// Admin Functions ///
//////////////////////////////
/**
* @dev Admin function to set partner discounts
* @param _partner the address of the partner
* @param _discount the discount
* Requirements:
* - '_discount' is not greater than MAX_FEE
*/
function setPartnerDiscount(address _partner, uint256 _discount) external onlyOwner {
if (_discount > MAX_FEE) revert Errors.InvalidPartnerDiscount();
partnerDiscounts[_partner] = _discount;
emit Events.PartnerDiscountSet(_partner, _discount);
}
/**
* @dev Admin function to add a token to the input whitelist
* @param _token the address of the token
* Requirements:
* - '_token" != address(0)
* - msg.sender is the owner
*/
function addToInputWhitelist(address _token) external onlyOwner {
if (_token == address(0)) revert Errors.ZeroAddress();
whitelistedInputTokens.add(_token);
emit Events.AddedWhitelistedInputToken(_token);
}
/**
* @dev Admin function to add a token to the output whitelist
* @param _token the address of the token
* Requirements:
* - '_token" != address(0)
* - msg.sender is the owner
*/
function addToOutputWhitelist(address _token) external onlyOwner {
if (_token == address(0)) revert Errors.ZeroAddress();
whitelistedOutputTokens.add(_token);
emit Events.AddedWhitelistedOutputToken(_token);
}
/**
* @dev Admin function to revoke a token from the input whitelist
* @param _token the address of the token
* Requirements:
* - '_token" != address(0)
* - msg.sender is the owner
*/
function revokeFromInputWhitelist(address _token) external onlyOwner {
if (_token == address(0)) revert Errors.ZeroAddress();
whitelistedInputTokens.remove(_token);
emit Events.RevokedWhitelistedInputToken(_token);
}
/**
* @dev Admin function to revoke a token from the output whitelist
* @param _token the address of the token
* Requirements:
* - '_token" != address(0)
* - msg.sender is the owner
*/
function revokeFromOutputWhitelist(address _token) external onlyOwner {
if (_token == address(0)) revert Errors.ZeroAddress();
whitelistedOutputTokens.remove(_token);
emit Events.RevokedWhitelistedOutputToken(_token);
}
/////////////////////////////
/// View Functions ///
/////////////////////////////
/**
* @notice returns whether or not a token is a whitelisted input token
* @param _token the token's address
* @return true if '_token' is a whitelisted input token, false otherwise
*/
function isWhitelistedInputToken(address _token) external view returns (bool) {
return whitelistedInputTokens.contains(_token);
}
/**
* @notice returns whether or not a token is a whitelisted output token
* @param _token the token's address
* @return true if '_token' is a whitelisted output token, false otherwise
*/
function isWhitelistedOutputToken(address _token) external view returns (bool) {
return whitelistedOutputTokens.contains(_token);
}
/**
* @notice returns all whitelisted input tokens
* @return an address array containing all whitelisted input tokens
*/
function getWhitelistedInputTokens() external view returns (address[] memory) {
return whitelistedInputTokens.values();
}
/**
* @notice returns all whitelisted output tokens
* @return an address array containing all whitelisted output tokens
*/
function getWhitelistedOutputTokens() external view returns (address[] memory) {
return whitelistedOutputTokens.values();
}
/**
* @notice returns the partner's discount
* @param _partner the partner's address
*/
function getPartnerDiscount(address _partner) external view returns (uint256) {
return partnerDiscounts[_partner];
}
/**
* @notice returns a recipient's preferences
* @param _recipient the recipient
* @return A struct containing the _recipient's preferred token and allowed slippage
*/
function getRecipientPreferences(address _recipient) external view returns (DataTypes.Preferences memory) {
return recipientPreferences[_recipient];
}
/**
* @dev Admin function to pause payments
*/
function pause() external onlyOwner {
_pause();
}
/**
* @dev Admin function to unpause payments
*/
function unpause() external onlyOwner {
_unpause();
}
}