@evvm/testnet-contracts 2.0.4 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/contracts/p2pSwap/P2PSwap.sol +1358 -0
- package/contracts/p2pSwap/lib/SignatureUtils.sol +100 -0
- package/contracts/staking/Estimator.sol +1 -1
- package/interfaces/INameService.sol +3 -1
- package/interfaces/IP2PSwap.sol +135 -0
- package/library/Erc191TestBuilder.sol +82 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1358 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EVVM-NONCOMMERCIAL-1.0
|
|
2
|
+
// Full license terms available at: https://www.evvm.org/docs/EVVMNoncommercialLicense
|
|
3
|
+
|
|
4
|
+
pragma solidity ^0.8.0;
|
|
5
|
+
/**
|
|
6
|
+
/$$$$$$$ /$$$$$$ /$$$$$$$ /$$$$$$
|
|
7
|
+
| $$__ $$/$$__ $| $$__ $$/$$__ $$
|
|
8
|
+
| $$ \ $|__/ \ $| $$ \ $| $$ \__//$$ /$$ /$$ /$$$$$$ /$$$$$$
|
|
9
|
+
| $$$$$$$/ /$$$$$$| $$$$$$$| $$$$$$| $$ | $$ | $$|____ $$/$$__ $$
|
|
10
|
+
| $$____/ /$$____/| $$____/ \____ $| $$ | $$ | $$ /$$$$$$| $$ \ $$
|
|
11
|
+
| $$ | $$ | $$ /$$ \ $| $$ | $$ | $$/$$__ $| $$ | $$
|
|
12
|
+
| $$ | $$$$$$$| $$ | $$$$$$| $$$$$/$$$$| $$$$$$| $$$$$$$/
|
|
13
|
+
|__/ |________|__/ \______/ \_____/\___/ \_______| $$____/
|
|
14
|
+
| $$
|
|
15
|
+
| $$
|
|
16
|
+
|__/
|
|
17
|
+
|
|
18
|
+
* @title P2P Swap Service
|
|
19
|
+
* @author Mate labs
|
|
20
|
+
* @notice Peer-to-peer decentralized exchange for token trading within the EVVM ecosystem
|
|
21
|
+
* @dev Implements order book-style trading with dynamic market creation, fee distribution,
|
|
22
|
+
* and integration with EVVM's staking and payment systems. Supports both proportional
|
|
23
|
+
* and fixed fee models with time-delayed governance for parameter updates.
|
|
24
|
+
*
|
|
25
|
+
* Key Features:
|
|
26
|
+
* - Dynamic market creation for any token pair
|
|
27
|
+
* - Order management (create, cancel, execute)
|
|
28
|
+
* - Configurable fee structure with multi-party distribution
|
|
29
|
+
* - Service staking capabilities via StakingServiceHooks inheritance
|
|
30
|
+
* - ERC-191 signature verification for all operations
|
|
31
|
+
* - Time-delayed administrative governance
|
|
32
|
+
*
|
|
33
|
+
* Fee Distribution:
|
|
34
|
+
* - Seller: 50% (configurable)
|
|
35
|
+
* - Service: 40% (configurable)
|
|
36
|
+
* - Staker Rewards: 10% (configurable)
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
import {Evvm} from "@evvm/testnet-contracts/contracts/evvm/Evvm.sol";
|
|
40
|
+
import {Staking} from "@evvm/testnet-contracts/contracts/staking/Staking.sol";
|
|
41
|
+
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
|
|
42
|
+
import {SignatureRecover} from "@evvm/testnet-contracts/library/SignatureRecover.sol";
|
|
43
|
+
import {SignatureUtils} from "@evvm/testnet-contracts/contracts/p2pSwap/lib/SignatureUtils.sol";
|
|
44
|
+
import {AdvancedStrings} from "@evvm/testnet-contracts/library/AdvancedStrings.sol";
|
|
45
|
+
import {EvvmStructs} from "@evvm/testnet-contracts/contracts/evvm/lib/EvvmStructs.sol";
|
|
46
|
+
import {StakingServiceHooks} from "@evvm/testnet-contracts/library/StakingServiceHooks.sol";
|
|
47
|
+
|
|
48
|
+
contract P2PSwap is StakingServiceHooks {
|
|
49
|
+
using SignatureRecover for *;
|
|
50
|
+
using AdvancedStrings for *;
|
|
51
|
+
|
|
52
|
+
/// @notice Current contract owner with administrative privileges
|
|
53
|
+
address owner;
|
|
54
|
+
/// @notice Proposed new owner address pending acceptance
|
|
55
|
+
address owner_proposal;
|
|
56
|
+
/// @notice Timestamp when the proposed owner change can be accepted
|
|
57
|
+
uint256 owner_timeToAccept;
|
|
58
|
+
|
|
59
|
+
/// @notice Address of the EVVM core contract for payment processing
|
|
60
|
+
address evvmAddress;
|
|
61
|
+
/// @notice Address of the Staking contract for service staking functionality
|
|
62
|
+
address stakingAddress;
|
|
63
|
+
|
|
64
|
+
/// @notice Constant address representing the MATE token (Principal Token)
|
|
65
|
+
address constant MATE_TOKEN_ADDRESS =
|
|
66
|
+
0x0000000000000000000000000000000000000001;
|
|
67
|
+
/// @notice Constant address representing native ETH
|
|
68
|
+
address constant ETH_ADDRESS = 0x0000000000000000000000000000000000000000;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @notice Market metadata containing token pair and order tracking information
|
|
72
|
+
* @param tokenA Address of the first token in the trading pair
|
|
73
|
+
* @param tokenB Address of the second token in the trading pair
|
|
74
|
+
* @param maxSlot Maximum order ID ever created in this market
|
|
75
|
+
* @param ordersAvailable Current number of active orders in the market
|
|
76
|
+
*/
|
|
77
|
+
struct MarketInformation {
|
|
78
|
+
address tokenA;
|
|
79
|
+
address tokenB;
|
|
80
|
+
uint256 maxSlot;
|
|
81
|
+
uint256 ordersAvailable;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @notice Individual order details within a market
|
|
86
|
+
* @param seller Address of the user who created the order
|
|
87
|
+
* @param amountA Amount of tokenA the seller is offering
|
|
88
|
+
* @param amountB Amount of tokenB the seller wants in return
|
|
89
|
+
*/
|
|
90
|
+
struct Order {
|
|
91
|
+
address seller;
|
|
92
|
+
uint256 amountA;
|
|
93
|
+
uint256 amountB;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @notice Extended order information for external queries
|
|
98
|
+
* @param marketId ID of the market containing this order
|
|
99
|
+
* @param orderId Unique order ID within the market
|
|
100
|
+
* @param seller Address of the user who created the order
|
|
101
|
+
* @param amountA Amount of tokenA being offered
|
|
102
|
+
* @param amountB Amount of tokenB being requested
|
|
103
|
+
*/
|
|
104
|
+
struct OrderForGetter {
|
|
105
|
+
uint256 marketId;
|
|
106
|
+
uint256 orderId;
|
|
107
|
+
address seller;
|
|
108
|
+
uint256 amountA;
|
|
109
|
+
uint256 amountB;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @notice Fee distribution percentages (in basis points, total must equal 10,000)
|
|
114
|
+
* @param seller Percentage of fees distributed to the order seller
|
|
115
|
+
* @param service Percentage of fees retained by the P2PSwap service
|
|
116
|
+
* @param mateStaker Percentage of fees distributed to MATE token stakers
|
|
117
|
+
*/
|
|
118
|
+
struct Percentage {
|
|
119
|
+
uint256 seller;
|
|
120
|
+
uint256 service;
|
|
121
|
+
uint256 mateStaker;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @notice Metadata required for creating a new order
|
|
126
|
+
* @param nonce Unique nonce to prevent replay attacks
|
|
127
|
+
* @param tokenA Address of the token being offered
|
|
128
|
+
* @param tokenB Address of the token being requested
|
|
129
|
+
* @param amountA Amount of tokenA to offer
|
|
130
|
+
* @param amountB Amount of tokenB requested in return
|
|
131
|
+
*/
|
|
132
|
+
struct MetadataMakeOrder {
|
|
133
|
+
uint256 nonce;
|
|
134
|
+
address tokenA;
|
|
135
|
+
address tokenB;
|
|
136
|
+
uint256 amountA;
|
|
137
|
+
uint256 amountB;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @notice Metadata required for canceling an existing order
|
|
142
|
+
* @param nonce Unique nonce to prevent replay attacks
|
|
143
|
+
* @param tokenA Address of the first token in the market
|
|
144
|
+
* @param tokenB Address of the second token in the market
|
|
145
|
+
* @param orderId ID of the order to cancel
|
|
146
|
+
* @param signature User's signature authorizing the cancellation
|
|
147
|
+
*/
|
|
148
|
+
struct MetadataCancelOrder {
|
|
149
|
+
uint256 nonce;
|
|
150
|
+
address tokenA;
|
|
151
|
+
address tokenB;
|
|
152
|
+
uint256 orderId;
|
|
153
|
+
bytes signature;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @notice Metadata required for executing/filling an order
|
|
158
|
+
* @param nonce Unique nonce to prevent replay attacks
|
|
159
|
+
* @param tokenA Address of the first token in the market
|
|
160
|
+
* @param tokenB Address of the second token in the market
|
|
161
|
+
* @param orderId ID of the order to execute
|
|
162
|
+
* @param amountOfTokenBToFill Amount of tokenB to pay (including fees)
|
|
163
|
+
* @param signature User's signature authorizing the execution
|
|
164
|
+
*/
|
|
165
|
+
struct MetadataDispatchOrder {
|
|
166
|
+
uint256 nonce;
|
|
167
|
+
address tokenA;
|
|
168
|
+
address tokenB;
|
|
169
|
+
uint256 orderId;
|
|
170
|
+
uint256 amountOfTokenBToFill;
|
|
171
|
+
bytes signature;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/// @notice Current fee distribution percentages
|
|
175
|
+
Percentage rewardPercentage;
|
|
176
|
+
/// @notice Proposed new fee distribution percentages
|
|
177
|
+
Percentage rewardPercentage_proposal;
|
|
178
|
+
/// @notice Timestamp when reward percentage change can be accepted
|
|
179
|
+
uint256 rewardPercentage_timeToAcceptNewChange;
|
|
180
|
+
|
|
181
|
+
/// @notice Current trading fee percentage (in basis points)
|
|
182
|
+
uint256 percentageFee;
|
|
183
|
+
/// @notice Proposed new trading fee percentage
|
|
184
|
+
uint256 percentageFee_proposal;
|
|
185
|
+
/// @notice Timestamp when fee percentage change can be accepted
|
|
186
|
+
uint256 percentageFee_timeToAccept;
|
|
187
|
+
|
|
188
|
+
/// @notice Maximum fixed fee limit for order execution
|
|
189
|
+
uint256 maxLimitFillFixedFee;
|
|
190
|
+
/// @notice Proposed new maximum fixed fee limit
|
|
191
|
+
uint256 maxLimitFillFixedFee_proposal;
|
|
192
|
+
/// @notice Timestamp when max fee limit change can be accepted
|
|
193
|
+
uint256 maxLimitFillFixedFee_timeToAccept;
|
|
194
|
+
|
|
195
|
+
/// @notice Token address for pending withdrawal
|
|
196
|
+
address tokenToWithdraw;
|
|
197
|
+
/// @notice Amount for pending withdrawal
|
|
198
|
+
uint256 amountToWithdraw;
|
|
199
|
+
/// @notice Recipient address for pending withdrawal
|
|
200
|
+
address recipientToWithdraw;
|
|
201
|
+
/// @notice Timestamp when withdrawal can be executed
|
|
202
|
+
uint256 timeToWithdrawal;
|
|
203
|
+
|
|
204
|
+
/// @notice Total number of markets created
|
|
205
|
+
uint256 marketCount;
|
|
206
|
+
|
|
207
|
+
/// @notice Tracks used nonces per user to prevent replay attacks
|
|
208
|
+
mapping(address user => mapping(uint256 nonce => bool isUsed)) nonceP2PSwap;
|
|
209
|
+
|
|
210
|
+
/// @notice Maps token pairs to their market ID
|
|
211
|
+
mapping(address tokenA => mapping(address tokenB => uint256 id)) marketId;
|
|
212
|
+
|
|
213
|
+
/// @notice Stores market information by market ID
|
|
214
|
+
mapping(uint256 id => MarketInformation info) marketMetadata;
|
|
215
|
+
|
|
216
|
+
/// @notice Stores orders within each market
|
|
217
|
+
mapping(uint256 idMarket => mapping(uint256 idOrder => Order)) ordersInsideMarket;
|
|
218
|
+
|
|
219
|
+
/// @notice Tracks service fee balances accumulated per token
|
|
220
|
+
mapping(address => uint256) balancesOfContract;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* @notice Initializes the P2PSwap contract with required addresses and default parameters
|
|
224
|
+
* @param _evvmAddress Address of the EVVM core contract for payment processing
|
|
225
|
+
* @param _stakingAddress Address of the Staking contract for service functionality
|
|
226
|
+
* @param _owner Address that will have administrative privileges
|
|
227
|
+
*/
|
|
228
|
+
constructor(
|
|
229
|
+
address _evvmAddress,
|
|
230
|
+
address _stakingAddress,
|
|
231
|
+
address _owner
|
|
232
|
+
) StakingServiceHooks(_stakingAddress) {
|
|
233
|
+
evvmAddress = _evvmAddress;
|
|
234
|
+
owner = _owner;
|
|
235
|
+
maxLimitFillFixedFee = 0.001 ether;
|
|
236
|
+
percentageFee = 500;
|
|
237
|
+
rewardPercentage = Percentage({
|
|
238
|
+
seller: 5000,
|
|
239
|
+
service: 4000,
|
|
240
|
+
mateStaker: 1000
|
|
241
|
+
});
|
|
242
|
+
stakingAddress = _stakingAddress;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* @notice Creates a new trading order in the specified market
|
|
247
|
+
* @dev Verifies signature, processes payment, creates/finds market, and assigns order slot
|
|
248
|
+
* @param user Address of the user creating the order
|
|
249
|
+
* @param metadata Order details including tokens, amounts, and nonce
|
|
250
|
+
* @param signature User's signature authorizing the order creation
|
|
251
|
+
* @param _priorityFee_Evvm Priority fee for EVVM transaction processing
|
|
252
|
+
* @param _nonce_Evvm Nonce for EVVM payment transaction
|
|
253
|
+
* @param _priority_Evvm Whether to use priority (async) processing
|
|
254
|
+
* @param _signature_Evvm Signature for EVVM payment authorization
|
|
255
|
+
* @return market ID of the market where order was created
|
|
256
|
+
* @return orderId Unique ID of the created order within the market
|
|
257
|
+
*/
|
|
258
|
+
function makeOrder(
|
|
259
|
+
address user,
|
|
260
|
+
MetadataMakeOrder memory metadata,
|
|
261
|
+
bytes memory signature,
|
|
262
|
+
uint256 _priorityFee_Evvm,
|
|
263
|
+
uint256 _nonce_Evvm,
|
|
264
|
+
bool _priority_Evvm,
|
|
265
|
+
bytes memory _signature_Evvm
|
|
266
|
+
) external returns (uint256 market, uint256 orderId) {
|
|
267
|
+
if (
|
|
268
|
+
!SignatureUtils.verifyMessageSignedForMakeOrder(
|
|
269
|
+
Evvm(evvmAddress).getEvvmID(),
|
|
270
|
+
user,
|
|
271
|
+
metadata.nonce,
|
|
272
|
+
metadata.tokenA,
|
|
273
|
+
metadata.tokenB,
|
|
274
|
+
metadata.amountA,
|
|
275
|
+
metadata.amountB,
|
|
276
|
+
signature
|
|
277
|
+
)
|
|
278
|
+
) {
|
|
279
|
+
revert("Invalid signature");
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (nonceP2PSwap[user][metadata.nonce]) {
|
|
283
|
+
revert("Nonce already used");
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
makePay(
|
|
287
|
+
user,
|
|
288
|
+
metadata.tokenA,
|
|
289
|
+
_nonce_Evvm,
|
|
290
|
+
metadata.amountA,
|
|
291
|
+
_priorityFee_Evvm,
|
|
292
|
+
_priority_Evvm,
|
|
293
|
+
_signature_Evvm
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
market = findMarket(metadata.tokenA, metadata.tokenB);
|
|
297
|
+
if (market == 0) {
|
|
298
|
+
market = createMarket(metadata.tokenA, metadata.tokenB);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (
|
|
302
|
+
marketMetadata[market].maxSlot ==
|
|
303
|
+
marketMetadata[market].ordersAvailable
|
|
304
|
+
) {
|
|
305
|
+
marketMetadata[market].maxSlot++;
|
|
306
|
+
marketMetadata[market].ordersAvailable++;
|
|
307
|
+
orderId = marketMetadata[market].maxSlot;
|
|
308
|
+
} else {
|
|
309
|
+
for (uint256 i = 1; i <= marketMetadata[market].maxSlot + 1; i++) {
|
|
310
|
+
if (ordersInsideMarket[market][i].seller == address(0)) {
|
|
311
|
+
orderId = i;
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
marketMetadata[market].ordersAvailable++;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
ordersInsideMarket[market][orderId] = Order(
|
|
319
|
+
user,
|
|
320
|
+
metadata.amountA,
|
|
321
|
+
metadata.amountB
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
if (Evvm(evvmAddress).isAddressStaker(msg.sender)) {
|
|
325
|
+
if (_priorityFee_Evvm > 0) {
|
|
326
|
+
// send the executor the priorityFee
|
|
327
|
+
makeCaPay(msg.sender, metadata.tokenA, _priorityFee_Evvm);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// send some mate token reward to the executor (independent of the priorityFee the user attached)
|
|
331
|
+
makeCaPay(
|
|
332
|
+
msg.sender,
|
|
333
|
+
MATE_TOKEN_ADDRESS,
|
|
334
|
+
_priorityFee_Evvm > 0
|
|
335
|
+
? (Evvm(evvmAddress).getRewardAmount() * 3)
|
|
336
|
+
: (Evvm(evvmAddress).getRewardAmount() * 2)
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
nonceP2PSwap[user][metadata.nonce] = true;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* @notice Cancels an existing order and refunds tokens to the seller
|
|
345
|
+
* @dev Verifies signature, validates ownership, refunds tokenA, and removes order
|
|
346
|
+
* @param user Address of the user canceling the order
|
|
347
|
+
* @param metadata Cancel details including market info and order ID
|
|
348
|
+
* @param _priorityFee_Evvm Priority fee for EVVM transaction (optional)
|
|
349
|
+
* @param _nonce_Evvm Nonce for EVVM payment transaction (if priority fee > 0)
|
|
350
|
+
* @param _priority_Evvm Whether to use priority processing
|
|
351
|
+
* @param _signature_Evvm Signature for EVVM payment (if priority fee > 0)
|
|
352
|
+
*/
|
|
353
|
+
function cancelOrder(
|
|
354
|
+
address user,
|
|
355
|
+
MetadataCancelOrder memory metadata,
|
|
356
|
+
uint256 _priorityFee_Evvm,
|
|
357
|
+
uint256 _nonce_Evvm,
|
|
358
|
+
bool _priority_Evvm,
|
|
359
|
+
bytes memory _signature_Evvm
|
|
360
|
+
) external {
|
|
361
|
+
if (
|
|
362
|
+
!SignatureUtils.verifyMessageSignedForCancelOrder(
|
|
363
|
+
Evvm(evvmAddress).getEvvmID(),
|
|
364
|
+
user,
|
|
365
|
+
metadata.nonce,
|
|
366
|
+
metadata.tokenA,
|
|
367
|
+
metadata.tokenB,
|
|
368
|
+
metadata.orderId,
|
|
369
|
+
metadata.signature
|
|
370
|
+
)
|
|
371
|
+
) {
|
|
372
|
+
revert("Invalid signature");
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
uint256 market = findMarket(metadata.tokenA, metadata.tokenB);
|
|
376
|
+
|
|
377
|
+
if (nonceP2PSwap[user][metadata.nonce]) {
|
|
378
|
+
revert("Invalid nonce");
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if (
|
|
382
|
+
market == 0 ||
|
|
383
|
+
ordersInsideMarket[market][metadata.orderId].seller != user
|
|
384
|
+
) {
|
|
385
|
+
revert("Invalid order");
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if (_priorityFee_Evvm > 0) {
|
|
389
|
+
makePay(
|
|
390
|
+
user,
|
|
391
|
+
MATE_TOKEN_ADDRESS,
|
|
392
|
+
_nonce_Evvm,
|
|
393
|
+
0,
|
|
394
|
+
_priorityFee_Evvm,
|
|
395
|
+
_priority_Evvm,
|
|
396
|
+
_signature_Evvm
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
makeCaPay(
|
|
401
|
+
user,
|
|
402
|
+
metadata.tokenA,
|
|
403
|
+
ordersInsideMarket[market][metadata.orderId].amountA
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
ordersInsideMarket[market][metadata.orderId].seller = address(0);
|
|
407
|
+
|
|
408
|
+
if (Evvm(evvmAddress).isAddressStaker(msg.sender)) {
|
|
409
|
+
makeCaPay(
|
|
410
|
+
msg.sender,
|
|
411
|
+
MATE_TOKEN_ADDRESS,
|
|
412
|
+
_priorityFee_Evvm > 0
|
|
413
|
+
? ((Evvm(evvmAddress).getRewardAmount() * 3) +
|
|
414
|
+
_priorityFee_Evvm)
|
|
415
|
+
: (Evvm(evvmAddress).getRewardAmount() * 2)
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
marketMetadata[market].ordersAvailable--;
|
|
419
|
+
nonceP2PSwap[user][metadata.nonce] = true;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* @notice Executes an order using proportional fee calculation
|
|
424
|
+
* @dev Calculates fee as percentage of order amount, distributes payments to all parties
|
|
425
|
+
* @param user Address of the user filling the order
|
|
426
|
+
* @param metadata Execution details including order ID and payment amount
|
|
427
|
+
* @param _priorityFee_Evvm Priority fee for EVVM transaction processing
|
|
428
|
+
* @param _nonce_Evvm Nonce for EVVM payment transaction
|
|
429
|
+
* @param _priority_Evvm Whether to use priority (async) processing
|
|
430
|
+
* @param _signature_Evvm Signature for EVVM payment authorization
|
|
431
|
+
*/
|
|
432
|
+
function dispatchOrder_fillPropotionalFee(
|
|
433
|
+
address user,
|
|
434
|
+
MetadataDispatchOrder memory metadata,
|
|
435
|
+
uint256 _priorityFee_Evvm,
|
|
436
|
+
uint256 _nonce_Evvm,
|
|
437
|
+
bool _priority_Evvm,
|
|
438
|
+
bytes memory _signature_Evvm
|
|
439
|
+
) external {
|
|
440
|
+
if (
|
|
441
|
+
!SignatureUtils.verifyMessageSignedForDispatchOrder(
|
|
442
|
+
Evvm(evvmAddress).getEvvmID(),
|
|
443
|
+
user,
|
|
444
|
+
metadata.nonce,
|
|
445
|
+
metadata.tokenA,
|
|
446
|
+
metadata.tokenB,
|
|
447
|
+
metadata.orderId,
|
|
448
|
+
metadata.signature
|
|
449
|
+
)
|
|
450
|
+
) {
|
|
451
|
+
revert("Invalid signature");
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
uint256 market = findMarket(metadata.tokenA, metadata.tokenB);
|
|
455
|
+
|
|
456
|
+
if (nonceP2PSwap[user][metadata.nonce]) {
|
|
457
|
+
revert("Invalid nonce");
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
if (
|
|
461
|
+
market == 0 ||
|
|
462
|
+
ordersInsideMarket[market][metadata.orderId].seller == address(0)
|
|
463
|
+
) {
|
|
464
|
+
revert();
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
uint256 fee = calculateFillPropotionalFee(
|
|
468
|
+
ordersInsideMarket[market][metadata.orderId].amountB
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
if (
|
|
472
|
+
metadata.amountOfTokenBToFill <
|
|
473
|
+
ordersInsideMarket[market][metadata.orderId].amountB + fee
|
|
474
|
+
) {
|
|
475
|
+
revert("Insuficient amountOfTokenToFill");
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
makePay(
|
|
479
|
+
user,
|
|
480
|
+
metadata.tokenB,
|
|
481
|
+
_nonce_Evvm,
|
|
482
|
+
metadata.amountOfTokenBToFill,
|
|
483
|
+
_priorityFee_Evvm,
|
|
484
|
+
_priority_Evvm,
|
|
485
|
+
_signature_Evvm
|
|
486
|
+
);
|
|
487
|
+
|
|
488
|
+
// si es mas del fee + el monto de la orden hacemos caPay al usuario del sobranate
|
|
489
|
+
if (
|
|
490
|
+
metadata.amountOfTokenBToFill >
|
|
491
|
+
ordersInsideMarket[market][metadata.orderId].amountB + fee
|
|
492
|
+
) {
|
|
493
|
+
makeCaPay(
|
|
494
|
+
user,
|
|
495
|
+
metadata.tokenB,
|
|
496
|
+
metadata.amountOfTokenBToFill -
|
|
497
|
+
(ordersInsideMarket[market][metadata.orderId].amountB + fee)
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
EvvmStructs.DisperseCaPayMetadata[]
|
|
502
|
+
memory toData = new EvvmStructs.DisperseCaPayMetadata[](2);
|
|
503
|
+
|
|
504
|
+
uint256 sellerAmount = ordersInsideMarket[market][metadata.orderId]
|
|
505
|
+
.amountB + ((fee * rewardPercentage.seller) / 10_000);
|
|
506
|
+
uint256 executorAmount = _priorityFee_Evvm +
|
|
507
|
+
((fee * rewardPercentage.mateStaker) / 10_000);
|
|
508
|
+
|
|
509
|
+
// pay seller
|
|
510
|
+
toData[0] = EvvmStructs.DisperseCaPayMetadata(
|
|
511
|
+
sellerAmount,
|
|
512
|
+
ordersInsideMarket[market][metadata.orderId].seller
|
|
513
|
+
);
|
|
514
|
+
// pay executor
|
|
515
|
+
toData[1] = EvvmStructs.DisperseCaPayMetadata(
|
|
516
|
+
executorAmount,
|
|
517
|
+
msg.sender
|
|
518
|
+
);
|
|
519
|
+
|
|
520
|
+
balancesOfContract[metadata.tokenB] +=
|
|
521
|
+
(fee * rewardPercentage.service) /
|
|
522
|
+
10_000;
|
|
523
|
+
|
|
524
|
+
makeDisperseCaPay(
|
|
525
|
+
toData,
|
|
526
|
+
metadata.tokenB,
|
|
527
|
+
toData[0].amount + toData[1].amount
|
|
528
|
+
);
|
|
529
|
+
|
|
530
|
+
// pay user with token A
|
|
531
|
+
makeCaPay(
|
|
532
|
+
user,
|
|
533
|
+
metadata.tokenA,
|
|
534
|
+
ordersInsideMarket[market][metadata.orderId].amountA
|
|
535
|
+
);
|
|
536
|
+
|
|
537
|
+
if (Evvm(evvmAddress).isAddressStaker(msg.sender)) {
|
|
538
|
+
makeCaPay(
|
|
539
|
+
msg.sender,
|
|
540
|
+
MATE_TOKEN_ADDRESS,
|
|
541
|
+
metadata.amountOfTokenBToFill >
|
|
542
|
+
ordersInsideMarket[market][metadata.orderId].amountB + fee
|
|
543
|
+
? Evvm(evvmAddress).getRewardAmount() * 5
|
|
544
|
+
: Evvm(evvmAddress).getRewardAmount() * 4
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
ordersInsideMarket[market][metadata.orderId].seller = address(0);
|
|
549
|
+
marketMetadata[market].ordersAvailable--;
|
|
550
|
+
nonceP2PSwap[user][metadata.nonce] = true;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* @notice Executes an order using fixed fee calculation with maximum limits
|
|
555
|
+
* @dev Calculates fee with upper bound, distributes payments, handles overpayment refunds
|
|
556
|
+
* @param user Address of the user filling the order
|
|
557
|
+
* @param metadata Execution details including order ID and payment amount
|
|
558
|
+
* @param _priorityFee_Evvm Priority fee for EVVM transaction processing
|
|
559
|
+
* @param _nonce_Evvm Nonce for EVVM payment transaction
|
|
560
|
+
* @param _priority_Evvm Whether to use priority (async) processing
|
|
561
|
+
* @param _signature_Evvm Signature for EVVM payment authorization
|
|
562
|
+
* @param maxFillFixedFee Maximum output amount for fee calculation (testing parameter)
|
|
563
|
+
*/
|
|
564
|
+
function dispatchOrder_fillFixedFee(
|
|
565
|
+
address user,
|
|
566
|
+
MetadataDispatchOrder memory metadata,
|
|
567
|
+
uint256 _priorityFee_Evvm,
|
|
568
|
+
uint256 _nonce_Evvm,
|
|
569
|
+
bool _priority_Evvm,
|
|
570
|
+
bytes memory _signature_Evvm,
|
|
571
|
+
uint256 maxFillFixedFee
|
|
572
|
+
) external {
|
|
573
|
+
if (
|
|
574
|
+
!SignatureUtils.verifyMessageSignedForDispatchOrder(
|
|
575
|
+
Evvm(evvmAddress).getEvvmID(),
|
|
576
|
+
user,
|
|
577
|
+
metadata.nonce,
|
|
578
|
+
metadata.tokenA,
|
|
579
|
+
metadata.tokenB,
|
|
580
|
+
metadata.orderId,
|
|
581
|
+
metadata.signature
|
|
582
|
+
)
|
|
583
|
+
) {
|
|
584
|
+
revert();
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
uint256 market = findMarket(metadata.tokenA, metadata.tokenB);
|
|
588
|
+
|
|
589
|
+
if (nonceP2PSwap[user][metadata.nonce]) {
|
|
590
|
+
revert();
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
if (
|
|
594
|
+
market == 0 ||
|
|
595
|
+
ordersInsideMarket[market][metadata.orderId].seller == address(0)
|
|
596
|
+
) {
|
|
597
|
+
revert();
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
(uint256 fee, uint256 fee10) = calculateFillFixedFee(
|
|
601
|
+
ordersInsideMarket[market][metadata.orderId].amountB,
|
|
602
|
+
maxFillFixedFee
|
|
603
|
+
);
|
|
604
|
+
|
|
605
|
+
if (
|
|
606
|
+
metadata.amountOfTokenBToFill <
|
|
607
|
+
ordersInsideMarket[market][metadata.orderId].amountB + fee - fee10
|
|
608
|
+
) {
|
|
609
|
+
revert();
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
makePay(
|
|
613
|
+
user,
|
|
614
|
+
metadata.tokenB,
|
|
615
|
+
_nonce_Evvm,
|
|
616
|
+
metadata.amountOfTokenBToFill,
|
|
617
|
+
_priorityFee_Evvm,
|
|
618
|
+
_priority_Evvm,
|
|
619
|
+
_signature_Evvm
|
|
620
|
+
);
|
|
621
|
+
|
|
622
|
+
uint256 finalFee = metadata.amountOfTokenBToFill >=
|
|
623
|
+
ordersInsideMarket[market][metadata.orderId].amountB +
|
|
624
|
+
fee -
|
|
625
|
+
fee10 &&
|
|
626
|
+
metadata.amountOfTokenBToFill <
|
|
627
|
+
ordersInsideMarket[market][metadata.orderId].amountB + fee
|
|
628
|
+
? metadata.amountOfTokenBToFill -
|
|
629
|
+
ordersInsideMarket[market][metadata.orderId].amountB
|
|
630
|
+
: fee;
|
|
631
|
+
|
|
632
|
+
// si es mas del fee + el monto de la orden hacemos caPay al usuario del sobranate
|
|
633
|
+
if (
|
|
634
|
+
metadata.amountOfTokenBToFill >
|
|
635
|
+
ordersInsideMarket[market][metadata.orderId].amountB + fee
|
|
636
|
+
) {
|
|
637
|
+
makeCaPay(
|
|
638
|
+
user,
|
|
639
|
+
metadata.tokenB,
|
|
640
|
+
metadata.amountOfTokenBToFill -
|
|
641
|
+
(ordersInsideMarket[market][metadata.orderId].amountB + fee)
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
EvvmStructs.DisperseCaPayMetadata[]
|
|
646
|
+
memory toData = new EvvmStructs.DisperseCaPayMetadata[](2);
|
|
647
|
+
|
|
648
|
+
toData[0] = EvvmStructs.DisperseCaPayMetadata(
|
|
649
|
+
ordersInsideMarket[market][metadata.orderId].amountB +
|
|
650
|
+
((finalFee * rewardPercentage.seller) / 10_000),
|
|
651
|
+
ordersInsideMarket[market][metadata.orderId].seller
|
|
652
|
+
);
|
|
653
|
+
toData[1] = EvvmStructs.DisperseCaPayMetadata(
|
|
654
|
+
_priorityFee_Evvm +
|
|
655
|
+
((finalFee * rewardPercentage.mateStaker) / 10_000),
|
|
656
|
+
msg.sender
|
|
657
|
+
);
|
|
658
|
+
|
|
659
|
+
balancesOfContract[metadata.tokenB] +=
|
|
660
|
+
(finalFee * rewardPercentage.service) /
|
|
661
|
+
10_000;
|
|
662
|
+
|
|
663
|
+
makeDisperseCaPay(
|
|
664
|
+
toData,
|
|
665
|
+
metadata.tokenB,
|
|
666
|
+
toData[0].amount + toData[1].amount
|
|
667
|
+
);
|
|
668
|
+
|
|
669
|
+
makeCaPay(
|
|
670
|
+
user,
|
|
671
|
+
metadata.tokenA,
|
|
672
|
+
ordersInsideMarket[market][metadata.orderId].amountA
|
|
673
|
+
);
|
|
674
|
+
|
|
675
|
+
if (Evvm(evvmAddress).isAddressStaker(msg.sender)) {
|
|
676
|
+
makeCaPay(
|
|
677
|
+
msg.sender,
|
|
678
|
+
MATE_TOKEN_ADDRESS,
|
|
679
|
+
metadata.amountOfTokenBToFill >
|
|
680
|
+
ordersInsideMarket[market][metadata.orderId].amountB + fee
|
|
681
|
+
? Evvm(evvmAddress).getRewardAmount() * 5
|
|
682
|
+
: Evvm(evvmAddress).getRewardAmount() * 4
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
ordersInsideMarket[market][metadata.orderId].seller = address(0);
|
|
687
|
+
marketMetadata[market].ordersAvailable--;
|
|
688
|
+
nonceP2PSwap[user][metadata.nonce] = true;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* @notice Calculates proportional trading fee as percentage of order amount
|
|
693
|
+
* @dev Fee is calculated as (amount * percentageFee) / 10,000 basis points
|
|
694
|
+
* @param amount The order amount to calculate fee for
|
|
695
|
+
* @return fee The calculated proportional fee amount
|
|
696
|
+
*/
|
|
697
|
+
function calculateFillPropotionalFee(
|
|
698
|
+
uint256 amount
|
|
699
|
+
) internal view returns (uint256 fee) {
|
|
700
|
+
fee = (amount * percentageFee) / 10_000;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* @notice Calculates fixed trading fee with maximum limit constraints
|
|
705
|
+
* @dev Compares proportional fee with maximum output, applies 10% reduction if needed
|
|
706
|
+
* @param amount Order amount for proportional fee calculation
|
|
707
|
+
* @param maxFillFixedFee Maximum output amount for fee limiting
|
|
708
|
+
* @return fee The final calculated fee amount
|
|
709
|
+
* @return fee10 10% of the fee amount for specific calculations
|
|
710
|
+
*/
|
|
711
|
+
function calculateFillFixedFee(
|
|
712
|
+
uint256 amount,
|
|
713
|
+
uint256 maxFillFixedFee
|
|
714
|
+
) internal view returns (uint256 fee, uint256 fee10) {
|
|
715
|
+
if (calculateFillPropotionalFee(amount) > maxFillFixedFee) {
|
|
716
|
+
fee = maxFillFixedFee;
|
|
717
|
+
fee10 = (fee * 1000) / 10_000;
|
|
718
|
+
} else {
|
|
719
|
+
fee = calculateFillPropotionalFee(amount);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* @notice Creates a new trading market for a token pair
|
|
725
|
+
* @dev Increments market count, assigns market ID, initializes market metadata
|
|
726
|
+
* @param tokenA Address of the first token in the trading pair
|
|
727
|
+
* @param tokenB Address of the second token in the trading pair
|
|
728
|
+
* @return The newly created market ID
|
|
729
|
+
*/
|
|
730
|
+
function createMarket(
|
|
731
|
+
address tokenA,
|
|
732
|
+
address tokenB
|
|
733
|
+
) internal returns (uint256) {
|
|
734
|
+
marketCount++;
|
|
735
|
+
marketId[tokenA][tokenB] = marketCount;
|
|
736
|
+
marketMetadata[marketCount] = MarketInformation(tokenA, tokenB, 0, 0);
|
|
737
|
+
return marketCount;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
//◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢
|
|
741
|
+
// Tools for Evvm
|
|
742
|
+
//◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* @notice Internal function to process payments through EVVM contract
|
|
746
|
+
* @dev Calls EVVM.pay() with all necessary parameters for token transfer
|
|
747
|
+
* @param _user_Evvm Address of the user making the payment
|
|
748
|
+
* @param _token_Evvm Address of the token being transferred
|
|
749
|
+
* @param _nonce_Evvm Nonce for the EVVM transaction
|
|
750
|
+
* @param _ammount_Evvm Amount of tokens to transfer
|
|
751
|
+
* @param _priorityFee_Evvm Additional priority fee for the transaction
|
|
752
|
+
* @param _priority_Evvm Whether to use priority (async) processing
|
|
753
|
+
* @param _signature_Evvm User's signature authorizing the payment
|
|
754
|
+
*/
|
|
755
|
+
function makePay(
|
|
756
|
+
address _user_Evvm,
|
|
757
|
+
address _token_Evvm,
|
|
758
|
+
uint256 _nonce_Evvm,
|
|
759
|
+
uint256 _ammount_Evvm,
|
|
760
|
+
uint256 _priorityFee_Evvm,
|
|
761
|
+
bool _priority_Evvm,
|
|
762
|
+
bytes memory _signature_Evvm
|
|
763
|
+
) internal {
|
|
764
|
+
Evvm(evvmAddress).pay(
|
|
765
|
+
_user_Evvm,
|
|
766
|
+
address(this),
|
|
767
|
+
"",
|
|
768
|
+
_token_Evvm,
|
|
769
|
+
_ammount_Evvm,
|
|
770
|
+
_priorityFee_Evvm,
|
|
771
|
+
_nonce_Evvm,
|
|
772
|
+
_priority_Evvm,
|
|
773
|
+
address(this),
|
|
774
|
+
_signature_Evvm
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* @notice Internal function to distribute tokens from contract balance via EVVM
|
|
780
|
+
* @dev Calls EVVM.caPay() to transfer tokens from P2PSwap to specified user
|
|
781
|
+
* @param _user_Evvm Address of the recipient
|
|
782
|
+
* @param _token_Evvm Address of the token to transfer
|
|
783
|
+
* @param _ammount_Evvm Amount of tokens to transfer
|
|
784
|
+
*/
|
|
785
|
+
function makeCaPay(
|
|
786
|
+
address _user_Evvm,
|
|
787
|
+
address _token_Evvm,
|
|
788
|
+
uint256 _ammount_Evvm
|
|
789
|
+
) internal {
|
|
790
|
+
Evvm(evvmAddress).caPay(_user_Evvm, _token_Evvm, _ammount_Evvm);
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
/**
|
|
794
|
+
* @notice Internal function to distribute tokens to multiple recipients via EVVM
|
|
795
|
+
* @dev Calls EVVM.disperseCaPay() for efficient batch token distribution
|
|
796
|
+
* @param toData Array of recipient addresses and amounts
|
|
797
|
+
* @param token Address of the token to distribute
|
|
798
|
+
* @param amount Total amount being distributed (must match sum of individual amounts)
|
|
799
|
+
*/
|
|
800
|
+
function makeDisperseCaPay(
|
|
801
|
+
EvvmStructs.DisperseCaPayMetadata[] memory toData,
|
|
802
|
+
address token,
|
|
803
|
+
uint256 amount
|
|
804
|
+
) internal {
|
|
805
|
+
Evvm(evvmAddress).disperseCaPay(toData, token, amount);
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
//◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢
|
|
809
|
+
// Admin tools
|
|
810
|
+
//◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢
|
|
811
|
+
|
|
812
|
+
/**
|
|
813
|
+
* @notice Proposes a new contract owner with 1-day delay
|
|
814
|
+
* @dev Only current owner can propose, starts time-delayed governance process
|
|
815
|
+
* @param _owner Address of the proposed new owner
|
|
816
|
+
*/
|
|
817
|
+
function proposeOwner(address _owner) external {
|
|
818
|
+
if (msg.sender != owner) {
|
|
819
|
+
revert();
|
|
820
|
+
}
|
|
821
|
+
owner_proposal = _owner;
|
|
822
|
+
owner_timeToAccept = block.timestamp + 1 days;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* @notice Rejects the current owner change proposal
|
|
827
|
+
* @dev Only proposed owner can reject before deadline expires
|
|
828
|
+
*/
|
|
829
|
+
function rejectProposeOwner() external {
|
|
830
|
+
if (
|
|
831
|
+
msg.sender != owner_proposal || block.timestamp > owner_timeToAccept
|
|
832
|
+
) {
|
|
833
|
+
revert();
|
|
834
|
+
}
|
|
835
|
+
owner_proposal = address(0);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* @notice Accepts ownership transfer after time delay
|
|
840
|
+
* @dev Only proposed owner can accept after 1-day waiting period
|
|
841
|
+
*/
|
|
842
|
+
function acceptOwner() external {
|
|
843
|
+
if (
|
|
844
|
+
msg.sender != owner_proposal || block.timestamp > owner_timeToAccept
|
|
845
|
+
) {
|
|
846
|
+
revert();
|
|
847
|
+
}
|
|
848
|
+
owner = owner_proposal;
|
|
849
|
+
owner_proposal = address(0);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/**
|
|
853
|
+
* @notice Proposes new fee distribution percentages for fixed fee model
|
|
854
|
+
* @dev Percentages must sum to 10,000 basis points (100%)
|
|
855
|
+
* @param _seller Percentage for order sellers (basis points)
|
|
856
|
+
* @param _service Percentage for P2PSwap service (basis points)
|
|
857
|
+
* @param _mateStaker Percentage for MATE token stakers (basis points)
|
|
858
|
+
*/
|
|
859
|
+
function proposeFillFixedPercentage(
|
|
860
|
+
uint256 _seller,
|
|
861
|
+
uint256 _service,
|
|
862
|
+
uint256 _mateStaker
|
|
863
|
+
) external {
|
|
864
|
+
if (msg.sender != owner) {
|
|
865
|
+
revert();
|
|
866
|
+
}
|
|
867
|
+
if (_seller + _service + _mateStaker != 10_000) {
|
|
868
|
+
revert();
|
|
869
|
+
}
|
|
870
|
+
rewardPercentage_proposal = Percentage(_seller, _service, _mateStaker);
|
|
871
|
+
rewardPercentage_timeToAcceptNewChange = block.timestamp + 1 days;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
/**
|
|
875
|
+
* @notice Rejects the current fee percentage proposal for fixed fee model
|
|
876
|
+
* @dev Only owner can reject before deadline expires, resets proposal to zero
|
|
877
|
+
*/
|
|
878
|
+
function rejectProposeFillFixedPercentage() external {
|
|
879
|
+
if (
|
|
880
|
+
msg.sender != owner ||
|
|
881
|
+
block.timestamp > rewardPercentage_timeToAcceptNewChange
|
|
882
|
+
) {
|
|
883
|
+
revert();
|
|
884
|
+
}
|
|
885
|
+
rewardPercentage_proposal = Percentage(0, 0, 0);
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* @notice Accepts the fee percentage proposal for fixed fee model after time delay
|
|
890
|
+
* @dev Only owner can accept after 1-day waiting period, applies new percentages
|
|
891
|
+
*/
|
|
892
|
+
function acceptFillFixedPercentage() external {
|
|
893
|
+
if (
|
|
894
|
+
msg.sender != owner ||
|
|
895
|
+
block.timestamp > rewardPercentage_timeToAcceptNewChange
|
|
896
|
+
) {
|
|
897
|
+
revert();
|
|
898
|
+
}
|
|
899
|
+
rewardPercentage = rewardPercentage_proposal;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
/**
|
|
903
|
+
* @notice Proposes new fee distribution percentages for proportional fee model
|
|
904
|
+
* @dev Percentages must sum to 10,000 basis points (100%)
|
|
905
|
+
* @param _seller Percentage for order sellers (basis points)
|
|
906
|
+
* @param _service Percentage for P2PSwap service (basis points)
|
|
907
|
+
* @param _mateStaker Percentage for MATE token stakers (basis points)
|
|
908
|
+
*/
|
|
909
|
+
function proposeFillPropotionalPercentage(
|
|
910
|
+
uint256 _seller,
|
|
911
|
+
uint256 _service,
|
|
912
|
+
uint256 _mateStaker
|
|
913
|
+
) external {
|
|
914
|
+
if (msg.sender != owner || _seller + _service + _mateStaker != 10_000) {
|
|
915
|
+
revert();
|
|
916
|
+
}
|
|
917
|
+
rewardPercentage_proposal = Percentage(_seller, _service, _mateStaker);
|
|
918
|
+
rewardPercentage_timeToAcceptNewChange = block.timestamp + 1 days;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* @notice Rejects the current fee percentage proposal for proportional fee model
|
|
923
|
+
* @dev Only owner can reject before deadline expires, resets proposal to zero
|
|
924
|
+
*/
|
|
925
|
+
function rejectProposeFillPropotionalPercentage() external {
|
|
926
|
+
if (
|
|
927
|
+
msg.sender != owner ||
|
|
928
|
+
block.timestamp > rewardPercentage_timeToAcceptNewChange
|
|
929
|
+
) {
|
|
930
|
+
revert();
|
|
931
|
+
}
|
|
932
|
+
rewardPercentage_proposal = Percentage(0, 0, 0);
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* @notice Accepts the fee percentage proposal for proportional fee model after time delay
|
|
937
|
+
* @dev Only owner can accept after 1-day waiting period, applies new percentages
|
|
938
|
+
*/
|
|
939
|
+
function acceptFillPropotionalPercentage() external {
|
|
940
|
+
if (
|
|
941
|
+
msg.sender != owner ||
|
|
942
|
+
block.timestamp > rewardPercentage_timeToAcceptNewChange
|
|
943
|
+
) {
|
|
944
|
+
revert();
|
|
945
|
+
}
|
|
946
|
+
rewardPercentage = rewardPercentage_proposal;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
/**
|
|
950
|
+
* @notice Proposes a new percentage fee for proportional fee calculation
|
|
951
|
+
* @dev Only owner can propose, starts time-delayed governance process
|
|
952
|
+
* @param _percentageFee New percentage fee value in basis points
|
|
953
|
+
*/
|
|
954
|
+
function proposePercentageFee(uint256 _percentageFee) external {
|
|
955
|
+
if (msg.sender != owner) {
|
|
956
|
+
revert();
|
|
957
|
+
}
|
|
958
|
+
percentageFee_proposal = _percentageFee;
|
|
959
|
+
percentageFee_timeToAccept = block.timestamp + 1 days;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* @notice Rejects the current percentage fee proposal
|
|
964
|
+
* @dev Only owner can reject before deadline expires, resets proposal to zero
|
|
965
|
+
*/
|
|
966
|
+
function rejectProposePercentageFee() external {
|
|
967
|
+
if (
|
|
968
|
+
msg.sender != owner || block.timestamp > percentageFee_timeToAccept
|
|
969
|
+
) {
|
|
970
|
+
revert();
|
|
971
|
+
}
|
|
972
|
+
percentageFee_proposal = 0;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
/**
|
|
976
|
+
* @notice Accepts the percentage fee proposal after time delay
|
|
977
|
+
* @dev Only owner can accept after 1-day waiting period, applies new fee
|
|
978
|
+
*/
|
|
979
|
+
function acceptPercentageFee() external {
|
|
980
|
+
if (
|
|
981
|
+
msg.sender != owner || block.timestamp > percentageFee_timeToAccept
|
|
982
|
+
) {
|
|
983
|
+
revert();
|
|
984
|
+
}
|
|
985
|
+
percentageFee = percentageFee_proposal;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
/**
|
|
989
|
+
* @notice Proposes a new maximum limit for fixed fee calculations
|
|
990
|
+
* @dev Only owner can propose, starts time-delayed governance process
|
|
991
|
+
* @param _maxLimitFillFixedFee New maximum limit value for fixed fee calculations
|
|
992
|
+
*/
|
|
993
|
+
function proposeMaxLimitFillFixedFee(
|
|
994
|
+
uint256 _maxLimitFillFixedFee
|
|
995
|
+
) external {
|
|
996
|
+
if (msg.sender != owner) {
|
|
997
|
+
revert();
|
|
998
|
+
}
|
|
999
|
+
maxLimitFillFixedFee_proposal = _maxLimitFillFixedFee;
|
|
1000
|
+
maxLimitFillFixedFee_timeToAccept = block.timestamp + 1 days;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
/**
|
|
1004
|
+
* @notice Rejects the current maximum limit proposal for fixed fees
|
|
1005
|
+
* @dev Only owner can reject before deadline expires, resets proposal to zero
|
|
1006
|
+
*/
|
|
1007
|
+
function rejectProposeMaxLimitFillFixedFee() external {
|
|
1008
|
+
if (
|
|
1009
|
+
msg.sender != owner ||
|
|
1010
|
+
block.timestamp > maxLimitFillFixedFee_timeToAccept
|
|
1011
|
+
) {
|
|
1012
|
+
revert();
|
|
1013
|
+
}
|
|
1014
|
+
maxLimitFillFixedFee_proposal = 0;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
/**
|
|
1018
|
+
* @notice Accepts the maximum limit proposal for fixed fees after time delay
|
|
1019
|
+
* @dev Only owner can accept after 1-day waiting period, applies new limit
|
|
1020
|
+
*/
|
|
1021
|
+
function acceptMaxLimitFillFixedFee() external {
|
|
1022
|
+
if (
|
|
1023
|
+
msg.sender != owner ||
|
|
1024
|
+
block.timestamp > maxLimitFillFixedFee_timeToAccept
|
|
1025
|
+
) {
|
|
1026
|
+
revert();
|
|
1027
|
+
}
|
|
1028
|
+
maxLimitFillFixedFee = maxLimitFillFixedFee_proposal;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* @notice Proposes withdrawal of accumulated service fees
|
|
1033
|
+
* @dev Only owner can propose, amount must not exceed available balance
|
|
1034
|
+
* @param _tokenToWithdraw Address of token to withdraw
|
|
1035
|
+
* @param _amountToWithdraw Amount of tokens to withdraw
|
|
1036
|
+
* @param _to Recipient address for the withdrawal
|
|
1037
|
+
*/
|
|
1038
|
+
function proposeWithdrawal(
|
|
1039
|
+
address _tokenToWithdraw,
|
|
1040
|
+
uint256 _amountToWithdraw,
|
|
1041
|
+
address _to
|
|
1042
|
+
) external {
|
|
1043
|
+
if (
|
|
1044
|
+
msg.sender != owner ||
|
|
1045
|
+
_amountToWithdraw > balancesOfContract[_tokenToWithdraw]
|
|
1046
|
+
) {
|
|
1047
|
+
revert();
|
|
1048
|
+
}
|
|
1049
|
+
tokenToWithdraw = _tokenToWithdraw;
|
|
1050
|
+
amountToWithdraw = _amountToWithdraw;
|
|
1051
|
+
recipientToWithdraw = _to;
|
|
1052
|
+
timeToWithdrawal = block.timestamp + 1 days;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
/**
|
|
1056
|
+
* @notice Rejects the current withdrawal proposal
|
|
1057
|
+
* @dev Only owner can reject before deadline expires, clears all withdrawal data
|
|
1058
|
+
*/
|
|
1059
|
+
function rejectProposeWithdrawal() external {
|
|
1060
|
+
if (msg.sender != owner || block.timestamp > timeToWithdrawal) {
|
|
1061
|
+
revert();
|
|
1062
|
+
}
|
|
1063
|
+
tokenToWithdraw = address(0);
|
|
1064
|
+
amountToWithdraw = 0;
|
|
1065
|
+
recipientToWithdraw = address(0);
|
|
1066
|
+
timeToWithdrawal = 0;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* @notice Executes the withdrawal proposal after time delay
|
|
1071
|
+
* @dev Transfers tokens via EVVM, updates balance, and clears withdrawal data
|
|
1072
|
+
*/
|
|
1073
|
+
function acceptWithdrawal() external {
|
|
1074
|
+
if (msg.sender != owner || block.timestamp > timeToWithdrawal) {
|
|
1075
|
+
revert();
|
|
1076
|
+
}
|
|
1077
|
+
makeCaPay(recipientToWithdraw, tokenToWithdraw, amountToWithdraw);
|
|
1078
|
+
balancesOfContract[tokenToWithdraw] -= amountToWithdraw;
|
|
1079
|
+
|
|
1080
|
+
tokenToWithdraw = address(0);
|
|
1081
|
+
amountToWithdraw = 0;
|
|
1082
|
+
recipientToWithdraw = address(0);
|
|
1083
|
+
timeToWithdrawal = 0;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
/**
|
|
1087
|
+
* @notice Stakes accumulated MATE tokens using service staking functionality
|
|
1088
|
+
* @dev Only owner can stake, requires sufficient MATE token balance
|
|
1089
|
+
* @param amount Number of staking tokens to stake (not MATE token amount)
|
|
1090
|
+
*/
|
|
1091
|
+
function stake(uint256 amount) external {
|
|
1092
|
+
if (
|
|
1093
|
+
msg.sender != owner ||
|
|
1094
|
+
amount * Staking(stakingAddress).priceOfStaking() >
|
|
1095
|
+
balancesOfContract[0x0000000000000000000000000000000000000001]
|
|
1096
|
+
) revert();
|
|
1097
|
+
|
|
1098
|
+
_makeStakeService(amount);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
/**
|
|
1102
|
+
* @notice Unstakes service staking tokens and receives MATE tokens
|
|
1103
|
+
* @dev Only owner can unstake, subject to staking contract time locks
|
|
1104
|
+
* @param amount Number of staking tokens to unstake
|
|
1105
|
+
*/
|
|
1106
|
+
function unstake(uint256 amount) external {
|
|
1107
|
+
if (msg.sender != owner) revert();
|
|
1108
|
+
|
|
1109
|
+
_makeUnstakeService(amount);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
/**
|
|
1113
|
+
* @notice Manually adds balance to the contract for a specific token
|
|
1114
|
+
* @dev Only owner can add balance, useful for reconciling accounting discrepancies
|
|
1115
|
+
* @param _token Address of the token to add balance for
|
|
1116
|
+
* @param _amount Amount to add to the contract's balance tracking
|
|
1117
|
+
*/
|
|
1118
|
+
function addBalance(address _token, uint256 _amount) external {
|
|
1119
|
+
if (msg.sender != owner) {
|
|
1120
|
+
revert();
|
|
1121
|
+
}
|
|
1122
|
+
balancesOfContract[_token] += _amount;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
//◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢
|
|
1126
|
+
//getters
|
|
1127
|
+
//◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢
|
|
1128
|
+
/**
|
|
1129
|
+
* @notice Retrieves all active orders in a specific market
|
|
1130
|
+
* @dev Returns array with extended order information including market and order IDs
|
|
1131
|
+
* @param market The market ID to query orders from
|
|
1132
|
+
* @return orders Array of OrderForGetter structs containing all active orders
|
|
1133
|
+
*/
|
|
1134
|
+
function getAllMarketOrders(
|
|
1135
|
+
uint256 market
|
|
1136
|
+
) public view returns (OrderForGetter[] memory orders) {
|
|
1137
|
+
orders = new OrderForGetter[](marketMetadata[market].maxSlot + 1);
|
|
1138
|
+
|
|
1139
|
+
for (uint256 i = 1; i <= marketMetadata[market].maxSlot + 1; i++) {
|
|
1140
|
+
if (ordersInsideMarket[market][i].seller != address(0)) {
|
|
1141
|
+
orders[i - 1] = OrderForGetter(
|
|
1142
|
+
market,
|
|
1143
|
+
i,
|
|
1144
|
+
ordersInsideMarket[market][i].seller,
|
|
1145
|
+
ordersInsideMarket[market][i].amountA,
|
|
1146
|
+
ordersInsideMarket[market][i].amountB
|
|
1147
|
+
);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
return orders;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
/**
|
|
1154
|
+
* @notice Retrieves a specific order by market and order ID
|
|
1155
|
+
* @param market The market ID containing the order
|
|
1156
|
+
* @param orderId The specific order ID to retrieve
|
|
1157
|
+
* @return order The Order struct containing seller address and amounts
|
|
1158
|
+
*/
|
|
1159
|
+
function getOrder(
|
|
1160
|
+
uint256 market,
|
|
1161
|
+
uint256 orderId
|
|
1162
|
+
) public view returns (Order memory order) {
|
|
1163
|
+
order = ordersInsideMarket[market][orderId];
|
|
1164
|
+
return order;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
/**
|
|
1168
|
+
* @notice Retrieves all orders from a specific user in a specific market
|
|
1169
|
+
* @dev Returns array with extended order information for user's orders only
|
|
1170
|
+
* @param user Address of the user whose orders to retrieve
|
|
1171
|
+
* @param market The market ID to query orders from
|
|
1172
|
+
* @return orders Array of OrderForGetter structs containing user's orders in the market
|
|
1173
|
+
*/
|
|
1174
|
+
function getMyOrdersInSpecificMarket(
|
|
1175
|
+
address user,
|
|
1176
|
+
uint256 market
|
|
1177
|
+
) public view returns (OrderForGetter[] memory orders) {
|
|
1178
|
+
orders = new OrderForGetter[](marketMetadata[market].maxSlot + 1);
|
|
1179
|
+
|
|
1180
|
+
for (uint256 i = 1; i <= marketMetadata[market].maxSlot + 1; i++) {
|
|
1181
|
+
if (ordersInsideMarket[market][i].seller == user) {
|
|
1182
|
+
orders[i - 1] = OrderForGetter(
|
|
1183
|
+
market,
|
|
1184
|
+
i,
|
|
1185
|
+
ordersInsideMarket[market][i].seller,
|
|
1186
|
+
ordersInsideMarket[market][i].amountA,
|
|
1187
|
+
ordersInsideMarket[market][i].amountB
|
|
1188
|
+
);
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
return orders;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
/**
|
|
1195
|
+
* @notice Finds the market ID for a specific token pair
|
|
1196
|
+
* @param tokenA Address of the first token
|
|
1197
|
+
* @param tokenB Address of the second token
|
|
1198
|
+
* @return The market ID for the token pair, or 0 if market doesn't exist
|
|
1199
|
+
*/
|
|
1200
|
+
function findMarket(
|
|
1201
|
+
address tokenA,
|
|
1202
|
+
address tokenB
|
|
1203
|
+
) public view returns (uint256) {
|
|
1204
|
+
return marketId[tokenA][tokenB];
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
/**
|
|
1208
|
+
* @notice Retrieves metadata information for a specific market
|
|
1209
|
+
* @param market The market ID to get metadata for
|
|
1210
|
+
* @return MarketInformation struct containing token addresses, max slot, and other metadata
|
|
1211
|
+
*/
|
|
1212
|
+
function getMarketMetadata(
|
|
1213
|
+
uint256 market
|
|
1214
|
+
) public view returns (MarketInformation memory) {
|
|
1215
|
+
return marketMetadata[market];
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
/**
|
|
1219
|
+
* @notice Retrieves metadata information for all existing markets
|
|
1220
|
+
* @dev Returns array of all market metadata from market ID 1 to marketCount
|
|
1221
|
+
* @return Array of MarketInformation structs containing all markets data
|
|
1222
|
+
*/
|
|
1223
|
+
function getAllMarketsMetadata()
|
|
1224
|
+
public
|
|
1225
|
+
view
|
|
1226
|
+
returns (MarketInformation[] memory)
|
|
1227
|
+
{
|
|
1228
|
+
MarketInformation[] memory markets = new MarketInformation[](
|
|
1229
|
+
marketCount + 1
|
|
1230
|
+
);
|
|
1231
|
+
for (uint256 i = 1; i <= marketCount; i++) {
|
|
1232
|
+
markets[i - 1] = marketMetadata[i];
|
|
1233
|
+
}
|
|
1234
|
+
return markets;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
/**
|
|
1238
|
+
* @notice Checks if a nonce has been used by a specific user
|
|
1239
|
+
* @dev Used to prevent replay attacks in P2P swap operations
|
|
1240
|
+
* @param user Address of the user to check
|
|
1241
|
+
* @param nonce The nonce value to verify
|
|
1242
|
+
* @return True if nonce has been used, false otherwise
|
|
1243
|
+
*/
|
|
1244
|
+
function checkIfANonceP2PSwapIsUsed(
|
|
1245
|
+
address user,
|
|
1246
|
+
uint256 nonce
|
|
1247
|
+
) public view returns (bool) {
|
|
1248
|
+
return nonceP2PSwap[user][nonce];
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
/**
|
|
1252
|
+
* @notice Returns the accumulated service fee balance for a specific token
|
|
1253
|
+
* @param token Address of the token to check balance for
|
|
1254
|
+
* @return The accumulated balance of the specified token
|
|
1255
|
+
*/
|
|
1256
|
+
function getBalanceOfContract(
|
|
1257
|
+
address token
|
|
1258
|
+
) external view returns (uint256) {
|
|
1259
|
+
return balancesOfContract[token];
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
/**
|
|
1263
|
+
* @notice Returns the currently proposed new owner address
|
|
1264
|
+
* @return Address of the proposed owner, or address(0) if no proposal exists
|
|
1265
|
+
*/
|
|
1266
|
+
function getOwnerProposal() external view returns (address) {
|
|
1267
|
+
return owner_proposal;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
/**
|
|
1271
|
+
* @notice Returns the current contract owner address
|
|
1272
|
+
* @return Address of the current contract owner
|
|
1273
|
+
*/
|
|
1274
|
+
function getOwner() external view returns (address) {
|
|
1275
|
+
return owner;
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
/**
|
|
1279
|
+
* @notice Returns the deadline timestamp for accepting ownership transfer
|
|
1280
|
+
* @return Timestamp until which the ownership proposal can be accepted
|
|
1281
|
+
*/
|
|
1282
|
+
function getOwnerTimeToAccept() external view returns (uint256) {
|
|
1283
|
+
return owner_timeToAccept;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
/**
|
|
1287
|
+
* @notice Returns the currently proposed reward percentage distribution
|
|
1288
|
+
* @return Percentage struct with proposed seller, service, and staker percentages
|
|
1289
|
+
*/
|
|
1290
|
+
function getRewardPercentageProposal()
|
|
1291
|
+
external
|
|
1292
|
+
view
|
|
1293
|
+
returns (Percentage memory)
|
|
1294
|
+
{
|
|
1295
|
+
return rewardPercentage_proposal;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
/**
|
|
1299
|
+
* @notice Returns the current active reward percentage distribution
|
|
1300
|
+
* @return Percentage struct with active seller, service, and staker percentages
|
|
1301
|
+
*/
|
|
1302
|
+
function getRewardPercentage() external view returns (Percentage memory) {
|
|
1303
|
+
return rewardPercentage;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
/**
|
|
1307
|
+
* @notice Returns the currently proposed percentage fee value
|
|
1308
|
+
* @return Proposed percentage fee in basis points for proportional fee calculation
|
|
1309
|
+
*/
|
|
1310
|
+
function getProposalPercentageFee() external view returns (uint256) {
|
|
1311
|
+
return percentageFee_proposal;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
/**
|
|
1315
|
+
* @notice Returns the current active percentage fee value
|
|
1316
|
+
* @return Active percentage fee in basis points for proportional fee calculation
|
|
1317
|
+
*/
|
|
1318
|
+
function getPercentageFee() external view returns (uint256) {
|
|
1319
|
+
return percentageFee;
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
/**
|
|
1323
|
+
* @notice Returns the currently proposed maximum limit for fixed fee calculations
|
|
1324
|
+
* @return Proposed maximum limit value for fixed fee model
|
|
1325
|
+
*/
|
|
1326
|
+
function getMaxLimitFillFixedFeeProposal() external view returns (uint256) {
|
|
1327
|
+
return maxLimitFillFixedFee_proposal;
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
/**
|
|
1331
|
+
* @notice Returns the current active maximum limit for fixed fee calculations
|
|
1332
|
+
* @return Active maximum limit value for fixed fee model
|
|
1333
|
+
*/
|
|
1334
|
+
function getMaxLimitFillFixedFee() external view returns (uint256) {
|
|
1335
|
+
return maxLimitFillFixedFee;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
/**
|
|
1339
|
+
* @notice Returns complete information about the current withdrawal proposal
|
|
1340
|
+
* @dev Returns all withdrawal parameters including token, amount, recipient, and deadline
|
|
1341
|
+
* @return tokenToWithdraw Address of token to be withdrawn
|
|
1342
|
+
* @return amountToWithdraw Amount of tokens to be withdrawn
|
|
1343
|
+
* @return recipientToWithdraw Address that will receive the tokens
|
|
1344
|
+
* @return timeToWithdrawal Deadline timestamp for accepting the withdrawal
|
|
1345
|
+
*/
|
|
1346
|
+
function getProposedWithdrawal()
|
|
1347
|
+
external
|
|
1348
|
+
view
|
|
1349
|
+
returns (address, uint256, address, uint256)
|
|
1350
|
+
{
|
|
1351
|
+
return (
|
|
1352
|
+
tokenToWithdraw,
|
|
1353
|
+
amountToWithdraw,
|
|
1354
|
+
recipientToWithdraw,
|
|
1355
|
+
timeToWithdrawal
|
|
1356
|
+
);
|
|
1357
|
+
}
|
|
1358
|
+
}
|