-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathValidationModule.sol
151 lines (137 loc) · 5.42 KB
/
ValidationModule.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
//SPDX-License-Identifier: MPL-2.0
pragma solidity ^0.8.20;
import "../../security/AuthorizationModule.sol";
import "../../internal/ValidationModuleInternal.sol";
import "../core/PauseModule.sol";
import "../core/EnforcementModule.sol";
import "../../../libraries/Errors.sol";
/**
* @dev Validation module.
*
* Useful for to restrict and validate transfers
*/
abstract contract ValidationModule is
ValidationModuleInternal,
PauseModule,
EnforcementModule,
IERC1404Wrapper
{
/* ============ State Variables ============ */
string constant TEXT_TRANSFER_OK = "No restriction";
string constant TEXT_UNKNOWN_CODE = "Unknown code";
/* ============ Initializer Function ============ */
function __ValidationModule_init_unchained() internal onlyInitializing {
// no variable to initialize
}
/*//////////////////////////////////////////////////////////////
PUBLIC/EXTERNAL FUNCTIONS
//////////////////////////////////////////////////////////////*/
/*
* @notice set a RuleEngine
* @param ruleEngine_ the call will be reverted if the new value of ruleEngine is the same as the current one
*/
function setRuleEngine(
IRuleEngine ruleEngine_
) external onlyRole(DEFAULT_ADMIN_ROLE) {
ValidationModuleInternalStorage storage $ = _getValidationModuleInternalStorage();
if ($._ruleEngine == ruleEngine_){
revert Errors.CMTAT_ValidationModule_SameValue();
}
$._ruleEngine = ruleEngine_;
emit RuleEngine(ruleEngine_);
}
/**
* @dev ERC1404 returns the human readable explaination corresponding to the error code returned by detectTransferRestriction
* @param restrictionCode The error code returned by detectTransferRestriction
* @return message The human readable explaination corresponding to the error code returned by detectTransferRestriction
*/
function messageForTransferRestriction(
uint8 restrictionCode
) external view override returns (string memory message) {
ValidationModuleInternalStorage storage $ = _getValidationModuleInternalStorage();
if (restrictionCode == uint8(REJECTED_CODE_BASE.TRANSFER_OK)) {
return TEXT_TRANSFER_OK;
} else if (
restrictionCode ==
uint8(REJECTED_CODE_BASE.TRANSFER_REJECTED_PAUSED)
) {
return TEXT_TRANSFER_REJECTED_PAUSED;
} else if (
restrictionCode ==
uint8(REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_FROZEN)
) {
return TEXT_TRANSFER_REJECTED_FROM_FROZEN;
} else if (
restrictionCode ==
uint8(REJECTED_CODE_BASE.TRANSFER_REJECTED_TO_FROZEN)
) {
return TEXT_TRANSFER_REJECTED_TO_FROZEN;
} else if (address($._ruleEngine) != address(0)) {
return _messageForTransferRestriction(restrictionCode);
} else {
return TEXT_UNKNOWN_CODE;
}
}
/**
* @dev ERC1404 check if _value token can be transferred from _from to _to
* @param from address The address which you want to send tokens from
* @param to address The address which you want to transfer to
* @param amount uint256 the amount of tokens to be transferred
* @return code of the rejection reason
*/
function detectTransferRestriction(
address from,
address to,
uint256 amount
) public view override returns (uint8 code) {
ValidationModuleInternalStorage storage $ = _getValidationModuleInternalStorage();
if (paused()) {
return uint8(REJECTED_CODE_BASE.TRANSFER_REJECTED_PAUSED);
} else if (frozen(from)) {
return uint8(REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_FROZEN);
} else if (frozen(to)) {
return uint8(REJECTED_CODE_BASE.TRANSFER_REJECTED_TO_FROZEN);
} else if (address($._ruleEngine) != address(0)) {
return _detectTransferRestriction(from, to, amount);
} else {
return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
}
}
function validateTransfer(
address from,
address to,
uint256 amount
) public view override returns (bool) {
if (!_validateTransferByModule(from, to, amount)) {
return false;
}
ValidationModuleInternalStorage storage $ = _getValidationModuleInternalStorage();
if (address($._ruleEngine) != address(0)) {
return _validateTransfer(from, to, amount);
}
return true;
}
/*//////////////////////////////////////////////////////////////
INTERNAL/PRIVATE FUNCTIONS
//////////////////////////////////////////////////////////////*/
function _validateTransferByModule(
address from,
address to,
uint256 /*amount*/
) internal view returns (bool) {
if (paused() || frozen(from) || frozen(to)) {
return false;
}
return true;
}
function _operateOnTransfer(address from, address to, uint256 amount) override internal returns (bool){
if (!_validateTransferByModule(from, to, amount)){
return false;
}
ValidationModuleInternalStorage storage $ = _getValidationModuleInternalStorage();
if (address($._ruleEngine) != address(0)) {
return ValidationModuleInternal._operateOnTransfer(from, to, amount);
}
return true;
}
}