-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathValidationModuleERC1404.sol
More file actions
160 lines (146 loc) · 6.33 KB
/
ValidationModuleERC1404.sol
File metadata and controls
160 lines (146 loc) · 6.33 KB
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
// SPDX-License-Identifier: MPL-2.0
pragma solidity ^0.8.20;
/* ==== Tokenization === */
import {IERC1404, IERC1404Extend} from "../../../../interfaces/tokenization/draft-IERC1404.sol";
import {ValidationModuleRuleEngine} from "./ValidationModuleRuleEngine.sol";
import {IRuleEngineERC1404} from "../../../../interfaces/engine/IRuleEngine.sol";
/**
* @dev Validation module (ERC-1404)
*
* Useful for to restrict and validate transfers
* Required a RuleEngine implementing the interface IRuleEngineERC1404
*/
abstract contract ValidationModuleERC1404 is
ValidationModuleRuleEngine, IERC1404Extend
{
/* ============ State Variables ============ */
string constant TEXT_TRANSFER_OK = "NoRestriction";
string constant TEXT_UNKNOWN_CODE = "UnknownCode";
/* EnforcementModule */
string internal constant TEXT_TRANSFER_REJECTED_FROM_FROZEN =
"AddrFromIsFrozen";
string internal constant TEXT_TRANSFER_REJECTED_TO_FROZEN =
"AddrToIsFrozen";
string internal constant TEXT_TRANSFER_REJECTED_SPENDER_FROZEN =
"AddrSpenderIsFrozen";
/* PauseModule */
string internal constant TEXT_TRANSFER_REJECTED_PAUSED =
"EnforcedPause";
/* Contract deactivated */
string internal constant TEXT_TRANSFER_REJECTED_DEACTIVATED =
"ContractDeactivated";
/*//////////////////////////////////////////////////////////////
PUBLIC/EXTERNAL FUNCTIONS
//////////////////////////////////////////////////////////////*/
/**
* @notice returns the human readable explanation
* corresponding to the error code returned by detectTransferRestriction
* @param restrictionCode The error code returned by detectTransferRestriction
* @return message The human readable explanation corresponding to the error code returned by detectTransferRestriction
* @dev see {ERC-1404}
*/
function messageForTransferRestriction(
uint8 restrictionCode
) public virtual view override(IERC1404) returns (string memory message) {
IRuleEngineERC1404 ruleEngine_ = IRuleEngineERC1404(address(ruleEngine()));
if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK)) {
return TEXT_TRANSFER_OK;
} else if (
restrictionCode ==
uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_PAUSED)
) {
return TEXT_TRANSFER_REJECTED_PAUSED;
} else if (
restrictionCode ==
uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_DEACTIVATED)
) {
return TEXT_TRANSFER_REJECTED_DEACTIVATED;
} else if (
restrictionCode ==
uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_FROZEN)
) {
return TEXT_TRANSFER_REJECTED_FROM_FROZEN;
} else if (
restrictionCode ==
uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_TO_FROZEN)
) {
return TEXT_TRANSFER_REJECTED_TO_FROZEN;
} else if (
restrictionCode ==
uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_SPENDER_FROZEN)
) {
return TEXT_TRANSFER_REJECTED_SPENDER_FROZEN;
} else if (address(ruleEngine_) != address(0)) {
return ruleEngine_.messageForTransferRestriction(restrictionCode);
} else {
return TEXT_UNKNOWN_CODE;
}
}
/**
* @notice 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 value uint256 the amount of tokens to be transferred
* @return code of the rejection reason
* @dev see {ERC-1404}
*/
function detectTransferRestriction(
address from,
address to,
uint256 value
) public virtual view override(IERC1404) returns (uint8 code) {
IRuleEngineERC1404 ruleEngine_ = IRuleEngineERC1404(address(ruleEngine()));
uint8 codeReturn = _detectTransferRestriction(from, to, value);
if(codeReturn != uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK) ){
return codeReturn;
} else if (address(ruleEngine_) != address(0)) {
return ruleEngine_.detectTransferRestriction(from, to, value);
} else{
return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK);
}
}
function detectTransferRestrictionFrom(
address spender,
address from,
address to,
uint256 value
) public virtual view override(IERC1404Extend) returns (uint8 code) {
IRuleEngineERC1404 ruleEngine_ = IRuleEngineERC1404(address(ruleEngine()));
if (isFrozen(spender)) {
return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_SPENDER_FROZEN);
} else {
uint8 codeReturn = _detectTransferRestriction(from, to, value);
if (codeReturn != uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK) ){
return codeReturn;
} else if (address(ruleEngine_) != address(0)) {
return ruleEngine_.detectTransferRestrictionFrom(spender, from, to, value);
} else {
return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK);
}
}
}
/*//////////////////////////////////////////////////////////////
INTERNAL/PRIVATE FUNCTIONS
//////////////////////////////////////////////////////////////*/
/**
* @dev override this function to add further restriction
*/
function _detectTransferRestriction(
address from,
address to,
uint256 /* value */
) internal virtual view returns (uint8 code) {
if (deactivated()){
return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_DEACTIVATED);
} else if (paused()) {
return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_PAUSED);
} else if (isFrozen(from)) {
return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_FROZEN);
} else if (isFrozen(to)) {
return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_TO_FROZEN);
}
else {
return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK);
}
}
}