-
Notifications
You must be signed in to change notification settings - Fork 6
/
MainZone.sol
112 lines (90 loc) · 3.78 KB
/
MainZone.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
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
// Inheritances
import {IMainZone} from "./IMainZone.sol";
import {IAuthZone} from "./IAuthZone.sol";
import {Zone} from "../Zone.sol";
import {AccessControlDefaultAdminRules} from "@openzeppelin/access/AccessControlDefaultAdminRules.sol";
import {Pausable} from "@openzeppelin/security/Pausable.sol";
// Interfaces
import {IFloodPlain} from "../../flood-plain/IFloodPlain.sol";
contract MainZone is Zone, IMainZone, IAuthZone, AccessControlDefaultAdminRules, Pausable {
bytes32 public constant CALLER_ROLE = keccak256("CALLER_ROLE");
bytes32 public constant FULFILLER_ROLE = keccak256("FULFILLER_ROLE");
bytes32 public constant BOOK_ROLE = keccak256("BOOK_ROLE");
bytes32 public constant CANCELLED_ORDERS = keccak256("CANCELLED_ORDERS");
address public secondaryZone;
mapping(address => AuthFilter) public filters;
constructor(address admin) AccessControlDefaultAdminRules(2 days, admin) {}
function pause() external onlyRole(DEFAULT_ADMIN_ROLE) {
_pause();
}
function unpause() external onlyRole(DEFAULT_ADMIN_ROLE) {
_unpause();
}
function setSecondaryZone(address newSecondaryZone) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (newSecondaryZone != address(0)) {
require(newSecondaryZone.code.length != 0);
}
secondaryZone = newSecondaryZone; // Zero address is to unset.
emit SecondaryZoneSet(newSecondaryZone);
}
function validateOrder(IFloodPlain.Order calldata, /* order */ address book, address caller, bytes32 orderHash)
external
view
override
whenNotPaused
{
// Always do basic built-in access control checks.
_checkRole(CALLER_ROLE, caller);
_checkRole(BOOK_ROLE, book);
// Check if an order is manually cancelled.
if (hasRole(CANCELLED_ORDERS, address(uint160(uint256(orderHash))))) {
revert CancelledOrder(orderHash);
}
_checkSecondaryZone();
}
function validateOrder(
IFloodPlain.Order calldata, /* order */
address book,
address fulfiller,
address caller,
bytes32 orderHash,
bytes calldata /* context */
) external view override whenNotPaused {
// Always do basic built-in access control checks.
_checkRole(CALLER_ROLE, caller);
_checkRole(FULFILLER_ROLE, fulfiller);
_checkRole(BOOK_ROLE, book);
// Check if an order is manually cancelled.
if (hasRole(CANCELLED_ORDERS, address(uint160(uint256(orderHash))))) {
revert CancelledOrder(orderHash);
}
_checkSecondaryZone();
}
function _checkSecondaryZone() internal view {
// Check if an extra zone is set to do additional checks.
address _secondaryZone = secondaryZone;
assembly {
// If secondaryZone is not zero address.
if _secondaryZone {
// Move entire calldata to memory starting from offset zero.
calldatacopy(0, 0, calldatasize())
// Make the exact same staticcall to the secondary zone.
let result := staticcall(gas(), _secondaryZone, 0, calldatasize(), 0, 0)
// Revert with the same message if call fails.
if iszero(result) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}
}
function setAuthorizationFilter(address actor, AuthFilter calldata filter) external onlyRole(DEFAULT_ADMIN_ROLE) {
filters[actor] = filter;
emit FilterUpdated(actor, filter);
}
function authorizationFilter(address actor) external view returns (AuthFilter memory) {
return filters[actor];
}
}