forked from Project-DARC/DARC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCondition_TokenAndCash.sol
167 lines (138 loc) · 9.13 KB
/
Condition_TokenAndCash.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
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.19;
/**
* @title Condition of pay-to-mint, pay-to-transfer, burn-and-refund operation with cash
* @author DARC Team
* @notice All the condition expression functions related to Operator
*/
import "../MachineState.sol";
import "../MachineStateManager.sol";
import "../Utilities/StringUtils.sol";
import "../Utilities/OpcodeMap.sol";
import "../Plugin.sol";
import "../Utilities/ExternalValueReader.sol";
contract Condition_TokenAndCash is MachineStateManager {
/**
* The function to check the batch operation related condition expression
* @param op The operation to be checked
* @param param The parameter list of the condition expression
* @param id The id of the condition expression
*/
function tokenAndCashExpressionCheck(Operation memory op, NodeParam memory param, uint256 id) internal view returns (bool) {
if (id== 461) return ID_461_TOKEN_X_OP_ANY_PRICE_GREATER_THAN(op, param);
if (id== 462) return ID_462_TOKEN_X_OP_ANY_PRICE_LESS_THAN(op, param);
if (id== 463) return ID_463_TOKEN_X_OP_ANY_PRICE_IN_RANGE(op, param);
if (id== 464) return ID_464_TOKEN_X_OP_ANY_PRICE_EQUALS(op, param);
if (id== 465) return ID_465_TOKEN_X_OP_ANY_PRICE_GREATER_THAN_EXTERNAL_VALUE_UINT256(op, param);
if (id== 466) return ID_466_TOKEN_X_OP_ANY_PRICE_LESS_THAN_EXTERNAL_VALUE_UINT256(op, param);
if (id== 467) return ID_467_TOKEN_X_OP_ANY_PRICE_EQUALS_EXTERNAL_VALUE_UINT256(op, param);
return false;
}
function ID_461_TOKEN_X_OP_ANY_PRICE_GREATER_THAN(Operation memory op, NodeParam memory param) private pure returns (bool) {
require(param.UINT256_2DARRAY.length == 1, "CE ID_461: The UINT256_2DARRAY length is not 1");
require(param.UINT256_2DARRAY[0].length == 2, "CE ID_461: The UINT256_2DARRAY[0] length is not 1");
if (bIsTokenOperationWithCash(op) == false) return false;
(uint256[] memory tokenClassList, , uint256[] memory priceList) = getTokenClassAmountPriceList(op);
require(tokenClassList.length == priceList.length, "CE ID_461: The token class list length is not equal to price list length");
for (uint256 i = 0; i < tokenClassList.length; i++) {
if (tokenClassList[i] == param.UINT256_2DARRAY[0][0] && priceList[i] > param.UINT256_2DARRAY[0][1]) { return true; }
}
return false;
}
function ID_462_TOKEN_X_OP_ANY_PRICE_LESS_THAN(Operation memory op, NodeParam memory param) private pure returns (bool) {
require(param.UINT256_2DARRAY.length == 1, "CE ID_462: The UINT256_2DARRAY length is not 1");
require(param.UINT256_2DARRAY[0].length == 2, "CE ID_462: The UINT256_2DARRAY[0] length is not 1");
if (bIsTokenOperationWithCash(op) == false) return false;
(uint256[] memory tokenClassList, , uint256[] memory priceList) = getTokenClassAmountPriceList(op);
require(tokenClassList.length == priceList.length, "CE ID_462: The token class list length is not equal to price list length");
for (uint256 i = 0; i < tokenClassList.length; i++) {
if (tokenClassList[i] == param.UINT256_2DARRAY[0][0] && priceList[i] < param.UINT256_2DARRAY[0][1]) { return true; }
}
return false;
}
function ID_463_TOKEN_X_OP_ANY_PRICE_IN_RANGE(Operation memory op, NodeParam memory param) private pure returns (bool) {
require(param.UINT256_2DARRAY.length == 1, "CE ID_463: The UINT256_2DARRAY length is not 1");
require(param.UINT256_2DARRAY[0].length == 3, "CE ID_463: The UINT256_2DARRAY[0] length is not 1");
if (bIsTokenOperationWithCash(op) == false) return false;
(uint256[] memory tokenClassList, , uint256[] memory priceList) = getTokenClassAmountPriceList(op);
require(tokenClassList.length == priceList.length, "CE ID_463: The token class list length is not equal to price list length");
for (uint256 i = 0; i < tokenClassList.length; i++) {
if (tokenClassList[i] == param.UINT256_2DARRAY[0][0] && priceList[i] >= param.UINT256_2DARRAY[0][1] && priceList[i] <= param.UINT256_2DARRAY[0][2]) { return true; }
}
return false;
}
function ID_464_TOKEN_X_OP_ANY_PRICE_EQUALS(Operation memory op, NodeParam memory param) private pure returns (bool) {
require(param.UINT256_2DARRAY.length == 1, "CE ID_464: The UINT256_2DARRAY length is not 1");
require(param.UINT256_2DARRAY[0].length == 2, "CE ID_464: The UINT256_2DARRAY[0] length is not 1");
if (bIsTokenOperationWithCash(op) == false) return false;
(uint256[] memory tokenClassList, , uint256[] memory priceList) = getTokenClassAmountPriceList(op);
require(tokenClassList.length == priceList.length, "CE ID_464: The token class list length is not equal to price list length");
for (uint256 i = 0; i < tokenClassList.length; i++) {
if (tokenClassList[i] == param.UINT256_2DARRAY[0][0] && priceList[i] == param.UINT256_2DARRAY[0][1]) { return true; }
}
return false;
}
function ID_465_TOKEN_X_OP_ANY_PRICE_GREATER_THAN_EXTERNAL_VALUE_UINT256(Operation memory op, NodeParam memory param) private view returns (bool) {
require(param.UINT256_2DARRAY.length == 1, "CE ID_465: The UINT256_2DARRAY length is not 1");
require(param.UINT256_2DARRAY[0].length == 2, "CE ID_465: The UINT256_2DARRAY[0] length is not 1");
if (bIsTokenOperationWithCash(op) == false) return false;
(uint256[] memory tokenClassList, , uint256[] memory priceList) = getTokenClassAmountPriceList(op);
require(tokenClassList.length == priceList.length, "CE ID_465: The token class list length is not equal to price list length");
// try to get external value
(bool success, uint256 externalValue) = ExternalValueReader.tryReadUINT256(op.param.ADDRESS_2DARRAY[0][0], op.param.BYTES);
if (success == false) return false;
for (uint256 i = 0; i < tokenClassList.length; i++) {
if (tokenClassList[i] == param.UINT256_2DARRAY[0][0] && priceList[i] > externalValue) { return true; }
}
return false;
}
function ID_466_TOKEN_X_OP_ANY_PRICE_LESS_THAN_EXTERNAL_VALUE_UINT256(Operation memory op, NodeParam memory param) private view returns (bool) {
require(param.UINT256_2DARRAY.length == 1, "CE ID_466: The UINT256_2DARRAY length is not 1");
require(param.UINT256_2DARRAY[0].length == 2, "CE ID_466: The UINT256_2DARRAY[0] length is not 1");
if (bIsTokenOperationWithCash(op) == false) return false;
(uint256[] memory tokenClassList, , uint256[] memory priceList) = getTokenClassAmountPriceList(op);
require(tokenClassList.length == priceList.length, "CE ID_466: The token class list length is not equal to price list length");
// try to get external value
(bool success, uint256 externalValue) = ExternalValueReader.tryReadUINT256(op.param.ADDRESS_2DARRAY[0][0], op.param.BYTES);
if (success == false) return false;
for (uint256 i = 0; i < tokenClassList.length; i++) {
if (tokenClassList[i] == param.UINT256_2DARRAY[0][0] && priceList[i] < externalValue) { return true; }
}
return false;
}
function ID_467_TOKEN_X_OP_ANY_PRICE_EQUALS_EXTERNAL_VALUE_UINT256(Operation memory op, NodeParam memory param) private view returns (bool) {
require(param.UINT256_2DARRAY.length == 1, "CE ID_467: The UINT256_2DARRAY length is not 1");
require(param.UINT256_2DARRAY[0].length == 2, "CE ID_467: The UINT256_2DARRAY[0] length is not 1");
if (bIsTokenOperationWithCash(op) == false) return false;
(uint256[] memory tokenClassList, , uint256[] memory priceList) = getTokenClassAmountPriceList(op);
require(tokenClassList.length == priceList.length, "CE ID_467: The token class list length is not equal to price list length");
// try to get external value
(bool success, uint256 externalValue) = ExternalValueReader.tryReadUINT256(op.param.ADDRESS_2DARRAY[0][0], op.param.BYTES);
if (success == false) return false;
for (uint256 i = 0; i < tokenClassList.length; i++) {
if (tokenClassList[i] == param.UINT256_2DARRAY[0][0] && priceList[i] == externalValue) { return true; }
}
return false;
}
// -------------------------------- below are helper functions ----------------------------
function bIsTokenOperationWithCash(Operation memory op) private pure returns (bool) {
if (op.opcode == EnumOpcode.BATCH_PAY_TO_MINT_TOKENS
|| op.opcode == EnumOpcode.BATCH_PAY_TO_TRANSFER_TOKENS
|| op.opcode == EnumOpcode.BATCH_BURN_TOKENS_AND_REFUND
) { return true; }
return false;
}
function getTokenClassAmountPriceList(Operation memory op) private pure returns (uint256[] memory, uint256[] memory, uint256[] memory) {
require(bIsTokenOperationWithCash(op), "CE ID_461: The operation is not token operation with cash(pay-to-mint, pay-to-transfer, burn-and-refund)");
if (op.opcode == EnumOpcode.BATCH_PAY_TO_MINT_TOKENS) {
return (op.param.UINT256_2DARRAY[0], op.param.UINT256_2DARRAY[1], op.param.UINT256_2DARRAY[2]);
}
if (op.opcode == EnumOpcode.BATCH_PAY_TO_TRANSFER_TOKENS) {
return (op.param.UINT256_2DARRAY[0], op.param.UINT256_2DARRAY[2], op.param.UINT256_2DARRAY[3]);
}
if (op.opcode == EnumOpcode.BATCH_BURN_TOKENS_AND_REFUND) {
return (op.param.UINT256_2DARRAY[0], op.param.UINT256_2DARRAY[1], op.param.UINT256_2DARRAY[2]);
}
return (new uint256[](0), new uint256[](0), new uint256[](0));
}
}