-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathLibCollectableDust.sol
101 lines (89 loc) · 3.44 KB
/
LibCollectableDust.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
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {EnumerableSet} from "./EnumerableSet.sol";
import {AddressUtils} from "./AddressUtils.sol";
import {UintUtils} from "./UintUtils.sol";
import {LibAppStorage} from "./LibAppStorage.sol";
import "./Constants.sol";
/// @notice Library for collecting dust (i.e. not part of a protocol) tokens sent to a contract
library LibCollectableDust {
using SafeERC20 for IERC20;
using AddressUtils for address;
using EnumerableSet for EnumerableSet.AddressSet;
using UintUtils for uint256;
/// @notice Emitted when dust tokens are sent to the `_to` address
event DustSent(address _to, address token, uint256 amount);
/// @notice Emitted when token is added to a protocol
event ProtocolTokenAdded(address _token);
/// @notice Emitted when token is removed from a protocol
event ProtocolTokenRemoved(address _token);
/// @notice Struct used as a storage for the current library
struct Tokens {
EnumerableSet.AddressSet protocolTokens;
}
/// @notice Storage slot used to store data for this library
bytes32 constant COLLECTABLE_DUST_CONTROL_STORAGE_SLOT =
bytes32(
uint256(keccak256("ubiquity.contracts.collectable.dust.storage")) -
1
);
/**
* @notice Returns struct used as a storage for this library
* @return l Struct used as a storage
*/
function collectableDustStorage() internal pure returns (Tokens storage l) {
bytes32 slot = COLLECTABLE_DUST_CONTROL_STORAGE_SLOT;
assembly {
l.slot := slot
}
}
/**
* @notice Adds token address to a protocol
* @param _token Token address to add
*/
function addProtocolToken(address _token) internal {
require(
!collectableDustStorage().protocolTokens.contains(_token),
"collectable-dust::token-is-part-of-the-protocol"
);
collectableDustStorage().protocolTokens.add(_token);
emit ProtocolTokenAdded(_token);
}
/**
* @notice Removes token address from a protocol
* @param _token Token address to remove
*/
function removeProtocolToken(address _token) internal {
require(
collectableDustStorage().protocolTokens.contains(_token),
"collectable-dust::token-not-part-of-the-protocol"
);
collectableDustStorage().protocolTokens.remove(_token);
emit ProtocolTokenRemoved(_token);
}
/**
* @notice Sends dust tokens (which are not part of a protocol) to the `_to` address
* @param _to Tokens receiver address
* @param _token Token address to send
* @param _amount Amount of tokens to send
*/
function sendDust(address _to, address _token, uint256 _amount) internal {
require(
_to != address(0),
"collectable-dust::cant-send-dust-to-zero-address"
);
require(
!collectableDustStorage().protocolTokens.contains(_token),
"collectable-dust::token-is-part-of-the-protocol"
);
if (_token == ETH_ADDRESS) {
(bool result, ) = _to.call{value: _amount}("");
require(result, "Failed to send Ether");
} else {
IERC20(_token).safeTransfer(_to, _amount);
}
emit DustSent(_to, _token, _amount);
}
}