"; // eg. OpenZeppelin.Slot
+ *
+ * function setValueInNamespace(uint256 key, address newValue) internal {
+ * _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue;
+ * }
+ *
+ * function getValueInNamespace(uint256 key) internal view returns (address) {
+ * return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value;
+ * }
+ * }
+ * ```
+ *
+ * TIP: Consider using this library along with {StorageSlot}.
+ *
+ * NOTE: This library provides a way to manipulate storage locations in a non-standard way. Tooling for checking
+ * upgrade safety will ignore the slots accessed through this library.
+ *
+ * _Available since v5.1._
+ */
+library SlotDerivation {
+ /**
+ * @dev Derive an ERC-7201 slot from a string (namespace).
+ */
+ function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) {
+ assembly ("memory-safe") {
+ mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1))
+ slot := and(keccak256(0x00, 0x20), not(0xff))
+ }
+ }
+
+ /**
+ * @dev Add an offset to a slot to get the n-th element of a structure or an array.
+ */
+ function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result) {
+ unchecked {
+ return bytes32(uint256(slot) + pos);
+ }
+ }
+
+ /**
+ * @dev Derive the location of the first element in an array from the slot where the length is stored.
+ */
+ function deriveArray(bytes32 slot) internal pure returns (bytes32 result) {
+ assembly ("memory-safe") {
+ mstore(0x00, slot)
+ result := keccak256(0x00, 0x20)
+ }
+ }
+
+ /**
+ * @dev Derive the location of a mapping element from the key.
+ */
+ function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) {
+ assembly ("memory-safe") {
+ mstore(0x00, and(key, shr(96, not(0))))
+ mstore(0x20, slot)
+ result := keccak256(0x00, 0x40)
+ }
+ }
+
+ /**
+ * @dev Derive the location of a mapping element from the key.
+ */
+ function deriveMapping(bytes32 slot, bool key) internal pure returns (bytes32 result) {
+ assembly ("memory-safe") {
+ mstore(0x00, iszero(iszero(key)))
+ mstore(0x20, slot)
+ result := keccak256(0x00, 0x40)
+ }
+ }
+
+ /**
+ * @dev Derive the location of a mapping element from the key.
+ */
+ function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) {
+ assembly ("memory-safe") {
+ mstore(0x00, key)
+ mstore(0x20, slot)
+ result := keccak256(0x00, 0x40)
+ }
+ }
+
+ /**
+ * @dev Derive the location of a mapping element from the key.
+ */
+ function deriveMapping(bytes32 slot, uint256 key) internal pure returns (bytes32 result) {
+ assembly ("memory-safe") {
+ mstore(0x00, key)
+ mstore(0x20, slot)
+ result := keccak256(0x00, 0x40)
+ }
+ }
+
+ /**
+ * @dev Derive the location of a mapping element from the key.
+ */
+ function deriveMapping(bytes32 slot, int256 key) internal pure returns (bytes32 result) {
+ assembly ("memory-safe") {
+ mstore(0x00, key)
+ mstore(0x20, slot)
+ result := keccak256(0x00, 0x40)
+ }
+ }
+
+ /**
+ * @dev Derive the location of a mapping element from the key.
+ */
+ function deriveMapping(bytes32 slot, string memory key) internal pure returns (bytes32 result) {
+ assembly ("memory-safe") {
+ let length := mload(key)
+ let begin := add(key, 0x20)
+ let end := add(begin, length)
+ let cache := mload(end)
+ mstore(end, slot)
+ result := keccak256(begin, add(length, 0x20))
+ mstore(end, cache)
+ }
+ }
+
+ /**
+ * @dev Derive the location of a mapping element from the key.
+ */
+ function deriveMapping(bytes32 slot, bytes memory key) internal pure returns (bytes32 result) {
+ assembly ("memory-safe") {
+ let length := mload(key)
+ let begin := add(key, 0x20)
+ let end := add(begin, length)
+ let cache := mload(end)
+ mstore(end, slot)
+ result := keccak256(begin, add(length, 0x20))
+ mstore(end, cache)
+ }
+ }
+}
+
+// lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol
+
+// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)
+// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
+
+/**
+ * @dev Library for reading and writing primitive types to specific storage slots.
+ *
+ * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
+ * This library helps with reading and writing to such slots without the need for inline assembly.
+ *
+ * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
+ *
+ * Example usage to set ERC-1967 implementation slot:
+ * ```solidity
+ * contract ERC1967 {
+ * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
+ * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
+ *
+ * function _getImplementation() internal view returns (address) {
+ * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
+ * }
+ *
+ * function _setImplementation(address newImplementation) internal {
+ * require(newImplementation.code.length > 0);
+ * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
+ * }
+ * }
+ * ```
+ *
+ * TIP: Consider using this library along with {SlotDerivation}.
+ */
+library StorageSlot {
+ struct AddressSlot {
+ address value;
+ }
+
+ struct BooleanSlot {
+ bool value;
+ }
+
+ struct Bytes32Slot {
+ bytes32 value;
+ }
+
+ struct Uint256Slot {
+ uint256 value;
+ }
+
+ struct Int256Slot {
+ int256 value;
+ }
+
+ struct StringSlot {
+ string value;
+ }
+
+ struct BytesSlot {
+ bytes value;
+ }
+
+ /**
+ * @dev Returns an `AddressSlot` with member `value` located at `slot`.
+ */
+ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
+ assembly ("memory-safe") {
+ r.slot := slot
+ }
+ }
+
+ /**
+ * @dev Returns a `BooleanSlot` with member `value` located at `slot`.
+ */
+ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
+ assembly ("memory-safe") {
+ r.slot := slot
+ }
+ }
+
+ /**
+ * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.
+ */
+ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
+ assembly ("memory-safe") {
+ r.slot := slot
+ }
+ }
+
+ /**
+ * @dev Returns a `Uint256Slot` with member `value` located at `slot`.
+ */
+ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
+ assembly ("memory-safe") {
+ r.slot := slot
+ }
+ }
+
+ /**
+ * @dev Returns a `Int256Slot` with member `value` located at `slot`.
+ */
+ function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {
+ assembly ("memory-safe") {
+ r.slot := slot
+ }
+ }
+
+ /**
+ * @dev Returns a `StringSlot` with member `value` located at `slot`.
+ */
+ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
+ assembly ("memory-safe") {
+ r.slot := slot
+ }
+ }
+
+ /**
+ * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
+ */
+ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
+ assembly ("memory-safe") {
+ r.slot := store.slot
+ }
+ }
+
+ /**
+ * @dev Returns a `BytesSlot` with member `value` located at `slot`.
+ */
+ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
+ assembly ("memory-safe") {
+ r.slot := slot
+ }
+ }
+
+ /**
+ * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
+ */
+ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
+ assembly ("memory-safe") {
+ r.slot := store.slot
+ }
+ }
+}
+
+// lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol
+
+// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
+
+/**
+ * @dev Interface of the ERC-165 standard, as defined in the
+ * https://eips.ethereum.org/EIPS/eip-165[ERC].
+ *
+ * Implementers can declare support of contract interfaces, which can then be
+ * queried by others ({ERC165Checker}).
+ *
+ * For an implementation, see {ERC165}.
+ */
+interface IERC165 {
+ /**
+ * @dev Returns true if this contract implements the interface defined by
+ * `interfaceId`. See the corresponding
+ * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
+ * to learn more about how these ids are created.
+ *
+ * This function call must use less than 30 000 gas.
+ */
+ function supportsInterface(bytes4 interfaceId) external view returns (bool);
+}
+
+// lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol
+
+// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)
+// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
+
+/**
+ * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow
+ * checks.
+ *
+ * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
+ * easily result in undesired exploitation or bugs, since developers usually
+ * assume that overflows raise errors. `SafeCast` restores this intuition by
+ * reverting the transaction when such an operation overflows.
+ *
+ * Using this library instead of the unchecked operations eliminates an entire
+ * class of bugs, so it's recommended to use it always.
+ */
+library SafeCast {
+ /**
+ * @dev Value doesn't fit in an uint of `bits` size.
+ */
+ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
+
+ /**
+ * @dev An int value doesn't fit in an uint of `bits` size.
+ */
+ error SafeCastOverflowedIntToUint(int256 value);
+
+ /**
+ * @dev Value doesn't fit in an int of `bits` size.
+ */
+ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);
+
+ /**
+ * @dev An uint value doesn't fit in an int of `bits` size.
+ */
+ error SafeCastOverflowedUintToInt(uint256 value);
+
+ /**
+ * @dev Returns the downcasted uint248 from uint256, reverting on
+ * overflow (when the input is greater than largest uint248).
+ *
+ * Counterpart to Solidity's `uint248` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 248 bits
+ */
+ function toUint248(uint256 value) internal pure returns (uint248) {
+ if (value > type(uint248).max) {
+ revert SafeCastOverflowedUintDowncast(248, value);
+ }
+ return uint248(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint240 from uint256, reverting on
+ * overflow (when the input is greater than largest uint240).
+ *
+ * Counterpart to Solidity's `uint240` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 240 bits
+ */
+ function toUint240(uint256 value) internal pure returns (uint240) {
+ if (value > type(uint240).max) {
+ revert SafeCastOverflowedUintDowncast(240, value);
+ }
+ return uint240(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint232 from uint256, reverting on
+ * overflow (when the input is greater than largest uint232).
+ *
+ * Counterpart to Solidity's `uint232` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 232 bits
+ */
+ function toUint232(uint256 value) internal pure returns (uint232) {
+ if (value > type(uint232).max) {
+ revert SafeCastOverflowedUintDowncast(232, value);
+ }
+ return uint232(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint224 from uint256, reverting on
+ * overflow (when the input is greater than largest uint224).
+ *
+ * Counterpart to Solidity's `uint224` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 224 bits
+ */
+ function toUint224(uint256 value) internal pure returns (uint224) {
+ if (value > type(uint224).max) {
+ revert SafeCastOverflowedUintDowncast(224, value);
+ }
+ return uint224(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint216 from uint256, reverting on
+ * overflow (when the input is greater than largest uint216).
+ *
+ * Counterpart to Solidity's `uint216` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 216 bits
+ */
+ function toUint216(uint256 value) internal pure returns (uint216) {
+ if (value > type(uint216).max) {
+ revert SafeCastOverflowedUintDowncast(216, value);
+ }
+ return uint216(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint208 from uint256, reverting on
+ * overflow (when the input is greater than largest uint208).
+ *
+ * Counterpart to Solidity's `uint208` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 208 bits
+ */
+ function toUint208(uint256 value) internal pure returns (uint208) {
+ if (value > type(uint208).max) {
+ revert SafeCastOverflowedUintDowncast(208, value);
+ }
+ return uint208(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint200 from uint256, reverting on
+ * overflow (when the input is greater than largest uint200).
+ *
+ * Counterpart to Solidity's `uint200` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 200 bits
+ */
+ function toUint200(uint256 value) internal pure returns (uint200) {
+ if (value > type(uint200).max) {
+ revert SafeCastOverflowedUintDowncast(200, value);
+ }
+ return uint200(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint192 from uint256, reverting on
+ * overflow (when the input is greater than largest uint192).
+ *
+ * Counterpart to Solidity's `uint192` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 192 bits
+ */
+ function toUint192(uint256 value) internal pure returns (uint192) {
+ if (value > type(uint192).max) {
+ revert SafeCastOverflowedUintDowncast(192, value);
+ }
+ return uint192(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint184 from uint256, reverting on
+ * overflow (when the input is greater than largest uint184).
+ *
+ * Counterpart to Solidity's `uint184` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 184 bits
+ */
+ function toUint184(uint256 value) internal pure returns (uint184) {
+ if (value > type(uint184).max) {
+ revert SafeCastOverflowedUintDowncast(184, value);
+ }
+ return uint184(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint176 from uint256, reverting on
+ * overflow (when the input is greater than largest uint176).
+ *
+ * Counterpart to Solidity's `uint176` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 176 bits
+ */
+ function toUint176(uint256 value) internal pure returns (uint176) {
+ if (value > type(uint176).max) {
+ revert SafeCastOverflowedUintDowncast(176, value);
+ }
+ return uint176(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint168 from uint256, reverting on
+ * overflow (when the input is greater than largest uint168).
+ *
+ * Counterpart to Solidity's `uint168` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 168 bits
+ */
+ function toUint168(uint256 value) internal pure returns (uint168) {
+ if (value > type(uint168).max) {
+ revert SafeCastOverflowedUintDowncast(168, value);
+ }
+ return uint168(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint160 from uint256, reverting on
+ * overflow (when the input is greater than largest uint160).
+ *
+ * Counterpart to Solidity's `uint160` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 160 bits
+ */
+ function toUint160(uint256 value) internal pure returns (uint160) {
+ if (value > type(uint160).max) {
+ revert SafeCastOverflowedUintDowncast(160, value);
+ }
+ return uint160(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint152 from uint256, reverting on
+ * overflow (when the input is greater than largest uint152).
+ *
+ * Counterpart to Solidity's `uint152` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 152 bits
+ */
+ function toUint152(uint256 value) internal pure returns (uint152) {
+ if (value > type(uint152).max) {
+ revert SafeCastOverflowedUintDowncast(152, value);
+ }
+ return uint152(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint144 from uint256, reverting on
+ * overflow (when the input is greater than largest uint144).
+ *
+ * Counterpart to Solidity's `uint144` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 144 bits
+ */
+ function toUint144(uint256 value) internal pure returns (uint144) {
+ if (value > type(uint144).max) {
+ revert SafeCastOverflowedUintDowncast(144, value);
+ }
+ return uint144(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint136 from uint256, reverting on
+ * overflow (when the input is greater than largest uint136).
+ *
+ * Counterpart to Solidity's `uint136` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 136 bits
+ */
+ function toUint136(uint256 value) internal pure returns (uint136) {
+ if (value > type(uint136).max) {
+ revert SafeCastOverflowedUintDowncast(136, value);
+ }
+ return uint136(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint128 from uint256, reverting on
+ * overflow (when the input is greater than largest uint128).
+ *
+ * Counterpart to Solidity's `uint128` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 128 bits
+ */
+ function toUint128(uint256 value) internal pure returns (uint128) {
+ if (value > type(uint128).max) {
+ revert SafeCastOverflowedUintDowncast(128, value);
+ }
+ return uint128(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint120 from uint256, reverting on
+ * overflow (when the input is greater than largest uint120).
+ *
+ * Counterpart to Solidity's `uint120` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 120 bits
+ */
+ function toUint120(uint256 value) internal pure returns (uint120) {
+ if (value > type(uint120).max) {
+ revert SafeCastOverflowedUintDowncast(120, value);
+ }
+ return uint120(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint112 from uint256, reverting on
+ * overflow (when the input is greater than largest uint112).
+ *
+ * Counterpart to Solidity's `uint112` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 112 bits
+ */
+ function toUint112(uint256 value) internal pure returns (uint112) {
+ if (value > type(uint112).max) {
+ revert SafeCastOverflowedUintDowncast(112, value);
+ }
+ return uint112(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint104 from uint256, reverting on
+ * overflow (when the input is greater than largest uint104).
+ *
+ * Counterpart to Solidity's `uint104` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 104 bits
+ */
+ function toUint104(uint256 value) internal pure returns (uint104) {
+ if (value > type(uint104).max) {
+ revert SafeCastOverflowedUintDowncast(104, value);
+ }
+ return uint104(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint96 from uint256, reverting on
+ * overflow (when the input is greater than largest uint96).
+ *
+ * Counterpart to Solidity's `uint96` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 96 bits
+ */
+ function toUint96(uint256 value) internal pure returns (uint96) {
+ if (value > type(uint96).max) {
+ revert SafeCastOverflowedUintDowncast(96, value);
+ }
+ return uint96(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint88 from uint256, reverting on
+ * overflow (when the input is greater than largest uint88).
+ *
+ * Counterpart to Solidity's `uint88` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 88 bits
+ */
+ function toUint88(uint256 value) internal pure returns (uint88) {
+ if (value > type(uint88).max) {
+ revert SafeCastOverflowedUintDowncast(88, value);
+ }
+ return uint88(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint80 from uint256, reverting on
+ * overflow (when the input is greater than largest uint80).
+ *
+ * Counterpart to Solidity's `uint80` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 80 bits
+ */
+ function toUint80(uint256 value) internal pure returns (uint80) {
+ if (value > type(uint80).max) {
+ revert SafeCastOverflowedUintDowncast(80, value);
+ }
+ return uint80(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint72 from uint256, reverting on
+ * overflow (when the input is greater than largest uint72).
+ *
+ * Counterpart to Solidity's `uint72` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 72 bits
+ */
+ function toUint72(uint256 value) internal pure returns (uint72) {
+ if (value > type(uint72).max) {
+ revert SafeCastOverflowedUintDowncast(72, value);
+ }
+ return uint72(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint64 from uint256, reverting on
+ * overflow (when the input is greater than largest uint64).
+ *
+ * Counterpart to Solidity's `uint64` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 64 bits
+ */
+ function toUint64(uint256 value) internal pure returns (uint64) {
+ if (value > type(uint64).max) {
+ revert SafeCastOverflowedUintDowncast(64, value);
+ }
+ return uint64(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint56 from uint256, reverting on
+ * overflow (when the input is greater than largest uint56).
+ *
+ * Counterpart to Solidity's `uint56` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 56 bits
+ */
+ function toUint56(uint256 value) internal pure returns (uint56) {
+ if (value > type(uint56).max) {
+ revert SafeCastOverflowedUintDowncast(56, value);
+ }
+ return uint56(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint48 from uint256, reverting on
+ * overflow (when the input is greater than largest uint48).
+ *
+ * Counterpart to Solidity's `uint48` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 48 bits
+ */
+ function toUint48(uint256 value) internal pure returns (uint48) {
+ if (value > type(uint48).max) {
+ revert SafeCastOverflowedUintDowncast(48, value);
+ }
+ return uint48(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint40 from uint256, reverting on
+ * overflow (when the input is greater than largest uint40).
+ *
+ * Counterpart to Solidity's `uint40` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 40 bits
+ */
+ function toUint40(uint256 value) internal pure returns (uint40) {
+ if (value > type(uint40).max) {
+ revert SafeCastOverflowedUintDowncast(40, value);
+ }
+ return uint40(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint32 from uint256, reverting on
+ * overflow (when the input is greater than largest uint32).
+ *
+ * Counterpart to Solidity's `uint32` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 32 bits
+ */
+ function toUint32(uint256 value) internal pure returns (uint32) {
+ if (value > type(uint32).max) {
+ revert SafeCastOverflowedUintDowncast(32, value);
+ }
+ return uint32(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint24 from uint256, reverting on
+ * overflow (when the input is greater than largest uint24).
+ *
+ * Counterpart to Solidity's `uint24` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 24 bits
+ */
+ function toUint24(uint256 value) internal pure returns (uint24) {
+ if (value > type(uint24).max) {
+ revert SafeCastOverflowedUintDowncast(24, value);
+ }
+ return uint24(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint16 from uint256, reverting on
+ * overflow (when the input is greater than largest uint16).
+ *
+ * Counterpart to Solidity's `uint16` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 16 bits
+ */
+ function toUint16(uint256 value) internal pure returns (uint16) {
+ if (value > type(uint16).max) {
+ revert SafeCastOverflowedUintDowncast(16, value);
+ }
+ return uint16(value);
+ }
+
+ /**
+ * @dev Returns the downcasted uint8 from uint256, reverting on
+ * overflow (when the input is greater than largest uint8).
+ *
+ * Counterpart to Solidity's `uint8` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 8 bits
+ */
+ function toUint8(uint256 value) internal pure returns (uint8) {
+ if (value > type(uint8).max) {
+ revert SafeCastOverflowedUintDowncast(8, value);
+ }
+ return uint8(value);
+ }
+
+ /**
+ * @dev Converts a signed int256 into an unsigned uint256.
+ *
+ * Requirements:
+ *
+ * - input must be greater than or equal to 0.
+ */
+ function toUint256(int256 value) internal pure returns (uint256) {
+ if (value < 0) {
+ revert SafeCastOverflowedIntToUint(value);
+ }
+ return uint256(value);
+ }
+
+ /**
+ * @dev Returns the downcasted int248 from int256, reverting on
+ * overflow (when the input is less than smallest int248 or
+ * greater than largest int248).
+ *
+ * Counterpart to Solidity's `int248` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 248 bits
+ */
+ function toInt248(int256 value) internal pure returns (int248 downcasted) {
+ downcasted = int248(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(248, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int240 from int256, reverting on
+ * overflow (when the input is less than smallest int240 or
+ * greater than largest int240).
+ *
+ * Counterpart to Solidity's `int240` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 240 bits
+ */
+ function toInt240(int256 value) internal pure returns (int240 downcasted) {
+ downcasted = int240(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(240, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int232 from int256, reverting on
+ * overflow (when the input is less than smallest int232 or
+ * greater than largest int232).
+ *
+ * Counterpart to Solidity's `int232` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 232 bits
+ */
+ function toInt232(int256 value) internal pure returns (int232 downcasted) {
+ downcasted = int232(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(232, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int224 from int256, reverting on
+ * overflow (when the input is less than smallest int224 or
+ * greater than largest int224).
+ *
+ * Counterpart to Solidity's `int224` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 224 bits
+ */
+ function toInt224(int256 value) internal pure returns (int224 downcasted) {
+ downcasted = int224(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(224, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int216 from int256, reverting on
+ * overflow (when the input is less than smallest int216 or
+ * greater than largest int216).
+ *
+ * Counterpart to Solidity's `int216` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 216 bits
+ */
+ function toInt216(int256 value) internal pure returns (int216 downcasted) {
+ downcasted = int216(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(216, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int208 from int256, reverting on
+ * overflow (when the input is less than smallest int208 or
+ * greater than largest int208).
+ *
+ * Counterpart to Solidity's `int208` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 208 bits
+ */
+ function toInt208(int256 value) internal pure returns (int208 downcasted) {
+ downcasted = int208(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(208, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int200 from int256, reverting on
+ * overflow (when the input is less than smallest int200 or
+ * greater than largest int200).
+ *
+ * Counterpart to Solidity's `int200` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 200 bits
+ */
+ function toInt200(int256 value) internal pure returns (int200 downcasted) {
+ downcasted = int200(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(200, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int192 from int256, reverting on
+ * overflow (when the input is less than smallest int192 or
+ * greater than largest int192).
+ *
+ * Counterpart to Solidity's `int192` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 192 bits
+ */
+ function toInt192(int256 value) internal pure returns (int192 downcasted) {
+ downcasted = int192(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(192, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int184 from int256, reverting on
+ * overflow (when the input is less than smallest int184 or
+ * greater than largest int184).
+ *
+ * Counterpart to Solidity's `int184` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 184 bits
+ */
+ function toInt184(int256 value) internal pure returns (int184 downcasted) {
+ downcasted = int184(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(184, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int176 from int256, reverting on
+ * overflow (when the input is less than smallest int176 or
+ * greater than largest int176).
+ *
+ * Counterpart to Solidity's `int176` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 176 bits
+ */
+ function toInt176(int256 value) internal pure returns (int176 downcasted) {
+ downcasted = int176(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(176, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int168 from int256, reverting on
+ * overflow (when the input is less than smallest int168 or
+ * greater than largest int168).
+ *
+ * Counterpart to Solidity's `int168` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 168 bits
+ */
+ function toInt168(int256 value) internal pure returns (int168 downcasted) {
+ downcasted = int168(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(168, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int160 from int256, reverting on
+ * overflow (when the input is less than smallest int160 or
+ * greater than largest int160).
+ *
+ * Counterpart to Solidity's `int160` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 160 bits
+ */
+ function toInt160(int256 value) internal pure returns (int160 downcasted) {
+ downcasted = int160(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(160, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int152 from int256, reverting on
+ * overflow (when the input is less than smallest int152 or
+ * greater than largest int152).
+ *
+ * Counterpart to Solidity's `int152` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 152 bits
+ */
+ function toInt152(int256 value) internal pure returns (int152 downcasted) {
+ downcasted = int152(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(152, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int144 from int256, reverting on
+ * overflow (when the input is less than smallest int144 or
+ * greater than largest int144).
+ *
+ * Counterpart to Solidity's `int144` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 144 bits
+ */
+ function toInt144(int256 value) internal pure returns (int144 downcasted) {
+ downcasted = int144(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(144, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int136 from int256, reverting on
+ * overflow (when the input is less than smallest int136 or
+ * greater than largest int136).
+ *
+ * Counterpart to Solidity's `int136` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 136 bits
+ */
+ function toInt136(int256 value) internal pure returns (int136 downcasted) {
+ downcasted = int136(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(136, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int128 from int256, reverting on
+ * overflow (when the input is less than smallest int128 or
+ * greater than largest int128).
+ *
+ * Counterpart to Solidity's `int128` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 128 bits
+ */
+ function toInt128(int256 value) internal pure returns (int128 downcasted) {
+ downcasted = int128(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(128, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int120 from int256, reverting on
+ * overflow (when the input is less than smallest int120 or
+ * greater than largest int120).
+ *
+ * Counterpart to Solidity's `int120` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 120 bits
+ */
+ function toInt120(int256 value) internal pure returns (int120 downcasted) {
+ downcasted = int120(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(120, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int112 from int256, reverting on
+ * overflow (when the input is less than smallest int112 or
+ * greater than largest int112).
+ *
+ * Counterpart to Solidity's `int112` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 112 bits
+ */
+ function toInt112(int256 value) internal pure returns (int112 downcasted) {
+ downcasted = int112(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(112, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int104 from int256, reverting on
+ * overflow (when the input is less than smallest int104 or
+ * greater than largest int104).
+ *
+ * Counterpart to Solidity's `int104` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 104 bits
+ */
+ function toInt104(int256 value) internal pure returns (int104 downcasted) {
+ downcasted = int104(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(104, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int96 from int256, reverting on
+ * overflow (when the input is less than smallest int96 or
+ * greater than largest int96).
+ *
+ * Counterpart to Solidity's `int96` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 96 bits
+ */
+ function toInt96(int256 value) internal pure returns (int96 downcasted) {
+ downcasted = int96(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(96, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int88 from int256, reverting on
+ * overflow (when the input is less than smallest int88 or
+ * greater than largest int88).
+ *
+ * Counterpart to Solidity's `int88` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 88 bits
+ */
+ function toInt88(int256 value) internal pure returns (int88 downcasted) {
+ downcasted = int88(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(88, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int80 from int256, reverting on
+ * overflow (when the input is less than smallest int80 or
+ * greater than largest int80).
+ *
+ * Counterpart to Solidity's `int80` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 80 bits
+ */
+ function toInt80(int256 value) internal pure returns (int80 downcasted) {
+ downcasted = int80(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(80, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int72 from int256, reverting on
+ * overflow (when the input is less than smallest int72 or
+ * greater than largest int72).
+ *
+ * Counterpart to Solidity's `int72` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 72 bits
+ */
+ function toInt72(int256 value) internal pure returns (int72 downcasted) {
+ downcasted = int72(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(72, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int64 from int256, reverting on
+ * overflow (when the input is less than smallest int64 or
+ * greater than largest int64).
+ *
+ * Counterpart to Solidity's `int64` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 64 bits
+ */
+ function toInt64(int256 value) internal pure returns (int64 downcasted) {
+ downcasted = int64(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(64, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int56 from int256, reverting on
+ * overflow (when the input is less than smallest int56 or
+ * greater than largest int56).
+ *
+ * Counterpart to Solidity's `int56` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 56 bits
+ */
+ function toInt56(int256 value) internal pure returns (int56 downcasted) {
+ downcasted = int56(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(56, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int48 from int256, reverting on
+ * overflow (when the input is less than smallest int48 or
+ * greater than largest int48).
+ *
+ * Counterpart to Solidity's `int48` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 48 bits
+ */
+ function toInt48(int256 value) internal pure returns (int48 downcasted) {
+ downcasted = int48(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(48, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int40 from int256, reverting on
+ * overflow (when the input is less than smallest int40 or
+ * greater than largest int40).
+ *
+ * Counterpart to Solidity's `int40` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 40 bits
+ */
+ function toInt40(int256 value) internal pure returns (int40 downcasted) {
+ downcasted = int40(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(40, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int32 from int256, reverting on
+ * overflow (when the input is less than smallest int32 or
+ * greater than largest int32).
+ *
+ * Counterpart to Solidity's `int32` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 32 bits
+ */
+ function toInt32(int256 value) internal pure returns (int32 downcasted) {
+ downcasted = int32(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(32, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int24 from int256, reverting on
+ * overflow (when the input is less than smallest int24 or
+ * greater than largest int24).
+ *
+ * Counterpart to Solidity's `int24` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 24 bits
+ */
+ function toInt24(int256 value) internal pure returns (int24 downcasted) {
+ downcasted = int24(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(24, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int16 from int256, reverting on
+ * overflow (when the input is less than smallest int16 or
+ * greater than largest int16).
+ *
+ * Counterpart to Solidity's `int16` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 16 bits
+ */
+ function toInt16(int256 value) internal pure returns (int16 downcasted) {
+ downcasted = int16(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(16, value);
+ }
+ }
+
+ /**
+ * @dev Returns the downcasted int8 from int256, reverting on
+ * overflow (when the input is less than smallest int8 or
+ * greater than largest int8).
+ *
+ * Counterpart to Solidity's `int8` operator.
+ *
+ * Requirements:
+ *
+ * - input must fit into 8 bits
+ */
+ function toInt8(int256 value) internal pure returns (int8 downcasted) {
+ downcasted = int8(value);
+ if (downcasted != value) {
+ revert SafeCastOverflowedIntDowncast(8, value);
+ }
+ }
+
+ /**
+ * @dev Converts an unsigned uint256 into a signed int256.
+ *
+ * Requirements:
+ *
+ * - input must be less than or equal to maxInt256.
+ */
+ function toInt256(uint256 value) internal pure returns (int256) {
+ // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
+ if (value > uint256(type(int256).max)) {
+ revert SafeCastOverflowedUintToInt(value);
+ }
+ return int256(value);
+ }
+
+ /**
+ * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.
+ */
+ function toUint(bool b) internal pure returns (uint256 u) {
+ assembly ("memory-safe") {
+ u := iszero(iszero(b))
+ }
+ }
+}
+
+// src/modules/library/RuleEngineInvariantStorage.sol
+
+abstract contract RuleEngineInvariantStorage {
+ /* ==== Errors === */
+ error RuleEngine_AdminWithAddressZeroNotAllowed();
+}
+
+// lib/CMTAT/contracts/interfaces/tokenization/draft-IERC7551.sol
+
+/**
+ * @title IERC7551Mint
+ * @dev Interface for token minting operations.
+ */
+interface IERC7551Mint {
+ /**
+ * @notice Emitted when new tokens are minted and assigned to an account.
+ * @param minter The address that initiated the mint operation.
+ * @param account The address receiving the newly minted tokens.
+ * @param value The amount of tokens created.
+ * @param data Optional metadata associated with the mint (e.g., reason, reference ID).
+ */
+ event Mint(address indexed minter, address indexed account, uint256 value, bytes data);
+ /**
+ * @notice Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0)
+ * @dev
+ * - Increases the total supply of tokens.
+ * - Emits both a `Mint` event and a standard ERC-20 `Transfer` event (with `from` set to the zero address).
+ * - The `data` parameter can be used to attach off-chain metadata or audit information.
+ * - If {IERC7551Pause} is implemented:
+ * - Token issuance MUST NOT be blocked by paused transfer state.
+ * Requirements:
+ * - `account` cannot be the zero address
+ * @param account The address that will receive the newly minted tokens.
+ * @param value The amount of tokens to mint.
+ * @param data Additional contextual data to include with the mint (optional).
+ */
+ function mint(address account, uint256 value, bytes calldata data) external;
+}
+
+/**
+* @title interface for burn operation
+*/
+interface IERC7551Burn {
+ /**
+ * @notice Emitted when tokens are burned from an account.
+ * @param burner The address that initiated the burn.
+ * @param account The address from which tokens were burned.
+ * @param value The amount of tokens burned.
+ * @param data Additional data related to the burn.
+ */
+ event Burn(address indexed burner, address indexed account, uint256 value, bytes data);
+
+ /**
+ * @notice Burns a specific number of tokens from the given account by transferring it to address(0)
+ * @dev
+ * - The account's balance is decreased by the specified amount.
+ * - Emits a `Burn` event and a standard `Transfer` event with `to` set to `address(0)`.
+ * - If the account balance (including frozen tokens) is less than the burn amount, the transaction MUST revert.
+ * - If the token contract supports {IERC7551Pause}, paused transfers MUST NOT prevent this burn operation.
+ * - The `data` parameter MAY be used to provide additional context (e.g., audit trail or documentation).
+ * @param account The address whose tokens will be burned.
+ * @param amount The number of tokens to remove from circulation.
+ * @param data Arbitrary additional data to document the burn.
+ */
+ function burn(address account, uint256 amount, bytes calldata data) external;
+}
+
+interface IERC7551Pause {
+ /**
+ * @notice Returns true if token transfers are currently paused.
+ * @return True if paused, false otherwise.
+ * @dev
+ * If this function returns true, it MUST NOT be possible to transfer tokens to other accounts
+ * and the function canTransfer() MUST return false.
+ */
+ function paused() external view returns (bool);
+ /**
+ * @notice Pauses token transfers.
+ * @dev Reverts if already paused.
+ * Emits a `Paused` event
+ */
+ function pause() external;
+ /**
+ * @notice Unpauses token transfers.
+ * @dev Reverts if token is not in pause state.
+ * emits an `Unpaused` event
+ */
+ function unpause() external;
+}
+interface IERC7551ERC20EnforcementEvent {
+ /**
+ * @notice Emitted when a forced transfer or burn occurs.
+ * @param enforcer The address that initiated the enforcement.
+ * @param account The address affected by the enforcement.
+ * @param amount The number of tokens involved.
+ * @param data Additional data related to the enforcement.
+ */
+ event Enforcement (address indexed enforcer, address indexed account, uint256 amount, bytes data);
+}
+
+interface IERC7551ERC20EnforcementTokenFrozenEvent {
+ /**
+ * @notice Emitted when a specific amount of tokens are frozen on an address.
+ * @param account The address whose tokens are frozen.
+ * @param value The number of tokens frozen.
+ * @param data Additional data related to the freezing action.
+ * @dev
+ * Same name as ERC-3643 but with a supplementary data parameter
+ * The event is emitted by freezePartialTokens and batchFreezePartialTokens functions
+ */
+ event TokensFrozen(address indexed account, uint256 value, bytes data);
+
+ /**
+ * @notice Emitted when a specific amount of tokens are unfrozen on an address.
+ * @param account The address whose tokens are unfrozen.
+ * @param value The number of tokens unfrozen.
+ * @param data Additional data related to the unfreezing action.
+ * @dev
+ * Same name as ERC-3643 but with a supplementary data parameter
+ * The event is emitted by `unfreezePartialTokens`, `batchUnfreezePartialTokens`and potentially `forcedTransfer` functions
+ */
+ event TokensUnfrozen(address indexed account, uint256 value, bytes data);
+}
+
+interface IERC7551ERC20Enforcement {
+ /* ============ View Functions ============ */
+ /**
+ * @notice Returns the active (unfrozen) token balance of a given account.
+ * @param account The address to query.
+ * @return activeBalance_ The amount of tokens that can be transferred using standard ERC-20 functions.
+ */
+ function getActiveBalanceOf(address account) external view returns (uint256 activeBalance_);
+
+ /**
+ * @notice Returns the frozen token balance of a given account.
+ * @dev Frozen tokens cannot be transferred using standard ERC-20 functions.
+ * Implementations MAY support transferring frozen tokens using other mechanisms like `forcedTransfer`.
+ * If the active balance is insufficient to cover a transfer, `canTransfer` and `canTransferFrom` MUST return false.
+ * @param account The address to query.
+ * @return frozenBalance_ The amount of tokens that are frozen and non-transferable via ERC-20 `transfer` and `transferFrom`.
+ */
+ function getFrozenTokens(address account) external view returns (uint256 frozenBalance_);
+
+ /* ============ State Functions ============ */
+ /**
+ * @notice Freezes a specified amount of tokens for a given account.
+ * @dev Emits a `TokensFrozen` event.
+ * @param account The address whose tokens will be frozen.
+ * @param amount The number of tokens to freeze.
+ * @param data Arbitrary additional data for logging or business logic.
+ */
+ function freezePartialTokens(address account, uint256 amount, bytes memory data) external;
+
+
+ /**
+ * @notice Unfreezes a specified amount of tokens for a given account.
+ * @dev Emits a `TokensUnfrozen` event.
+ * @param account The address whose tokens will be unfrozen.
+ * @param amount The number of tokens to unfreeze.
+ * @param data Arbitrary additional data for logging or business logic.
+ */
+ function unfreezePartialTokens(address account, uint256 amount, bytes memory data) external;
+ /**
+ * @notice Executes a forced transfer of tokens from one account to another.
+ * @dev Transfers `value` tokens from `account` to `to` without requiring the account’s consent.
+ * If the `account` does not have enough active (unfrozen) tokens, frozen tokens may be automatically unfrozen to fulfill the transfer.
+ * Emits a `Transfer` event. Emits a `TokensUnfrozen` event if frozen tokens are used.
+ * @param account The address to debit tokens from.
+ * @param to The address to credit tokens to.
+ * @param value The amount of tokens to transfer.
+ * @param data Optional additional metadata to accompany the transfer.
+ * @return success_ Returns true if the transfer was successful.
+ */
+ function forcedTransfer(address account, address to, uint256 value, bytes calldata data) external returns (bool success_);
+}
+
+interface IERC7551Compliance is IERC3643ComplianceRead {
+ /**
+ * @notice Checks if `spender` can transfer `value` tokens from `from` to `to` under compliance rules.
+ * @dev Does not check balances or access rights (Access Control).
+ * @param spender The address performing the transfer.
+ * @param from The source address.
+ * @param to The destination address.
+ * @param value The number of tokens to transfer.
+ * @return isCompliant True if the transfer complies with policy.
+ */
+ function canTransferFrom(
+ address spender,
+ address from,
+ address to,
+ uint256 value
+ ) external view returns (bool);
+}
+
+interface IERC7551Document {
+ /**
+ * @notice Returns the hash of the "Terms" document.
+ * @return hash_ The `bytes32` hash of the terms document.
+ */
+ function termsHash() external view returns (bytes32 hash_);
+
+ /**
+ * @notice Sets the terms hash and URI.
+ * @param _hash The new hash of the document.
+ * @param _uri The corresponding URI.
+ */
+ function setTerms(bytes32 _hash, string calldata _uri) external;
+
+ /**
+ * @notice Returns the metadata string (e.g. URL).
+ * @return metadata_ The metadata string.
+ */
+ function metaData() external view returns (string memory metadata_);
+
+ /**
+ * @notice Sets a new metadata string (e.g. URL).
+ * @param metaData_ The new metadata value.
+ */
+ function setMetaData(string calldata metaData_) external;
+}
+
+// lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol
+
+// OpenZeppelin Contracts (last updated v5.4.0) (metatx/ERC2771Context.sol)
+
+/**
+ * @dev Context variant with ERC-2771 support.
+ *
+ * WARNING: Avoid using this pattern in contracts that rely in a specific calldata length as they'll
+ * be affected by any forwarder whose `msg.data` is suffixed with the `from` address according to the ERC-2771
+ * specification adding the address size in bytes (20) to the calldata size. An example of an unexpected
+ * behavior could be an unintended fallback (or another function) invocation while trying to invoke the `receive`
+ * function only accessible if `msg.data.length == 0`.
+ *
+ * WARNING: The usage of `delegatecall` in this contract is dangerous and may result in context corruption.
+ * Any forwarded request to this contract triggering a `delegatecall` to itself will result in an invalid {_msgSender}
+ * recovery.
+ */
+abstract contract ERC2771Context is Context {
+ /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
+ address private immutable _trustedForwarder;
+
+ /**
+ * @dev Initializes the contract with a trusted forwarder, which will be able to
+ * invoke functions on this contract on behalf of other accounts.
+ *
+ * NOTE: The trusted forwarder can be replaced by overriding {trustedForwarder}.
+ */
+ /// @custom:oz-upgrades-unsafe-allow constructor
+ constructor(address trustedForwarder_) {
+ _trustedForwarder = trustedForwarder_;
+ }
+
+ /**
+ * @dev Returns the address of the trusted forwarder.
+ */
+ function trustedForwarder() public view virtual returns (address) {
+ return _trustedForwarder;
+ }
+
+ /**
+ * @dev Indicates whether any particular address is the trusted forwarder.
+ */
+ function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
+ return forwarder == trustedForwarder();
+ }
+
+ /**
+ * @dev Override for `msg.sender`. Defaults to the original `msg.sender` whenever
+ * a call is not performed by the trusted forwarder or the calldata length is less than
+ * 20 bytes (an address length).
+ */
+ function _msgSender() internal view virtual override returns (address) {
+ uint256 calldataLength = msg.data.length;
+ uint256 contextSuffixLength = _contextSuffixLength();
+ if (calldataLength >= contextSuffixLength && isTrustedForwarder(msg.sender)) {
+ unchecked {
+ return address(bytes20(msg.data[calldataLength - contextSuffixLength:]));
+ }
+ } else {
+ return super._msgSender();
+ }
+ }
+
+ /**
+ * @dev Override for `msg.data`. Defaults to the original `msg.data` whenever
+ * a call is not performed by the trusted forwarder or the calldata length is less than
+ * 20 bytes (an address length).
+ */
+ function _msgData() internal view virtual override returns (bytes calldata) {
+ uint256 calldataLength = msg.data.length;
+ uint256 contextSuffixLength = _contextSuffixLength();
+ if (calldataLength >= contextSuffixLength && isTrustedForwarder(msg.sender)) {
+ unchecked {
+ return msg.data[:calldataLength - contextSuffixLength];
+ }
+ } else {
+ return super._msgData();
+ }
+ }
+
+ /**
+ * @dev ERC-2771 specifies the context as being a single address (20 bytes).
+ */
+ function _contextSuffixLength() internal view virtual override returns (uint256) {
+ return 20;
+ }
+}
+
+// lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol
+
+// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)
+
+/**
+ * @dev Implementation of the {IERC165} interface.
+ *
+ * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
+ * for the additional interface id that will be supported. For example:
+ *
+ * ```solidity
+ * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
+ * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
+ * }
+ * ```
+ */
+abstract contract ERC165 is IERC165 {
+ /// @inheritdoc IERC165
+ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
+ return interfaceId == type(IERC165).interfaceId;
+ }
+}
+
+// src/interfaces/IERC3643Compliance.sol
+
+/* ==== CMTAT === */
+
+interface IERC3643Compliance is IERC3643ComplianceRead, IERC3643IComplianceContract {
+ /* ============ Events ============ */
+ /**
+ * @notice Emitted when a token is successfully bound to the compliance contract.
+ * @param token The address of the token that was bound.
+ */
+ event TokenBound(address token);
+
+ /**
+ * @notice Emitted when a token is successfully unbound from the compliance contract.
+ * @param token The address of the token that was unbound.
+ */
+ event TokenUnbound(address token);
+
+ /* ============ Functions ============ */
+ /**
+ * @notice Associates a token contract with this compliance contract.
+ * @dev The compliance contract may restrict operations on the bound token
+ * according to the compliance logic.
+ * Reverts if the token is already bound.
+ * Complexity: O(1).
+ * @param token The address of the token to bind.
+ */
+ function bindToken(address token) external;
+ /**
+ * @notice Removes the association of a token contract from this compliance contract.
+ * @dev Reverts if the token is not currently bound.
+ * Complexity: O(1).
+ * @param token The address of the token to unbind.
+ */
+ function unbindToken(address token) external;
+
+ /**
+ * @notice Checks whether a token is currently bound to this compliance contract.
+ * @dev
+ * Complexity: O(1).
+ * Note that there are no guarantees on the ordering of values inside the array,
+ * and it may change when more values are added or removed.
+ * @param token The token address to verify.
+ * @return isBound True if the token is bound, false otherwise.
+ */
+ function isTokenBound(address token) external view returns (bool isBound);
+ /**
+ * @notice Returns the single token currently bound to this compliance contract.
+ * @dev If multiple tokens are supported, consider using getTokenBounds().
+ * @return token The address of the currently bound token.
+ */
+ function getTokenBound() external view returns (address token);
+
+ /**
+ * @notice Returns all tokens currently bound to this compliance contract.
+ * @dev This is a view-only function and does not modify state.
+ * This function is not part of the original ERC-3643 specification
+ * This operation will copy the entire storage to memory, which can be quite expensive.
+ * This is designed to mostly be used by view accessors that are queried without any gas fees.
+ * @return tokens An array of addresses of bound token contracts.
+ */
+ function getTokenBounds() external view returns (address[] memory tokens);
+
+ /**
+ * @notice Updates the compliance contract state when tokens are created (minted).
+ * @dev Called by the token contract when new tokens are issued to an account.
+ * Reverts if the minting does not comply with the rules.
+ * @param to The address receiving the minted tokens.
+ * @param value The number of tokens created.
+ */
+ function created(address to, uint256 value) external;
+
+ /**
+ * @notice Updates the compliance contract state when tokens are destroyed (burned).
+ * @dev Called by the token contract when tokens are redeemed or burned.
+ * Reverts if the burning does not comply with the rules.
+ * @param from The address whose tokens are being destroyed.
+ * @param value The number of tokens destroyed.
+ */
+ function destroyed(address from, uint256 value) external;
+}
+
+// src/modules/VersionModule.sol
+
+/* ==== CMTAT === */
+
+abstract contract VersionModule is IERC3643Base {
+ /* ============ State Variables ============ */
+ /**
+ * @dev
+ * Get the current version of the smart contract
+ */
+ string private constant VERSION = "3.0.0";
+ /* ============ Events ============ */
+ /*//////////////////////////////////////////////////////////////
+ PUBLIC/EXTERNAL FUNCTIONS
+ //////////////////////////////////////////////////////////////*/
+ /**
+ * @inheritdoc IERC3643Base
+ */
+ function version() public view virtual override(IERC3643Base) returns (string memory version_) {
+ return VERSION;
+ }
+}
+
+// lib/openzeppelin-contracts/contracts/utils/math/Math.sol
+
+// OpenZeppelin Contracts (last updated v5.3.0) (utils/math/Math.sol)
+
+/**
+ * @dev Standard math utilities missing in the Solidity language.
+ */
+library Math {
+ enum Rounding {
+ Floor, // Toward negative infinity
+ Ceil, // Toward positive infinity
+ Trunc, // Toward zero
+ Expand // Away from zero
+ }
+
+ /**
+ * @dev Return the 512-bit addition of two uint256.
+ *
+ * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.
+ */
+ function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {
+ assembly ("memory-safe") {
+ low := add(a, b)
+ high := lt(low, a)
+ }
+ }
+
+ /**
+ * @dev Return the 512-bit multiplication of two uint256.
+ *
+ * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.
+ */
+ function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {
+ // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use
+ // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
+ // variables such that product = high * 2²⁵⁶ + low.
+ assembly ("memory-safe") {
+ let mm := mulmod(a, b, not(0))
+ low := mul(a, b)
+ high := sub(sub(mm, low), lt(mm, low))
+ }
+ }
+
+ /**
+ * @dev Returns the addition of two unsigned integers, with a success flag (no overflow).
+ */
+ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
+ unchecked {
+ uint256 c = a + b;
+ success = c >= a;
+ result = c * SafeCast.toUint(success);
+ }
+ }
+
+ /**
+ * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).
+ */
+ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
+ unchecked {
+ uint256 c = a - b;
+ success = c <= a;
+ result = c * SafeCast.toUint(success);
+ }
+ }
+
+ /**
+ * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).
+ */
+ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
+ unchecked {
+ uint256 c = a * b;
+ assembly ("memory-safe") {
+ // Only true when the multiplication doesn't overflow
+ // (c / a == b) || (a == 0)
+ success := or(eq(div(c, a), b), iszero(a))
+ }
+ // equivalent to: success ? c : 0
+ result = c * SafeCast.toUint(success);
+ }
+ }
+
+ /**
+ * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).
+ */
+ function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
+ unchecked {
+ success = b > 0;
+ assembly ("memory-safe") {
+ // The `DIV` opcode returns zero when the denominator is 0.
+ result := div(a, b)
+ }
+ }
+ }
+
+ /**
+ * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).
+ */
+ function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
+ unchecked {
+ success = b > 0;
+ assembly ("memory-safe") {
+ // The `MOD` opcode returns zero when the denominator is 0.
+ result := mod(a, b)
+ }
+ }
+ }
+
+ /**
+ * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.
+ */
+ function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {
+ (bool success, uint256 result) = tryAdd(a, b);
+ return ternary(success, result, type(uint256).max);
+ }
+
+ /**
+ * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.
+ */
+ function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {
+ (, uint256 result) = trySub(a, b);
+ return result;
+ }
+
+ /**
+ * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.
+ */
+ function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {
+ (bool success, uint256 result) = tryMul(a, b);
+ return ternary(success, result, type(uint256).max);
+ }
+
+ /**
+ * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.
+ *
+ * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.
+ * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute
+ * one branch when needed, making this function more expensive.
+ */
+ function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {
+ unchecked {
+ // branchless ternary works because:
+ // b ^ (a ^ b) == a
+ // b ^ 0 == b
+ return b ^ ((a ^ b) * SafeCast.toUint(condition));
+ }
+ }
+
+ /**
+ * @dev Returns the largest of two numbers.
+ */
+ function max(uint256 a, uint256 b) internal pure returns (uint256) {
+ return ternary(a > b, a, b);
+ }
+
+ /**
+ * @dev Returns the smallest of two numbers.
+ */
+ function min(uint256 a, uint256 b) internal pure returns (uint256) {
+ return ternary(a < b, a, b);
+ }
+
+ /**
+ * @dev Returns the average of two numbers. The result is rounded towards
+ * zero.
+ */
+ function average(uint256 a, uint256 b) internal pure returns (uint256) {
+ // (a + b) / 2 can overflow.
+ return (a & b) + (a ^ b) / 2;
+ }
+
+ /**
+ * @dev Returns the ceiling of the division of two numbers.
+ *
+ * This differs from standard division with `/` in that it rounds towards infinity instead
+ * of rounding towards zero.
+ */
+ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
+ if (b == 0) {
+ // Guarantee the same behavior as in a regular Solidity division.
+ Panic.panic(Panic.DIVISION_BY_ZERO);
+ }
+
+ // The following calculation ensures accurate ceiling division without overflow.
+ // Since a is non-zero, (a - 1) / b will not overflow.
+ // The largest possible result occurs when (a - 1) / b is type(uint256).max,
+ // but the largest value we can obtain is type(uint256).max - 1, which happens
+ // when a = type(uint256).max and b = 1.
+ unchecked {
+ return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);
+ }
+ }
+
+ /**
+ * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
+ * denominator == 0.
+ *
+ * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
+ * Uniswap Labs also under MIT license.
+ */
+ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
+ unchecked {
+ (uint256 high, uint256 low) = mul512(x, y);
+
+ // Handle non-overflow cases, 256 by 256 division.
+ if (high == 0) {
+ // Solidity will revert if denominator == 0, unlike the div opcode on its own.
+ // The surrounding unchecked block does not change this fact.
+ // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
+ return low / denominator;
+ }
+
+ // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.
+ if (denominator <= high) {
+ Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));
+ }
+
+ ///////////////////////////////////////////////
+ // 512 by 256 division.
+ ///////////////////////////////////////////////
+
+ // Make division exact by subtracting the remainder from [high low].
+ uint256 remainder;
+ assembly ("memory-safe") {
+ // Compute remainder using mulmod.
+ remainder := mulmod(x, y, denominator)
+
+ // Subtract 256 bit number from 512 bit number.
+ high := sub(high, gt(remainder, low))
+ low := sub(low, remainder)
+ }
+
+ // Factor powers of two out of denominator and compute largest power of two divisor of denominator.
+ // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.
+
+ uint256 twos = denominator & (0 - denominator);
+ assembly ("memory-safe") {
+ // Divide denominator by twos.
+ denominator := div(denominator, twos)
+
+ // Divide [high low] by twos.
+ low := div(low, twos)
+
+ // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.
+ twos := add(div(sub(0, twos), twos), 1)
+ }
+
+ // Shift in bits from high into low.
+ low |= high * twos;
+
+ // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such
+ // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for
+ // four bits. That is, denominator * inv ≡ 1 mod 2⁴.
+ uint256 inverse = (3 * denominator) ^ 2;
+
+ // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
+ // works in modular arithmetic, doubling the correct bits in each step.
+ inverse *= 2 - denominator * inverse; // inverse mod 2⁸
+ inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶
+ inverse *= 2 - denominator * inverse; // inverse mod 2³²
+ inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴
+ inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸
+ inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶
+
+ // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
+ // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is
+ // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high
+ // is no longer required.
+ result = low * inverse;
+ return result;
+ }
+ }
+
+ /**
+ * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.
+ */
+ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
+ return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);
+ }
+
+ /**
+ * @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.
+ */
+ function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {
+ unchecked {
+ (uint256 high, uint256 low) = mul512(x, y);
+ if (high >= 1 << n) {
+ Panic.panic(Panic.UNDER_OVERFLOW);
+ }
+ return (high << (256 - n)) | (low >> n);
+ }
+ }
+
+ /**
+ * @dev Calculates x * y >> n with full precision, following the selected rounding direction.
+ */
+ function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {
+ return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);
+ }
+
+ /**
+ * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.
+ *
+ * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.
+ * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.
+ *
+ * If the input value is not inversible, 0 is returned.
+ *
+ * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the
+ * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.
+ */
+ function invMod(uint256 a, uint256 n) internal pure returns (uint256) {
+ unchecked {
+ if (n == 0) return 0;
+
+ // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)
+ // Used to compute integers x and y such that: ax + ny = gcd(a, n).
+ // When the gcd is 1, then the inverse of a modulo n exists and it's x.
+ // ax + ny = 1
+ // ax = 1 + (-y)n
+ // ax ≡ 1 (mod n) # x is the inverse of a modulo n
+
+ // If the remainder is 0 the gcd is n right away.
+ uint256 remainder = a % n;
+ uint256 gcd = n;
+
+ // Therefore the initial coefficients are:
+ // ax + ny = gcd(a, n) = n
+ // 0a + 1n = n
+ int256 x = 0;
+ int256 y = 1;
+
+ while (remainder != 0) {
+ uint256 quotient = gcd / remainder;
+
+ (gcd, remainder) = (
+ // The old remainder is the next gcd to try.
+ remainder,
+ // Compute the next remainder.
+ // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd
+ // where gcd is at most n (capped to type(uint256).max)
+ gcd - remainder * quotient
+ );
+
+ (x, y) = (
+ // Increment the coefficient of a.
+ y,
+ // Decrement the coefficient of n.
+ // Can overflow, but the result is casted to uint256 so that the
+ // next value of y is "wrapped around" to a value between 0 and n - 1.
+ x - y * int256(quotient)
+ );
+ }
+
+ if (gcd != 1) return 0; // No inverse exists.
+ return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.
+ }
+ }
+
+ /**
+ * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.
+ *
+ * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is
+ * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that
+ * `a**(p-2)` is the modular multiplicative inverse of a in Fp.
+ *
+ * NOTE: this function does NOT check that `p` is a prime greater than `2`.
+ */
+ function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {
+ unchecked {
+ return Math.modExp(a, p - 2, p);
+ }
+ }
+
+ /**
+ * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)
+ *
+ * Requirements:
+ * - modulus can't be zero
+ * - underlying staticcall to precompile must succeed
+ *
+ * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make
+ * sure the chain you're using it on supports the precompiled contract for modular exponentiation
+ * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,
+ * the underlying function will succeed given the lack of a revert, but the result may be incorrectly
+ * interpreted as 0.
+ */
+ function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {
+ (bool success, uint256 result) = tryModExp(b, e, m);
+ if (!success) {
+ Panic.panic(Panic.DIVISION_BY_ZERO);
+ }
+ return result;
+ }
+
+ /**
+ * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).
+ * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying
+ * to operate modulo 0 or if the underlying precompile reverted.
+ *
+ * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain
+ * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in
+ * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack
+ * of a revert, but the result may be incorrectly interpreted as 0.
+ */
+ function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {
+ if (m == 0) return (false, 0);
+ assembly ("memory-safe") {
+ let ptr := mload(0x40)
+ // | Offset | Content | Content (Hex) |
+ // |-----------|------------|--------------------------------------------------------------------|
+ // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 |
+ // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 |
+ // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 |
+ // | 0x60:0x7f | value of b | 0x<.............................................................b> |
+ // | 0x80:0x9f | value of e | 0x<.............................................................e> |
+ // | 0xa0:0xbf | value of m | 0x<.............................................................m> |
+ mstore(ptr, 0x20)
+ mstore(add(ptr, 0x20), 0x20)
+ mstore(add(ptr, 0x40), 0x20)
+ mstore(add(ptr, 0x60), b)
+ mstore(add(ptr, 0x80), e)
+ mstore(add(ptr, 0xa0), m)
+
+ // Given the result < m, it's guaranteed to fit in 32 bytes,
+ // so we can use the memory scratch space located at offset 0.
+ success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)
+ result := mload(0x00)
+ }
+ }
+
+ /**
+ * @dev Variant of {modExp} that supports inputs of arbitrary length.
+ */
+ function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {
+ (bool success, bytes memory result) = tryModExp(b, e, m);
+ if (!success) {
+ Panic.panic(Panic.DIVISION_BY_ZERO);
+ }
+ return result;
+ }
+
+ /**
+ * @dev Variant of {tryModExp} that supports inputs of arbitrary length.
+ */
+ function tryModExp(
+ bytes memory b,
+ bytes memory e,
+ bytes memory m
+ ) internal view returns (bool success, bytes memory result) {
+ if (_zeroBytes(m)) return (false, new bytes(0));
+
+ uint256 mLen = m.length;
+
+ // Encode call args in result and move the free memory pointer
+ result = abi.encodePacked(b.length, e.length, mLen, b, e, m);
+
+ assembly ("memory-safe") {
+ let dataPtr := add(result, 0x20)
+ // Write result on top of args to avoid allocating extra memory.
+ success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)
+ // Overwrite the length.
+ // result.length > returndatasize() is guaranteed because returndatasize() == m.length
+ mstore(result, mLen)
+ // Set the memory pointer after the returned data.
+ mstore(0x40, add(dataPtr, mLen))
+ }
+ }
+
+ /**
+ * @dev Returns whether the provided byte array is zero.
+ */
+ function _zeroBytes(bytes memory byteArray) private pure returns (bool) {
+ for (uint256 i = 0; i < byteArray.length; ++i) {
+ if (byteArray[i] != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
+ * towards zero.
+ *
+ * This method is based on Newton's method for computing square roots; the algorithm is restricted to only
+ * using integer operations.
+ */
+ function sqrt(uint256 a) internal pure returns (uint256) {
+ unchecked {
+ // Take care of easy edge cases when a == 0 or a == 1
+ if (a <= 1) {
+ return a;
+ }
+
+ // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a
+ // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between
+ // the current value as `ε_n = | x_n - sqrt(a) |`.
+ //
+ // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root
+ // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is
+ // bigger than any uint256.
+ //
+ // By noticing that
+ // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`
+ // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar
+ // to the msb function.
+ uint256 aa = a;
+ uint256 xn = 1;
+
+ if (aa >= (1 << 128)) {
+ aa >>= 128;
+ xn <<= 64;
+ }
+ if (aa >= (1 << 64)) {
+ aa >>= 64;
+ xn <<= 32;
+ }
+ if (aa >= (1 << 32)) {
+ aa >>= 32;
+ xn <<= 16;
+ }
+ if (aa >= (1 << 16)) {
+ aa >>= 16;
+ xn <<= 8;
+ }
+ if (aa >= (1 << 8)) {
+ aa >>= 8;
+ xn <<= 4;
+ }
+ if (aa >= (1 << 4)) {
+ aa >>= 4;
+ xn <<= 2;
+ }
+ if (aa >= (1 << 2)) {
+ xn <<= 1;
+ }
+
+ // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).
+ //
+ // We can refine our estimation by noticing that the middle of that interval minimizes the error.
+ // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).
+ // This is going to be our x_0 (and ε_0)
+ xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)
+
+ // From here, Newton's method give us:
+ // x_{n+1} = (x_n + a / x_n) / 2
+ //
+ // One should note that:
+ // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a
+ // = ((x_n² + a) / (2 * x_n))² - a
+ // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a
+ // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)
+ // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)
+ // = (x_n² - a)² / (2 * x_n)²
+ // = ((x_n² - a) / (2 * x_n))²
+ // ≥ 0
+ // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n
+ //
+ // This gives us the proof of quadratic convergence of the sequence:
+ // ε_{n+1} = | x_{n+1} - sqrt(a) |
+ // = | (x_n + a / x_n) / 2 - sqrt(a) |
+ // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |
+ // = | (x_n - sqrt(a))² / (2 * x_n) |
+ // = | ε_n² / (2 * x_n) |
+ // = ε_n² / | (2 * x_n) |
+ //
+ // For the first iteration, we have a special case where x_0 is known:
+ // ε_1 = ε_0² / | (2 * x_0) |
+ // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))
+ // ≤ 2**(2*e-4) / (3 * 2**(e-1))
+ // ≤ 2**(e-3) / 3
+ // ≤ 2**(e-3-log2(3))
+ // ≤ 2**(e-4.5)
+ //
+ // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:
+ // ε_{n+1} = ε_n² / | (2 * x_n) |
+ // ≤ (2**(e-k))² / (2 * 2**(e-1))
+ // ≤ 2**(2*e-2*k) / 2**e
+ // ≤ 2**(e-2*k)
+ xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above
+ xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5
+ xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9
+ xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18
+ xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36
+ xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72
+
+ // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision
+ // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either
+ // sqrt(a) or sqrt(a) + 1.
+ return xn - SafeCast.toUint(xn > a / xn);
+ }
+ }
+
+ /**
+ * @dev Calculates sqrt(a), following the selected rounding direction.
+ */
+ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
+ unchecked {
+ uint256 result = sqrt(a);
+ return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);
+ }
+ }
+
+ /**
+ * @dev Return the log in base 2 of a positive value rounded towards zero.
+ * Returns 0 if given 0.
+ */
+ function log2(uint256 x) internal pure returns (uint256 r) {
+ // If value has upper 128 bits set, log2 result is at least 128
+ r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;
+ // If upper 64 bits of 128-bit half set, add 64 to result
+ r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;
+ // If upper 32 bits of 64-bit half set, add 32 to result
+ r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;
+ // If upper 16 bits of 32-bit half set, add 16 to result
+ r |= SafeCast.toUint((x >> r) > 0xffff) << 4;
+ // If upper 8 bits of 16-bit half set, add 8 to result
+ r |= SafeCast.toUint((x >> r) > 0xff) << 3;
+ // If upper 4 bits of 8-bit half set, add 4 to result
+ r |= SafeCast.toUint((x >> r) > 0xf) << 2;
+
+ // Shifts value right by the current result and use it as an index into this lookup table:
+ //
+ // | x (4 bits) | index | table[index] = MSB position |
+ // |------------|---------|-----------------------------|
+ // | 0000 | 0 | table[0] = 0 |
+ // | 0001 | 1 | table[1] = 0 |
+ // | 0010 | 2 | table[2] = 1 |
+ // | 0011 | 3 | table[3] = 1 |
+ // | 0100 | 4 | table[4] = 2 |
+ // | 0101 | 5 | table[5] = 2 |
+ // | 0110 | 6 | table[6] = 2 |
+ // | 0111 | 7 | table[7] = 2 |
+ // | 1000 | 8 | table[8] = 3 |
+ // | 1001 | 9 | table[9] = 3 |
+ // | 1010 | 10 | table[10] = 3 |
+ // | 1011 | 11 | table[11] = 3 |
+ // | 1100 | 12 | table[12] = 3 |
+ // | 1101 | 13 | table[13] = 3 |
+ // | 1110 | 14 | table[14] = 3 |
+ // | 1111 | 15 | table[15] = 3 |
+ //
+ // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the last 16 bytes.
+ assembly ("memory-safe") {
+ r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))
+ }
+ }
+
+ /**
+ * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
+ * Returns 0 if given 0.
+ */
+ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
+ unchecked {
+ uint256 result = log2(value);
+ return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);
+ }
+ }
+
+ /**
+ * @dev Return the log in base 10 of a positive value rounded towards zero.
+ * Returns 0 if given 0.
+ */
+ function log10(uint256 value) internal pure returns (uint256) {
+ uint256 result = 0;
+ unchecked {
+ if (value >= 10 ** 64) {
+ value /= 10 ** 64;
+ result += 64;
+ }
+ if (value >= 10 ** 32) {
+ value /= 10 ** 32;
+ result += 32;
+ }
+ if (value >= 10 ** 16) {
+ value /= 10 ** 16;
+ result += 16;
+ }
+ if (value >= 10 ** 8) {
+ value /= 10 ** 8;
+ result += 8;
+ }
+ if (value >= 10 ** 4) {
+ value /= 10 ** 4;
+ result += 4;
+ }
+ if (value >= 10 ** 2) {
+ value /= 10 ** 2;
+ result += 2;
+ }
+ if (value >= 10 ** 1) {
+ result += 1;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
+ * Returns 0 if given 0.
+ */
+ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
+ unchecked {
+ uint256 result = log10(value);
+ return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);
+ }
+ }
+
+ /**
+ * @dev Return the log in base 256 of a positive value rounded towards zero.
+ * Returns 0 if given 0.
+ *
+ * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
+ */
+ function log256(uint256 x) internal pure returns (uint256 r) {
+ // If value has upper 128 bits set, log2 result is at least 128
+ r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;
+ // If upper 64 bits of 128-bit half set, add 64 to result
+ r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;
+ // If upper 32 bits of 64-bit half set, add 32 to result
+ r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;
+ // If upper 16 bits of 32-bit half set, add 16 to result
+ r |= SafeCast.toUint((x >> r) > 0xffff) << 4;
+ // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8
+ return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);
+ }
+
+ /**
+ * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
+ * Returns 0 if given 0.
+ */
+ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
+ unchecked {
+ uint256 result = log256(value);
+ return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);
+ }
+ }
+
+ /**
+ * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
+ */
+ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
+ return uint8(rounding) % 2 == 1;
+ }
+}
+
+// src/modules/ERC2771ModuleStandalone.sol
+
+/* ==== OpenZeppelin === */
+
+/**
+ * @dev Meta transaction (gasless) module.
+ */
+abstract contract ERC2771ModuleStandalone is ERC2771Context {
+ constructor(address trustedForwarder) ERC2771Context(trustedForwarder) {
+ // Nothing to do
+ }
+}
+
+// lib/CMTAT/contracts/interfaces/engine/IRuleEngine.sol
+
+/*
+* @title Minimum interface to define a RuleEngine
+*/
+interface IRuleEngine is IERC1404Extend, IERC7551Compliance, IERC3643IComplianceContract {
+ /**
+ * @notice
+ * Function called whenever tokens are transferred from one wallet to another
+ * @dev
+ * Must revert if the transfer is invalid
+ * Same name as ERC-3643 but with one supplementary argument `spender`
+ * This function can be used to update state variables of the RuleEngine contract
+ * This function can be called ONLY by the token contract bound to the RuleEngine
+ * @param spender spender address (sender)
+ * @param from token holder address
+ * @param to receiver address
+ * @param value value of tokens involved in the transfer
+ */
+ function transferred(address spender, address from, address to, uint256 value) external;
+}
+
+// lib/openzeppelin-contracts/contracts/access/AccessControl.sol
+
+// OpenZeppelin Contracts (last updated v5.4.0) (access/AccessControl.sol)
+
+/**
+ * @dev Contract module that allows children to implement role-based access
+ * control mechanisms. This is a lightweight version that doesn't allow enumerating role
+ * members except through off-chain means by accessing the contract event logs. Some
+ * applications may benefit from on-chain enumerability, for those cases see
+ * {AccessControlEnumerable}.
+ *
+ * Roles are referred to by their `bytes32` identifier. These should be exposed
+ * in the external API and be unique. The best way to achieve this is by
+ * using `public constant` hash digests:
+ *
+ * ```solidity
+ * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
+ * ```
+ *
+ * Roles can be used to represent a set of permissions. To restrict access to a
+ * function call, use {hasRole}:
+ *
+ * ```solidity
+ * function foo() public {
+ * require(hasRole(MY_ROLE, msg.sender));
+ * ...
+ * }
+ * ```
+ *
+ * Roles can be granted and revoked dynamically via the {grantRole} and
+ * {revokeRole} functions. Each role has an associated admin role, and only
+ * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
+ *
+ * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
+ * that only accounts with this role will be able to grant or revoke other
+ * roles. More complex role relationships can be created by using
+ * {_setRoleAdmin}.
+ *
+ * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
+ * grant and revoke this role. Extra precautions should be taken to secure
+ * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
+ * to enforce additional security measures for this role.
+ */
+abstract contract AccessControl is Context, IAccessControl, ERC165 {
+ struct RoleData {
+ mapping(address account => bool) hasRole;
+ bytes32 adminRole;
+ }
+
+ mapping(bytes32 role => RoleData) private _roles;
+
+ bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
+
+ /**
+ * @dev Modifier that checks that an account has a specific role. Reverts
+ * with an {AccessControlUnauthorizedAccount} error including the required role.
+ */
+ modifier onlyRole(bytes32 role) {
+ _checkRole(role);
+ _;
+ }
+
+ /// @inheritdoc IERC165
+ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
+ return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
+ }
+
+ /**
+ * @dev Returns `true` if `account` has been granted `role`.
+ */
+ function hasRole(bytes32 role, address account) public view virtual returns (bool) {
+ return _roles[role].hasRole[account];
+ }
+
+ /**
+ * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
+ * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
+ */
+ function _checkRole(bytes32 role) internal view virtual {
+ _checkRole(role, _msgSender());
+ }
+
+ /**
+ * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
+ * is missing `role`.
+ */
+ function _checkRole(bytes32 role, address account) internal view virtual {
+ if (!hasRole(role, account)) {
+ revert AccessControlUnauthorizedAccount(account, role);
+ }
+ }
+
+ /**
+ * @dev Returns the admin role that controls `role`. See {grantRole} and
+ * {revokeRole}.
+ *
+ * To change a role's admin, use {_setRoleAdmin}.
+ */
+ function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
+ return _roles[role].adminRole;
+ }
+
+ /**
+ * @dev Grants `role` to `account`.
+ *
+ * If `account` had not been already granted `role`, emits a {RoleGranted}
+ * event.
+ *
+ * Requirements:
+ *
+ * - the caller must have ``role``'s admin role.
+ *
+ * May emit a {RoleGranted} event.
+ */
+ function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
+ _grantRole(role, account);
+ }
+
+ /**
+ * @dev Revokes `role` from `account`.
+ *
+ * If `account` had been granted `role`, emits a {RoleRevoked} event.
+ *
+ * Requirements:
+ *
+ * - the caller must have ``role``'s admin role.
+ *
+ * May emit a {RoleRevoked} event.
+ */
+ function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
+ _revokeRole(role, account);
+ }
+
+ /**
+ * @dev Revokes `role` from the calling account.
+ *
+ * Roles are often managed via {grantRole} and {revokeRole}: this function's
+ * purpose is to provide a mechanism for accounts to lose their privileges
+ * if they are compromised (such as when a trusted device is misplaced).
+ *
+ * If the calling account had been revoked `role`, emits a {RoleRevoked}
+ * event.
+ *
+ * Requirements:
+ *
+ * - the caller must be `callerConfirmation`.
+ *
+ * May emit a {RoleRevoked} event.
+ */
+ function renounceRole(bytes32 role, address callerConfirmation) public virtual {
+ if (callerConfirmation != _msgSender()) {
+ revert AccessControlBadConfirmation();
+ }
+
+ _revokeRole(role, callerConfirmation);
+ }
+
+ /**
+ * @dev Sets `adminRole` as ``role``'s admin role.
+ *
+ * Emits a {RoleAdminChanged} event.
+ */
+ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
+ bytes32 previousAdminRole = getRoleAdmin(role);
+ _roles[role].adminRole = adminRole;
+ emit RoleAdminChanged(role, previousAdminRole, adminRole);
+ }
+
+ /**
+ * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
+ *
+ * Internal function without access restriction.
+ *
+ * May emit a {RoleGranted} event.
+ */
+ function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
+ if (!hasRole(role, account)) {
+ _roles[role].hasRole[account] = true;
+ emit RoleGranted(role, account, _msgSender());
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.
+ *
+ * Internal function without access restriction.
+ *
+ * May emit a {RoleRevoked} event.
+ */
+ function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
+ if (hasRole(role, account)) {
+ _roles[role].hasRole[account] = false;
+ emit RoleRevoked(role, account, _msgSender());
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+
+// src/interfaces/IRule.sol
+
+/* ==== CMTAT === */
+
+/* ==== Interfaces === */
+
+interface IRule is IRuleEngine {
+ /**
+ * @dev Returns true if the restriction code exists, and false otherwise.
+ */
+ function canReturnTransferRestrictionCode(
+ uint8 restrictionCode
+ ) external view returns (bool);
+}
+
+// src/interfaces/IRulesManagementModule.sol
+
+/* ==== Interfaces === */
+
+interface IRulesManagementModule {
+ /**
+ * @notice Defines the rules for the rule engine.
+ * @dev Sets the list of rule contract addresses for s.
+ * Any previously set rules will be completely overwritten by the new list.
+ * Rules should be deployed contracts that implement the expected interface.
+ * @param rules_ The array of addresses representing the new rules to be set.
+ * @dev Revert if one rule is a zero address or if the rule is already present
+ * This function calls _clearRules if at least one rule is still configured
+ */
+ function setRules(IRule[] calldata rules_) external;
+
+ /**
+ * @notice Returns the total number of currently configured rules.
+ * @dev Equivalent to the length of the internal rules array.
+ * Complexity: O(1)
+ * @return numberOfrules The number of active rules.
+ */
+ function rulesCount() external view returns (uint256 numberOfrules);
+
+ /**
+ * @notice Retrieves the rule address at a specific index.
+ * @dev Reverts if `ruleId` is out of bounds.
+ * Complexity: O(1).
+ * Note that there are no guarantees on the ordering of values inside the array,
+ * and it may change when more values are added or removed.
+ * @param ruleId The index of the desired rule in the array.
+ * @return ruleAddress The address of the corresponding IRule contract, return the `zero address` is out of bounds.
+ */
+ function rule(uint256 ruleId) external view returns (address ruleAddress);
+
+ /**
+ * @notice Returns the full list of currently configured rules.
+ * @dev This is a view-only function that does not modify state.
+ * This operation will copy the entire storage to memory, which can be quite expensive.
+ * This is designed to mostly be used by view accessors that are queried without any gas fees.
+ * @return ruleAddresses An array of all active rule contract addresses.
+ */
+ function rules() external view returns (address[] memory ruleAddresses);
+
+ /**
+ * @notice Removes all configured rules.
+ * @dev After calling this function, no rules will remain set.
+ * Developers should keep in mind that this function has an unbounded cost
+ * and using it may render the function uncallable if the set grows to the point
+ * where clearing it consumes too much gas to fit in a block.
+ */
+ function clearRules() external;
+
+ /**
+ * @notice Adds a new rule to the current rule set.
+ * @dev Reverts if the rule address is zero or already exists in the set.
+ * Complexity: O(1).
+ * @param rule_ The IRule contract to add.
+ */
+ function addRule(
+ IRule rule_
+ ) external;
+
+ /**
+ * @notice Removes a specific rule from the current rule set.
+ * @dev Reverts if the provided rule is not found or does not match the stored rule at its index.
+ * Complexity: O(1).
+ * @param rule_ The IRule contract to remove.
+ */
+ function removeRule(
+ IRule rule_
+ ) external;
+
+ /**
+ * @notice Checks whether a specific rule is currently configured.
+ * @param rule_ The IRule contract to check for membership.
+ * @dev Complexity: O(1).
+ * @return exists True if the rule is present, false otherwise.
+ */
+ function containsRule(IRule rule_) external returns (bool exists);
+}
+
+// src/modules/library/RulesManagementModuleInvariantStorage.sol
+
+abstract contract RulesManagementModuleInvariantStorage {
+ /* ==== Errors === */
+ error RuleEngine_RulesManagementModule_RuleAddressZeroNotAllowed();
+ error RuleEngine_RulesManagementModule_RuleAlreadyExists();
+ error RuleEngine_RulesManagementModule_RuleDoNotMatch();
+ error RuleEngine_RulesManagementModule_ArrayIsEmpty();
+ error RuleEngine_RulesManagementModule_OperationNotSuccessful();
+
+ /* ============ Events ============ */
+ /**
+ * @notice Emitted when a new rule is added to the rule set.
+ * @param rule The address of the rule contract that was added.
+ */
+ event AddRule(IRule indexed rule);
+
+ /**
+ * @notice Emitted when a rule is removed from the rule set.
+ * @param rule The address of the rule contract that was removed.
+ */
+ event RemoveRule(IRule indexed rule);
+
+ /**
+ * @notice Emitted when all rules are cleared from the rule set.
+ */
+ event ClearRules();
+
+ /* ==== Constant === */
+ /// @notice Role to manage the ruleEngine
+ bytes32 public constant RULES_MANAGEMENT_ROLE =
+ keccak256("RULES_MANAGEMENT_ROLE");
+}
+
+// lib/openzeppelin-contracts/contracts/utils/Arrays.sol
+
+// OpenZeppelin Contracts (last updated v5.4.0) (utils/Arrays.sol)
+// This file was procedurally generated from scripts/generate/templates/Arrays.js.
+
+/**
+ * @dev Collection of functions related to array types.
+ */
+library Arrays {
+ using SlotDerivation for bytes32;
+ using StorageSlot for bytes32;
+
+ /**
+ * @dev Sort an array of uint256 (in memory) following the provided comparator function.
+ *
+ * This function does the sorting "in place", meaning that it overrides the input. The object is returned for
+ * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
+ *
+ * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
+ * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
+ * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
+ * consume more gas than is available in a block, leading to potential DoS.
+ *
+ * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
+ */
+ function sort(
+ uint256[] memory array,
+ function(uint256, uint256) pure returns (bool) comp
+ ) internal pure returns (uint256[] memory) {
+ _quickSort(_begin(array), _end(array), comp);
+ return array;
+ }
+
+ /**
+ * @dev Variant of {sort} that sorts an array of uint256 in increasing order.
+ */
+ function sort(uint256[] memory array) internal pure returns (uint256[] memory) {
+ sort(array, Comparators.lt);
+ return array;
+ }
+
+ /**
+ * @dev Sort an array of address (in memory) following the provided comparator function.
+ *
+ * This function does the sorting "in place", meaning that it overrides the input. The object is returned for
+ * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
+ *
+ * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
+ * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
+ * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
+ * consume more gas than is available in a block, leading to potential DoS.
+ *
+ * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
+ */
+ function sort(
+ address[] memory array,
+ function(address, address) pure returns (bool) comp
+ ) internal pure returns (address[] memory) {
+ sort(_castToUint256Array(array), _castToUint256Comp(comp));
+ return array;
+ }
+
+ /**
+ * @dev Variant of {sort} that sorts an array of address in increasing order.
+ */
+ function sort(address[] memory array) internal pure returns (address[] memory) {
+ sort(_castToUint256Array(array), Comparators.lt);
+ return array;
+ }
+
+ /**
+ * @dev Sort an array of bytes32 (in memory) following the provided comparator function.
+ *
+ * This function does the sorting "in place", meaning that it overrides the input. The object is returned for
+ * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
+ *
+ * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
+ * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
+ * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
+ * consume more gas than is available in a block, leading to potential DoS.
+ *
+ * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
+ */
+ function sort(
+ bytes32[] memory array,
+ function(bytes32, bytes32) pure returns (bool) comp
+ ) internal pure returns (bytes32[] memory) {
+ sort(_castToUint256Array(array), _castToUint256Comp(comp));
+ return array;
+ }
+
+ /**
+ * @dev Variant of {sort} that sorts an array of bytes32 in increasing order.
+ */
+ function sort(bytes32[] memory array) internal pure returns (bytes32[] memory) {
+ sort(_castToUint256Array(array), Comparators.lt);
+ return array;
+ }
+
+ /**
+ * @dev Performs a quick sort of a segment of memory. The segment sorted starts at `begin` (inclusive), and stops
+ * at end (exclusive). Sorting follows the `comp` comparator.
+ *
+ * Invariant: `begin <= end`. This is the case when initially called by {sort} and is preserved in subcalls.
+ *
+ * IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should
+ * be used only if the limits are within a memory array.
+ */
+ function _quickSort(uint256 begin, uint256 end, function(uint256, uint256) pure returns (bool) comp) private pure {
+ unchecked {
+ if (end - begin < 0x40) return;
+
+ // Use first element as pivot
+ uint256 pivot = _mload(begin);
+ // Position where the pivot should be at the end of the loop
+ uint256 pos = begin;
+
+ for (uint256 it = begin + 0x20; it < end; it += 0x20) {
+ if (comp(_mload(it), pivot)) {
+ // If the value stored at the iterator's position comes before the pivot, we increment the
+ // position of the pivot and move the value there.
+ pos += 0x20;
+ _swap(pos, it);
+ }
+ }
+
+ _swap(begin, pos); // Swap pivot into place
+ _quickSort(begin, pos, comp); // Sort the left side of the pivot
+ _quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot
+ }
+ }
+
+ /**
+ * @dev Pointer to the memory location of the first element of `array`.
+ */
+ function _begin(uint256[] memory array) private pure returns (uint256 ptr) {
+ assembly ("memory-safe") {
+ ptr := add(array, 0x20)
+ }
+ }
+
+ /**
+ * @dev Pointer to the memory location of the first memory word (32bytes) after `array`. This is the memory word
+ * that comes just after the last element of the array.
+ */
+ function _end(uint256[] memory array) private pure returns (uint256 ptr) {
+ unchecked {
+ return _begin(array) + array.length * 0x20;
+ }
+ }
+
+ /**
+ * @dev Load memory word (as a uint256) at location `ptr`.
+ */
+ function _mload(uint256 ptr) private pure returns (uint256 value) {
+ assembly {
+ value := mload(ptr)
+ }
+ }
+
+ /**
+ * @dev Swaps the elements memory location `ptr1` and `ptr2`.
+ */
+ function _swap(uint256 ptr1, uint256 ptr2) private pure {
+ assembly {
+ let value1 := mload(ptr1)
+ let value2 := mload(ptr2)
+ mstore(ptr1, value2)
+ mstore(ptr2, value1)
+ }
+ }
+
+ /// @dev Helper: low level cast address memory array to uint256 memory array
+ function _castToUint256Array(address[] memory input) private pure returns (uint256[] memory output) {
+ assembly {
+ output := input
+ }
+ }
+
+ /// @dev Helper: low level cast bytes32 memory array to uint256 memory array
+ function _castToUint256Array(bytes32[] memory input) private pure returns (uint256[] memory output) {
+ assembly {
+ output := input
+ }
+ }
+
+ /// @dev Helper: low level cast address comp function to uint256 comp function
+ function _castToUint256Comp(
+ function(address, address) pure returns (bool) input
+ ) private pure returns (function(uint256, uint256) pure returns (bool) output) {
+ assembly {
+ output := input
+ }
+ }
+
+ /// @dev Helper: low level cast bytes32 comp function to uint256 comp function
+ function _castToUint256Comp(
+ function(bytes32, bytes32) pure returns (bool) input
+ ) private pure returns (function(uint256, uint256) pure returns (bool) output) {
+ assembly {
+ output := input
+ }
+ }
+
+ /**
+ * @dev Searches a sorted `array` and returns the first index that contains
+ * a value greater or equal to `element`. If no such index exists (i.e. all
+ * values in the array are strictly less than `element`), the array length is
+ * returned. Time complexity O(log n).
+ *
+ * NOTE: The `array` is expected to be sorted in ascending order, and to
+ * contain no repeated elements.
+ *
+ * IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks
+ * support for repeated elements in the array. The {lowerBound} function should
+ * be used instead.
+ */
+ function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
+ uint256 low = 0;
+ uint256 high = array.length;
+
+ if (high == 0) {
+ return 0;
+ }
+
+ while (low < high) {
+ uint256 mid = Math.average(low, high);
+
+ // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
+ // because Math.average rounds towards zero (it does integer division with truncation).
+ if (unsafeAccess(array, mid).value > element) {
+ high = mid;
+ } else {
+ low = mid + 1;
+ }
+ }
+
+ // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
+ if (low > 0 && unsafeAccess(array, low - 1).value == element) {
+ return low - 1;
+ } else {
+ return low;
+ }
+ }
+
+ /**
+ * @dev Searches an `array` sorted in ascending order and returns the first
+ * index that contains a value greater or equal than `element`. If no such index
+ * exists (i.e. all values in the array are strictly less than `element`), the array
+ * length is returned. Time complexity O(log n).
+ *
+ * See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound].
+ */
+ function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
+ uint256 low = 0;
+ uint256 high = array.length;
+
+ if (high == 0) {
+ return 0;
+ }
+
+ while (low < high) {
+ uint256 mid = Math.average(low, high);
+
+ // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
+ // because Math.average rounds towards zero (it does integer division with truncation).
+ if (unsafeAccess(array, mid).value < element) {
+ // this cannot overflow because mid < high
+ unchecked {
+ low = mid + 1;
+ }
+ } else {
+ high = mid;
+ }
+ }
+
+ return low;
+ }
+
+ /**
+ * @dev Searches an `array` sorted in ascending order and returns the first
+ * index that contains a value strictly greater than `element`. If no such index
+ * exists (i.e. all values in the array are strictly less than `element`), the array
+ * length is returned. Time complexity O(log n).
+ *
+ * See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound].
+ */
+ function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
+ uint256 low = 0;
+ uint256 high = array.length;
+
+ if (high == 0) {
+ return 0;
+ }
+
+ while (low < high) {
+ uint256 mid = Math.average(low, high);
+
+ // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
+ // because Math.average rounds towards zero (it does integer division with truncation).
+ if (unsafeAccess(array, mid).value > element) {
+ high = mid;
+ } else {
+ // this cannot overflow because mid < high
+ unchecked {
+ low = mid + 1;
+ }
+ }
+ }
+
+ return low;
+ }
+
+ /**
+ * @dev Same as {lowerBound}, but with an array in memory.
+ */
+ function lowerBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {
+ uint256 low = 0;
+ uint256 high = array.length;
+
+ if (high == 0) {
+ return 0;
+ }
+
+ while (low < high) {
+ uint256 mid = Math.average(low, high);
+
+ // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
+ // because Math.average rounds towards zero (it does integer division with truncation).
+ if (unsafeMemoryAccess(array, mid) < element) {
+ // this cannot overflow because mid < high
+ unchecked {
+ low = mid + 1;
+ }
+ } else {
+ high = mid;
+ }
+ }
+
+ return low;
+ }
+
+ /**
+ * @dev Same as {upperBound}, but with an array in memory.
+ */
+ function upperBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {
+ uint256 low = 0;
+ uint256 high = array.length;
+
+ if (high == 0) {
+ return 0;
+ }
+
+ while (low < high) {
+ uint256 mid = Math.average(low, high);
+
+ // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
+ // because Math.average rounds towards zero (it does integer division with truncation).
+ if (unsafeMemoryAccess(array, mid) > element) {
+ high = mid;
+ } else {
+ // this cannot overflow because mid < high
+ unchecked {
+ low = mid + 1;
+ }
+ }
+ }
+
+ return low;
+ }
+
+ /**
+ * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
+ *
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
+ */
+ function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {
+ bytes32 slot;
+ assembly ("memory-safe") {
+ slot := arr.slot
+ }
+ return slot.deriveArray().offset(pos).getAddressSlot();
+ }
+
+ /**
+ * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
+ *
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
+ */
+ function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {
+ bytes32 slot;
+ assembly ("memory-safe") {
+ slot := arr.slot
+ }
+ return slot.deriveArray().offset(pos).getBytes32Slot();
+ }
+
+ /**
+ * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
+ *
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
+ */
+ function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {
+ bytes32 slot;
+ assembly ("memory-safe") {
+ slot := arr.slot
+ }
+ return slot.deriveArray().offset(pos).getUint256Slot();
+ }
+
+ /**
+ * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
+ *
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
+ */
+ function unsafeAccess(bytes[] storage arr, uint256 pos) internal pure returns (StorageSlot.BytesSlot storage) {
+ bytes32 slot;
+ assembly ("memory-safe") {
+ slot := arr.slot
+ }
+ return slot.deriveArray().offset(pos).getBytesSlot();
+ }
+
+ /**
+ * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
+ *
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
+ */
+ function unsafeAccess(string[] storage arr, uint256 pos) internal pure returns (StorageSlot.StringSlot storage) {
+ bytes32 slot;
+ assembly ("memory-safe") {
+ slot := arr.slot
+ }
+ return slot.deriveArray().offset(pos).getStringSlot();
+ }
+
+ /**
+ * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
+ *
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
+ */
+ function unsafeMemoryAccess(address[] memory arr, uint256 pos) internal pure returns (address res) {
+ assembly {
+ res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
+ }
+ }
+
+ /**
+ * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
+ *
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
+ */
+ function unsafeMemoryAccess(bytes32[] memory arr, uint256 pos) internal pure returns (bytes32 res) {
+ assembly {
+ res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
+ }
+ }
+
+ /**
+ * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
+ *
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
+ */
+ function unsafeMemoryAccess(uint256[] memory arr, uint256 pos) internal pure returns (uint256 res) {
+ assembly {
+ res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
+ }
+ }
+
+ /**
+ * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
+ *
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
+ */
+ function unsafeMemoryAccess(bytes[] memory arr, uint256 pos) internal pure returns (bytes memory res) {
+ assembly {
+ res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
+ }
+ }
+
+ /**
+ * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
+ *
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
+ */
+ function unsafeMemoryAccess(string[] memory arr, uint256 pos) internal pure returns (string memory res) {
+ assembly {
+ res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
+ }
+ }
+
+ /**
+ * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
+ *
+ * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
+ */
+ function unsafeSetLength(address[] storage array, uint256 len) internal {
+ assembly ("memory-safe") {
+ sstore(array.slot, len)
+ }
+ }
+
+ /**
+ * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
+ *
+ * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
+ */
+ function unsafeSetLength(bytes32[] storage array, uint256 len) internal {
+ assembly ("memory-safe") {
+ sstore(array.slot, len)
+ }
+ }
+
+ /**
+ * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
+ *
+ * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
+ */
+ function unsafeSetLength(uint256[] storage array, uint256 len) internal {
+ assembly ("memory-safe") {
+ sstore(array.slot, len)
+ }
+ }
+
+ /**
+ * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
+ *
+ * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
+ */
+ function unsafeSetLength(bytes[] storage array, uint256 len) internal {
+ assembly ("memory-safe") {
+ sstore(array.slot, len)
+ }
+ }
+
+ /**
+ * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
+ *
+ * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
+ */
+ function unsafeSetLength(string[] storage array, uint256 len) internal {
+ assembly ("memory-safe") {
+ sstore(array.slot, len)
+ }
+ }
+}
+
+// lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol
+
+// OpenZeppelin Contracts (last updated v5.4.0) (utils/structs/EnumerableSet.sol)
+// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
+
+/**
+ * @dev Library for managing
+ * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
+ * types.
+ *
+ * Sets have the following properties:
+ *
+ * - Elements are added, removed, and checked for existence in constant time
+ * (O(1)).
+ * - Elements are enumerated in O(n). No guarantees are made on the ordering.
+ * - Set can be cleared (all elements removed) in O(n).
+ *
+ * ```solidity
+ * contract Example {
+ * // Add the library methods
+ * using EnumerableSet for EnumerableSet.AddressSet;
+ *
+ * // Declare a set state variable
+ * EnumerableSet.AddressSet private mySet;
+ * }
+ * ```
+ *
+ * The following types are supported:
+ *
+ * - `bytes32` (`Bytes32Set`) since v3.3.0
+ * - `address` (`AddressSet`) since v3.3.0
+ * - `uint256` (`UintSet`) since v3.3.0
+ * - `string` (`StringSet`) since v5.4.0
+ * - `bytes` (`BytesSet`) since v5.4.0
+ *
+ * [WARNING]
+ * ====
+ * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
+ * unusable.
+ * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
+ *
+ * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
+ * array of EnumerableSet.
+ * ====
+ */
+library EnumerableSet {
+ // To implement this library for multiple types with as little code
+ // repetition as possible, we write it in terms of a generic Set type with
+ // bytes32 values.
+ // The Set implementation uses private functions, and user-facing
+ // implementations (such as AddressSet) are just wrappers around the
+ // underlying Set.
+ // This means that we can only create new EnumerableSets for types that fit
+ // in bytes32.
+
+ struct Set {
+ // Storage of set values
+ bytes32[] _values;
+ // Position is the index of the value in the `values` array plus 1.
+ // Position 0 is used to mean a value is not in the set.
+ mapping(bytes32 value => uint256) _positions;
+ }
+
+ /**
+ * @dev Add a value to a set. O(1).
+ *
+ * Returns true if the value was added to the set, that is if it was not
+ * already present.
+ */
+ function _add(Set storage set, bytes32 value) private returns (bool) {
+ if (!_contains(set, value)) {
+ set._values.push(value);
+ // The value is stored at length-1, but we add 1 to all indexes
+ // and use 0 as a sentinel value
+ set._positions[value] = set._values.length;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @dev Removes a value from a set. O(1).
+ *
+ * Returns true if the value was removed from the set, that is if it was
+ * present.
+ */
+ function _remove(Set storage set, bytes32 value) private returns (bool) {
+ // We cache the value's position to prevent multiple reads from the same storage slot
+ uint256 position = set._positions[value];
+
+ if (position != 0) {
+ // Equivalent to contains(set, value)
+ // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
+ // the array, and then remove the last element (sometimes called as 'swap and pop').
+ // This modifies the order of the array, as noted in {at}.
+
+ uint256 valueIndex = position - 1;
+ uint256 lastIndex = set._values.length - 1;
+
+ if (valueIndex != lastIndex) {
+ bytes32 lastValue = set._values[lastIndex];
+
+ // Move the lastValue to the index where the value to delete is
+ set._values[valueIndex] = lastValue;
+ // Update the tracked position of the lastValue (that was just moved)
+ set._positions[lastValue] = position;
+ }
+
+ // Delete the slot where the moved value was stored
+ set._values.pop();
+
+ // Delete the tracked position for the deleted slot
+ delete set._positions[value];
+
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @dev Removes all the values from a set. O(n).
+ *
+ * WARNING: This function has an unbounded cost that scales with set size. Developers should keep in mind that
+ * using it may render the function uncallable if the set grows to the point where clearing it consumes too much
+ * gas to fit in a block.
+ */
+ function _clear(Set storage set) private {
+ uint256 len = _length(set);
+ for (uint256 i = 0; i < len; ++i) {
+ delete set._positions[set._values[i]];
+ }
+ Arrays.unsafeSetLength(set._values, 0);
+ }
+
+ /**
+ * @dev Returns true if the value is in the set. O(1).
+ */
+ function _contains(Set storage set, bytes32 value) private view returns (bool) {
+ return set._positions[value] != 0;
+ }
+
+ /**
+ * @dev Returns the number of values on the set. O(1).
+ */
+ function _length(Set storage set) private view returns (uint256) {
+ return set._values.length;
+ }
+
+ /**
+ * @dev Returns the value stored at position `index` in the set. O(1).
+ *
+ * Note that there are no guarantees on the ordering of values inside the
+ * array, and it may change when more values are added or removed.
+ *
+ * Requirements:
+ *
+ * - `index` must be strictly less than {length}.
+ */
+ function _at(Set storage set, uint256 index) private view returns (bytes32) {
+ return set._values[index];
+ }
+
+ /**
+ * @dev Return the entire set in an array
+ *
+ * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ * this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ */
+ function _values(Set storage set) private view returns (bytes32[] memory) {
+ return set._values;
+ }
+
+ /**
+ * @dev Return a slice of the set in an array
+ *
+ * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ * this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ */
+ function _values(Set storage set, uint256 start, uint256 end) private view returns (bytes32[] memory) {
+ unchecked {
+ end = Math.min(end, _length(set));
+ start = Math.min(start, end);
+
+ uint256 len = end - start;
+ bytes32[] memory result = new bytes32[](len);
+ for (uint256 i = 0; i < len; ++i) {
+ result[i] = Arrays.unsafeAccess(set._values, start + i).value;
+ }
+ return result;
+ }
+ }
+
+ // Bytes32Set
+
+ struct Bytes32Set {
+ Set _inner;
+ }
+
+ /**
+ * @dev Add a value to a set. O(1).
+ *
+ * Returns true if the value was added to the set, that is if it was not
+ * already present.
+ */
+ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
+ return _add(set._inner, value);
+ }
+
+ /**
+ * @dev Removes a value from a set. O(1).
+ *
+ * Returns true if the value was removed from the set, that is if it was
+ * present.
+ */
+ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
+ return _remove(set._inner, value);
+ }
+
+ /**
+ * @dev Removes all the values from a set. O(n).
+ *
+ * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
+ * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
+ */
+ function clear(Bytes32Set storage set) internal {
+ _clear(set._inner);
+ }
+
+ /**
+ * @dev Returns true if the value is in the set. O(1).
+ */
+ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
+ return _contains(set._inner, value);
+ }
+
+ /**
+ * @dev Returns the number of values in the set. O(1).
+ */
+ function length(Bytes32Set storage set) internal view returns (uint256) {
+ return _length(set._inner);
+ }
+
+ /**
+ * @dev Returns the value stored at position `index` in the set. O(1).
+ *
+ * Note that there are no guarantees on the ordering of values inside the
+ * array, and it may change when more values are added or removed.
+ *
+ * Requirements:
+ *
+ * - `index` must be strictly less than {length}.
+ */
+ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
+ return _at(set._inner, index);
+ }
+
+ /**
+ * @dev Return the entire set in an array
+ *
+ * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ * this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ */
+ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
+ bytes32[] memory store = _values(set._inner);
+ bytes32[] memory result;
+
+ assembly ("memory-safe") {
+ result := store
+ }
+
+ return result;
+ }
+
+ /**
+ * @dev Return a slice of the set in an array
+ *
+ * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ * this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ */
+ function values(Bytes32Set storage set, uint256 start, uint256 end) internal view returns (bytes32[] memory) {
+ bytes32[] memory store = _values(set._inner, start, end);
+ bytes32[] memory result;
+
+ assembly ("memory-safe") {
+ result := store
+ }
+
+ return result;
+ }
+
+ // AddressSet
+
+ struct AddressSet {
+ Set _inner;
+ }
+
+ /**
+ * @dev Add a value to a set. O(1).
+ *
+ * Returns true if the value was added to the set, that is if it was not
+ * already present.
+ */
+ function add(AddressSet storage set, address value) internal returns (bool) {
+ return _add(set._inner, bytes32(uint256(uint160(value))));
+ }
+
+ /**
+ * @dev Removes a value from a set. O(1).
+ *
+ * Returns true if the value was removed from the set, that is if it was
+ * present.
+ */
+ function remove(AddressSet storage set, address value) internal returns (bool) {
+ return _remove(set._inner, bytes32(uint256(uint160(value))));
+ }
+
+ /**
+ * @dev Removes all the values from a set. O(n).
+ *
+ * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
+ * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
+ */
+ function clear(AddressSet storage set) internal {
+ _clear(set._inner);
+ }
+
+ /**
+ * @dev Returns true if the value is in the set. O(1).
+ */
+ function contains(AddressSet storage set, address value) internal view returns (bool) {
+ return _contains(set._inner, bytes32(uint256(uint160(value))));
+ }
+
+ /**
+ * @dev Returns the number of values in the set. O(1).
+ */
+ function length(AddressSet storage set) internal view returns (uint256) {
+ return _length(set._inner);
+ }
+
+ /**
+ * @dev Returns the value stored at position `index` in the set. O(1).
+ *
+ * Note that there are no guarantees on the ordering of values inside the
+ * array, and it may change when more values are added or removed.
+ *
+ * Requirements:
+ *
+ * - `index` must be strictly less than {length}.
+ */
+ function at(AddressSet storage set, uint256 index) internal view returns (address) {
+ return address(uint160(uint256(_at(set._inner, index))));
+ }
+
+ /**
+ * @dev Return the entire set in an array
+ *
+ * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ * this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ */
+ function values(AddressSet storage set) internal view returns (address[] memory) {
+ bytes32[] memory store = _values(set._inner);
+ address[] memory result;
+
+ assembly ("memory-safe") {
+ result := store
+ }
+
+ return result;
+ }
+
+ /**
+ * @dev Return a slice of the set in an array
+ *
+ * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ * this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ */
+ function values(AddressSet storage set, uint256 start, uint256 end) internal view returns (address[] memory) {
+ bytes32[] memory store = _values(set._inner, start, end);
+ address[] memory result;
+
+ assembly ("memory-safe") {
+ result := store
+ }
+
+ return result;
+ }
+
+ // UintSet
+
+ struct UintSet {
+ Set _inner;
+ }
+
+ /**
+ * @dev Add a value to a set. O(1).
+ *
+ * Returns true if the value was added to the set, that is if it was not
+ * already present.
+ */
+ function add(UintSet storage set, uint256 value) internal returns (bool) {
+ return _add(set._inner, bytes32(value));
+ }
+
+ /**
+ * @dev Removes a value from a set. O(1).
+ *
+ * Returns true if the value was removed from the set, that is if it was
+ * present.
+ */
+ function remove(UintSet storage set, uint256 value) internal returns (bool) {
+ return _remove(set._inner, bytes32(value));
+ }
+
+ /**
+ * @dev Removes all the values from a set. O(n).
+ *
+ * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
+ * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
+ */
+ function clear(UintSet storage set) internal {
+ _clear(set._inner);
+ }
+
+ /**
+ * @dev Returns true if the value is in the set. O(1).
+ */
+ function contains(UintSet storage set, uint256 value) internal view returns (bool) {
+ return _contains(set._inner, bytes32(value));
+ }
+
+ /**
+ * @dev Returns the number of values in the set. O(1).
+ */
+ function length(UintSet storage set) internal view returns (uint256) {
+ return _length(set._inner);
+ }
+
+ /**
+ * @dev Returns the value stored at position `index` in the set. O(1).
+ *
+ * Note that there are no guarantees on the ordering of values inside the
+ * array, and it may change when more values are added or removed.
+ *
+ * Requirements:
+ *
+ * - `index` must be strictly less than {length}.
+ */
+ function at(UintSet storage set, uint256 index) internal view returns (uint256) {
+ return uint256(_at(set._inner, index));
+ }
+
+ /**
+ * @dev Return the entire set in an array
+ *
+ * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ * this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ */
+ function values(UintSet storage set) internal view returns (uint256[] memory) {
+ bytes32[] memory store = _values(set._inner);
+ uint256[] memory result;
+
+ assembly ("memory-safe") {
+ result := store
+ }
+
+ return result;
+ }
+
+ /**
+ * @dev Return a slice of the set in an array
+ *
+ * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ * this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ */
+ function values(UintSet storage set, uint256 start, uint256 end) internal view returns (uint256[] memory) {
+ bytes32[] memory store = _values(set._inner, start, end);
+ uint256[] memory result;
+
+ assembly ("memory-safe") {
+ result := store
+ }
+
+ return result;
+ }
+
+ struct StringSet {
+ // Storage of set values
+ string[] _values;
+ // Position is the index of the value in the `values` array plus 1.
+ // Position 0 is used to mean a value is not in the set.
+ mapping(string value => uint256) _positions;
+ }
+
+ /**
+ * @dev Add a value to a set. O(1).
+ *
+ * Returns true if the value was added to the set, that is if it was not
+ * already present.
+ */
+ function add(StringSet storage set, string memory value) internal returns (bool) {
+ if (!contains(set, value)) {
+ set._values.push(value);
+ // The value is stored at length-1, but we add 1 to all indexes
+ // and use 0 as a sentinel value
+ set._positions[value] = set._values.length;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @dev Removes a value from a set. O(1).
+ *
+ * Returns true if the value was removed from the set, that is if it was
+ * present.
+ */
+ function remove(StringSet storage set, string memory value) internal returns (bool) {
+ // We cache the value's position to prevent multiple reads from the same storage slot
+ uint256 position = set._positions[value];
+
+ if (position != 0) {
+ // Equivalent to contains(set, value)
+ // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
+ // the array, and then remove the last element (sometimes called as 'swap and pop').
+ // This modifies the order of the array, as noted in {at}.
+
+ uint256 valueIndex = position - 1;
+ uint256 lastIndex = set._values.length - 1;
+
+ if (valueIndex != lastIndex) {
+ string memory lastValue = set._values[lastIndex];
+
+ // Move the lastValue to the index where the value to delete is
+ set._values[valueIndex] = lastValue;
+ // Update the tracked position of the lastValue (that was just moved)
+ set._positions[lastValue] = position;
+ }
+
+ // Delete the slot where the moved value was stored
+ set._values.pop();
+
+ // Delete the tracked position for the deleted slot
+ delete set._positions[value];
+
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @dev Removes all the values from a set. O(n).
+ *
+ * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
+ * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
+ */
+ function clear(StringSet storage set) internal {
+ uint256 len = length(set);
+ for (uint256 i = 0; i < len; ++i) {
+ delete set._positions[set._values[i]];
+ }
+ Arrays.unsafeSetLength(set._values, 0);
+ }
+
+ /**
+ * @dev Returns true if the value is in the set. O(1).
+ */
+ function contains(StringSet storage set, string memory value) internal view returns (bool) {
+ return set._positions[value] != 0;
+ }
+
+ /**
+ * @dev Returns the number of values on the set. O(1).
+ */
+ function length(StringSet storage set) internal view returns (uint256) {
+ return set._values.length;
+ }
+
+ /**
+ * @dev Returns the value stored at position `index` in the set. O(1).
+ *
+ * Note that there are no guarantees on the ordering of values inside the
+ * array, and it may change when more values are added or removed.
+ *
+ * Requirements:
+ *
+ * - `index` must be strictly less than {length}.
+ */
+ function at(StringSet storage set, uint256 index) internal view returns (string memory) {
+ return set._values[index];
+ }
+
+ /**
+ * @dev Return the entire set in an array
+ *
+ * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ * this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ */
+ function values(StringSet storage set) internal view returns (string[] memory) {
+ return set._values;
+ }
+
+ /**
+ * @dev Return a slice of the set in an array
+ *
+ * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ * this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ */
+ function values(StringSet storage set, uint256 start, uint256 end) internal view returns (string[] memory) {
+ unchecked {
+ end = Math.min(end, length(set));
+ start = Math.min(start, end);
+
+ uint256 len = end - start;
+ string[] memory result = new string[](len);
+ for (uint256 i = 0; i < len; ++i) {
+ result[i] = Arrays.unsafeAccess(set._values, start + i).value;
+ }
+ return result;
+ }
+ }
+
+ struct BytesSet {
+ // Storage of set values
+ bytes[] _values;
+ // Position is the index of the value in the `values` array plus 1.
+ // Position 0 is used to mean a value is not in the set.
+ mapping(bytes value => uint256) _positions;
+ }
+
+ /**
+ * @dev Add a value to a set. O(1).
+ *
+ * Returns true if the value was added to the set, that is if it was not
+ * already present.
+ */
+ function add(BytesSet storage set, bytes memory value) internal returns (bool) {
+ if (!contains(set, value)) {
+ set._values.push(value);
+ // The value is stored at length-1, but we add 1 to all indexes
+ // and use 0 as a sentinel value
+ set._positions[value] = set._values.length;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @dev Removes a value from a set. O(1).
+ *
+ * Returns true if the value was removed from the set, that is if it was
+ * present.
+ */
+ function remove(BytesSet storage set, bytes memory value) internal returns (bool) {
+ // We cache the value's position to prevent multiple reads from the same storage slot
+ uint256 position = set._positions[value];
+
+ if (position != 0) {
+ // Equivalent to contains(set, value)
+ // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
+ // the array, and then remove the last element (sometimes called as 'swap and pop').
+ // This modifies the order of the array, as noted in {at}.
+
+ uint256 valueIndex = position - 1;
+ uint256 lastIndex = set._values.length - 1;
+
+ if (valueIndex != lastIndex) {
+ bytes memory lastValue = set._values[lastIndex];
+
+ // Move the lastValue to the index where the value to delete is
+ set._values[valueIndex] = lastValue;
+ // Update the tracked position of the lastValue (that was just moved)
+ set._positions[lastValue] = position;
+ }
+
+ // Delete the slot where the moved value was stored
+ set._values.pop();
+
+ // Delete the tracked position for the deleted slot
+ delete set._positions[value];
+
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @dev Removes all the values from a set. O(n).
+ *
+ * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
+ * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
+ */
+ function clear(BytesSet storage set) internal {
+ uint256 len = length(set);
+ for (uint256 i = 0; i < len; ++i) {
+ delete set._positions[set._values[i]];
+ }
+ Arrays.unsafeSetLength(set._values, 0);
+ }
+
+ /**
+ * @dev Returns true if the value is in the set. O(1).
+ */
+ function contains(BytesSet storage set, bytes memory value) internal view returns (bool) {
+ return set._positions[value] != 0;
+ }
+
+ /**
+ * @dev Returns the number of values on the set. O(1).
+ */
+ function length(BytesSet storage set) internal view returns (uint256) {
+ return set._values.length;
+ }
+
+ /**
+ * @dev Returns the value stored at position `index` in the set. O(1).
+ *
+ * Note that there are no guarantees on the ordering of values inside the
+ * array, and it may change when more values are added or removed.
+ *
+ * Requirements:
+ *
+ * - `index` must be strictly less than {length}.
+ */
+ function at(BytesSet storage set, uint256 index) internal view returns (bytes memory) {
+ return set._values[index];
+ }
+
+ /**
+ * @dev Return the entire set in an array
+ *
+ * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ * this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ */
+ function values(BytesSet storage set) internal view returns (bytes[] memory) {
+ return set._values;
+ }
+
+ /**
+ * @dev Return a slice of the set in an array
+ *
+ * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ * this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ */
+ function values(BytesSet storage set, uint256 start, uint256 end) internal view returns (bytes[] memory) {
+ unchecked {
+ end = Math.min(end, length(set));
+ start = Math.min(start, end);
+
+ uint256 len = end - start;
+ bytes[] memory result = new bytes[](len);
+ for (uint256 i = 0; i < len; ++i) {
+ result[i] = Arrays.unsafeAccess(set._values, start + i).value;
+ }
+ return result;
+ }
+ }
+}
+
+// src/modules/ERC3643ComplianceModule.sol
+
+/* ==== OpenZeppelin === */
+
+/* ==== Interface and other library === */
+
+abstract contract ERC3643ComplianceModule is IERC3643Compliance, AccessControl {
+ /* ==== Type declaration === */
+ using EnumerableSet for EnumerableSet.AddressSet;
+ /* ==== State Variables === */
+ // Token binding tracking
+ EnumerableSet.AddressSet private _boundTokens;
+ // Access Control
+ bytes32 public constant COMPLIANCE_MANAGER_ROLE = keccak256("COMPLIANCE_MANAGER_ROLE");
+
+ /* ==== Errors === */
+ error RuleEngine_ERC3643Compliance_InvalidTokenAddress();
+ error RuleEngine_ERC3643Compliance_TokenAlreadyBound();
+ error RuleEngine_ERC3643Compliance_TokenNotBound();
+ error RuleEngine_ERC3643Compliance_UnauthorizedCaller();
+ error RuleEngine_ERC3643Compliance_OperationNotSuccessful();
+
+ /* ==== Modifier === */
+ modifier onlyBoundToken() {
+ if (!_boundTokens.contains(_msgSender())) {
+ revert RuleEngine_ERC3643Compliance_UnauthorizedCaller();
+ }
+ _;
+ }
+
+ /*//////////////////////////////////////////////////////////////
+ PUBLIC/public FUNCTIONS
+ //////////////////////////////////////////////////////////////*/
+
+ /* ============ State functions ============ */
+ /// @inheritdoc IERC3643Compliance
+ function bindToken(address token) public override virtual onlyRole(COMPLIANCE_MANAGER_ROLE) {
+ _bindToken(token);
+ }
+
+ /// @inheritdoc IERC3643Compliance
+ function unbindToken(address token) public override virtual onlyRole(COMPLIANCE_MANAGER_ROLE) {
+ _unbindToken(token);
+ }
+
+ /// @inheritdoc IERC3643Compliance
+ function isTokenBound(address token) public view virtual override returns (bool) {
+ return _boundTokens.contains(token);
+ }
+
+ /// @inheritdoc IERC3643Compliance
+ function getTokenBound() public view virtual override returns (address) {
+ if(_boundTokens.length() > 0){
+ // Note that there are no guarantees on the ordering of values inside the array,
+ // and it may change when more values are added or removed.
+ return _boundTokens.at(0);
+ } else {
+ return address(0);
+ }
+ }
+
+ /// @inheritdoc IERC3643Compliance
+ function getTokenBounds() public view override returns (address[] memory) {
+ return _boundTokens.values();
+ }
+
+ /*//////////////////////////////////////////////////////////////
+ INTERNAL/PRIVATE FUNCTIONS
+ //////////////////////////////////////////////////////////////*/
+
+ function _unbindToken(address token) internal {
+ require (_boundTokens.contains(token), RuleEngine_ERC3643Compliance_TokenNotBound());
+ // Should never revert because we check if the token address is already set before
+ require(_boundTokens.remove(token), RuleEngine_ERC3643Compliance_OperationNotSuccessful());
+
+ emit TokenUnbound(token);
+ }
+ function _bindToken(address token) internal{
+ require(token != address(0), RuleEngine_ERC3643Compliance_InvalidTokenAddress());
+ require(!_boundTokens.contains(token), RuleEngine_ERC3643Compliance_TokenAlreadyBound());
+ // Should never revert because we check if the token address is already set before
+ require(_boundTokens.add(token), RuleEngine_ERC3643Compliance_OperationNotSuccessful());
+ emit TokenBound(token);
+ }
+}
+
+// src/modules/RulesManagementModule.sol
+
+/* ==== OpenZeppelin === */
+
+/* ==== Interface and other library === */
+
+/**
+ * @title RuleEngine - part
+ */
+abstract contract RulesManagementModule is
+ AccessControl,
+ RulesManagementModuleInvariantStorage,
+ IRulesManagementModule
+{
+ /* ==== Type declaration === */
+ using EnumerableSet for EnumerableSet.AddressSet;
+
+ /* ==== State Variables === */
+ /// @dev Array of rules
+ EnumerableSet.AddressSet internal _rules;
+
+ /*//////////////////////////////////////////////////////////////
+ PUBLIC/EXTERNAL FUNCTIONS
+ //////////////////////////////////////////////////////////////*/
+
+ /* ============ State functions ============ */
+
+ /**
+ * @inheritdoc IRulesManagementModule
+ */
+ function setRules(
+ IRule[] calldata rules_
+ ) public virtual override(IRulesManagementModule) onlyRole(RULES_MANAGEMENT_ROLE) {
+ if (rules_.length == 0) {
+ revert RuleEngine_RulesManagementModule_ArrayIsEmpty();
+ }
+ if (_rules.length() > 0) {
+ _clearRules();
+ }
+ for(uint256 i = 0; i < rules_.length; ++i){
+ _checkRule(address(rules_[i]));
+ // Should never revert because we check the presence of the rule before
+ require(_rules.add(address(rules_[i])), RuleEngine_RulesManagementModule_OperationNotSuccessful());
+ emit AddRule(rules_[i]);
+ }
+ }
+
+ /**
+ * @inheritdoc IRulesManagementModule
+ */
+ function clearRules() public virtual override(IRulesManagementModule) onlyRole(RULES_MANAGEMENT_ROLE) {
+ _clearRules();
+ }
+
+ /**
+ * @inheritdoc IRulesManagementModule
+ */
+ function addRule(
+ IRule rule_
+ ) public virtual override(IRulesManagementModule) onlyRole(RULES_MANAGEMENT_ROLE) {
+ _checkRule(address(rule_));
+ require(_rules.add(address(rule_)), RuleEngine_RulesManagementModule_OperationNotSuccessful());
+ emit AddRule(rule_);
+ }
+
+ /**
+ * @inheritdoc IRulesManagementModule
+ */
+ function removeRule(
+ IRule rule_
+ ) public virtual override(IRulesManagementModule) onlyRole(RULES_MANAGEMENT_ROLE) {
+ require(_rules.contains(address(rule_)), RuleEngine_RulesManagementModule_RuleDoNotMatch());
+ _removeRule(rule_);
+ }
+
+ /* ============ View functions ============ */
+
+ /**
+ * @inheritdoc IRulesManagementModule
+ */
+ function rulesCount() public view virtual override(IRulesManagementModule) returns (uint256) {
+ return _rules.length();
+ }
+
+ /**
+ * @inheritdoc IRulesManagementModule
+ */
+ function containsRule(IRule rule_) public view virtual override(IRulesManagementModule) returns (bool){
+ return _rules.contains(address(rule_));
+ }
+
+ /**
+ * @inheritdoc IRulesManagementModule
+ */
+ function rule(
+ uint256 ruleId
+ ) public view virtual override(IRulesManagementModule) returns (address) {
+ if(ruleId < _rules.length()){
+ // Note that there are no guarantees on the ordering of values inside the array,
+ // and it may change when more values are added or removed.
+ return _rules.at(ruleId);
+ } else {
+ return address(0);
+ }
+ }
+
+ /**
+ * @inheritdoc IRulesManagementModule
+ */
+ function rules()
+ public
+ view
+ virtual
+ override(IRulesManagementModule)
+ returns (address[] memory)
+ {
+ return _rules.values();
+ }
+
+ /*//////////////////////////////////////////////////////////////
+ INTERNAL/PRIVATE FUNCTIONS
+ //////////////////////////////////////////////////////////////*/
+ /**
+ * @notice Clear all the rules of the array of rules
+ *
+ */
+ function _clearRules() internal virtual {
+ emit ClearRules();
+ _rules.clear();
+ }
+
+ /**
+ * @notice Remove a rule from the array of rules
+ * Revert if the rule found at the specified index does not match the rule in argument
+ * @param rule_ address of the target rule
+ *
+ *
+ */
+ function _removeRule(IRule rule_) internal virtual {
+ // Should never revert because we check the presence of the rule before
+ require(_rules.remove(address(rule_)), RuleEngine_RulesManagementModule_OperationNotSuccessful());
+ emit RemoveRule(rule_);
+ }
+
+ /**
+ * @dev check if a rule is valid, revert otherwise
+ */
+ function _checkRule(address rule_) internal view{
+ if (rule_ == address(0x0)) {
+ revert RuleEngine_RulesManagementModule_RuleAddressZeroNotAllowed();
+ }
+ if (_rules.contains(rule_)) {
+ revert RuleEngine_RulesManagementModule_RuleAlreadyExists();
+ }
+ }
+
+ /* ============ Transferred functions ============ */
+
+ /**
+ * @notice Go through all the rule to know if a restriction exists on the transfer
+ * @param from the origin address
+ * @param to the destination address
+ * @param value to transfer
+ **/
+ function _transferred(
+ address from,
+ address to,
+ uint256 value
+ ) internal virtual{
+ uint256 rulesLength = _rules.length();
+ for (uint256 i = 0; i < rulesLength; ++i) {
+ IRule(_rules.at(i)).transferred(
+ from,
+ to,
+ value
+ );
+ }
+ }
+
+ /**
+ * @notice Go through all the rule to know if a restriction exists on the transfer
+ * @param spender the spender address (transferFrom)
+ * @param from the origin address
+ * @param to the destination address
+ * @param value to transfer
+ **/
+ function _transferred(
+ address spender,
+ address from,
+ address to,
+ uint256 value
+ ) internal virtual{
+ uint256 rulesLength = _rules.length();
+ for (uint256 i = 0; i < rulesLength; ++i) {
+ IRule(_rules.at(i)).transferred(
+ spender,
+ from,
+ to,
+ value
+ );
+ }
+ }
+}
+
+// src/RuleEngineBase.sol
+
+/* ==== OpenZeppelin === */
+
+/* ==== CMTAT === */
+
+/* ==== Modules === */
+
+/* ==== Interface and other library === */
+
+/**
+ * @title Implementation of a ruleEngine as defined by the CMTAT
+ */
+abstract contract RuleEngineBase is
+ VersionModule,
+ RulesManagementModule,
+ ERC3643ComplianceModule,
+ RuleEngineInvariantStorage,
+ IRuleEngine
+{
+ /* ============ State functions ============ */
+ /*
+ * @inheritdoc IRuleEngine
+ */
+ function transferred(
+ address spender,
+ address from,
+ address to,
+ uint256 value
+ ) public virtual override(IRuleEngine) onlyBoundToken {
+ // Apply on RuleEngine
+ RulesManagementModule._transferred(spender, from, to, value);
+ }
+
+ /**
+ * @inheritdoc IERC3643IComplianceContract
+ */
+ function transferred(
+ address from,
+ address to,
+ uint256 value
+ ) public virtual override(IERC3643IComplianceContract) onlyBoundToken {
+ _transferred(from, to, value);
+ }
+
+ /// @inheritdoc IERC3643Compliance
+ function created(address to, uint256 value) public virtual override(IERC3643Compliance) onlyBoundToken{
+ _transferred(address(0), to, value);
+ }
+
+ /// @inheritdoc IERC3643Compliance
+ function destroyed(address from, uint256 value) public virtual override(IERC3643Compliance) onlyBoundToken {
+ _transferred(from, address(0), value);
+ }
+
+ /* ============ View functions ============ */
+ /**
+ * @notice Go through all the rule to know if a restriction exists on the transfer
+ * @param from the origin address
+ * @param to the destination address
+ * @param value to transfer
+ * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK (0) if the transfer is valid
+ **/
+ function detectTransferRestriction(
+ address from,
+ address to,
+ uint256 value
+ ) public view virtual override returns (uint8) {
+ uint256 rulesLength = rulesCount();
+ for (uint256 i = 0; i < rulesLength; ++i) {
+ uint8 restriction = IRule(rule(i))
+ .detectTransferRestriction(from, to, value);
+ if (restriction > 0) {
+ return restriction;
+ }
+ }
+ return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ }
+
+ /**
+ * @inheritdoc IERC1404Extend
+ */
+ function detectTransferRestrictionFrom(
+ address spender,
+ address from,
+ address to,
+ uint256 value
+ ) public view virtual override(IERC1404Extend) returns (uint8) {
+ uint256 rulesLength = rulesCount();
+ for (uint256 i = 0; i < rulesLength; ++i) {
+ uint8 restriction = IRule(rule(i))
+ .detectTransferRestrictionFrom(spender,from, to, value);
+ if (restriction > 0) {
+ return restriction;
+ }
+ }
+
+ return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ }
+
+ /**
+ * @inheritdoc IERC1404
+ */
+ function messageForTransferRestriction(
+ uint8 restrictionCode
+ ) public virtual view override(IERC1404) returns (string memory) {
+ //
+ uint256 rulesLength = rulesCount();
+ for (uint256 i = 0; i < rulesLength; ++i) {
+ if (
+ IRule(rule(i))
+ .canReturnTransferRestrictionCode(restrictionCode)
+ ) {
+ return
+ IRule(rule(i))
+ .messageForTransferRestriction(restrictionCode);
+ }
+ }
+ return "Unknown restriction code";
+ }
+
+ /**
+ * @inheritdoc IERC3643ComplianceRead
+ */
+ function canTransfer(
+ address from,
+ address to,
+ uint256 value
+ ) public virtual view override(IERC3643ComplianceRead) returns (bool) {
+ return
+ detectTransferRestriction(from, to, value) ==
+ uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ }
+
+ /**
+ * @inheritdoc IERC7551Compliance
+ */
+ function canTransferFrom(
+ address spender,
+ address from,
+ address to,
+ uint256 value
+ ) public virtual view override(IERC7551Compliance) returns (bool) {
+ return
+ detectTransferRestrictionFrom(spender, from, to, value) ==
+ uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ }
+
+ /* ============ ACCESS CONTROL ============ */
+ /**
+ * @notice Returns `true` if `account` has been granted `role`.
+ * @dev The Default Admin has all roles
+ */
+ function hasRole(
+ bytes32 role,
+ address account
+ ) public view virtual override(AccessControl) returns (bool) {
+ if (AccessControl.hasRole(DEFAULT_ADMIN_ROLE, account)) {
+ return true;
+ } else {
+ return AccessControl.hasRole(role, account);
+ }
+ }
+}
+
+// src/RuleEngine.sol
+
+/* ==== OpenZeppelin === */
+
+/* ==== Modules === */
+
+/* ==== Base contract === */
+
+/**
+ * @title Implementation of a ruleEngine as defined by the CMTAT
+ */
+contract RuleEngine is
+ ERC2771ModuleStandalone,
+ RuleEngineBase
+{
+ /**
+ * @param admin Address of the contract (Access Control)
+ * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ */
+ constructor(
+ address admin,
+ address forwarderIrrevocable,
+ address tokenContract
+ ) ERC2771ModuleStandalone(forwarderIrrevocable) {
+ if (admin == address(0)) {
+ revert RuleEngine_AdminWithAddressZeroNotAllowed();
+ }
+ if (tokenContract != address(0)) {
+ _bindToken(tokenContract);
+ }
+ _grantRole(DEFAULT_ADMIN_ROLE, admin);
+ }
+
+ /*//////////////////////////////////////////////////////////////
+ ERC-2771
+ //////////////////////////////////////////////////////////////*/
+
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
+ function _msgSender()
+ internal
+ view
+ virtual
+ override(ERC2771Context, Context)
+ returns (address sender)
+ {
+ return ERC2771Context._msgSender();
+ }
+
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
+ function _msgData()
+ internal
+ view
+ virtual
+ override(ERC2771Context, Context)
+ returns (bytes calldata)
+ {
+ return ERC2771Context._msgData();
+ }
+
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
+ function _contextSuffixLength()
+ internal
+ view
+ virtual
+ override(ERC2771Context, Context)
+ returns (uint256)
+ {
+ return ERC2771Context._contextSuffixLength();
+ }
+}
+
diff --git a/doc/compilation/hardhat/src/RuleEngine.sol/RuleEngine.dbg.json b/doc/compilation/hardhat/src/RuleEngine.sol/RuleEngine.dbg.json
new file mode 100644
index 0000000..4d68568
--- /dev/null
+++ b/doc/compilation/hardhat/src/RuleEngine.sol/RuleEngine.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/RuleEngine.sol/RuleEngine.json b/doc/compilation/hardhat/src/RuleEngine.sol/RuleEngine.json
new file mode 100644
index 0000000..884035d
--- /dev/null
+++ b/doc/compilation/hardhat/src/RuleEngine.sol/RuleEngine.json
@@ -0,0 +1,854 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleEngine",
+ "sourceName": "src/RuleEngine.sol",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "admin",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "forwarderIrrevocable",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "tokenContract",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "inputs": [],
+ "name": "AccessControlBadConfirmation",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "neededRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AccessControlUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_AdminWithAddressZeroNotAllowed",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_InvalidTokenAddress",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_OperationNotSuccessful",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_TokenAlreadyBound",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_TokenNotBound",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_UnauthorizedCaller",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_ArrayIsEmpty",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_OperationNotSuccessful",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_RuleAddressZeroNotAllowed",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_RuleAlreadyExists",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_RuleDoNotMatch",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "contract IRule",
+ "name": "rule",
+ "type": "address"
+ }
+ ],
+ "name": "AddRule",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "ClearRules",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "contract IRule",
+ "name": "rule",
+ "type": "address"
+ }
+ ],
+ "name": "RemoveRule",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "previousAdminRole",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "newAdminRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RoleAdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleGranted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleRevoked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "TokenBound",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "TokenUnbound",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "COMPLIANCE_MANAGER_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "DEFAULT_ADMIN_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "RULES_MANAGEMENT_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule",
+ "name": "rule_",
+ "type": "address"
+ }
+ ],
+ "name": "addRule",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "bindToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "clearRules",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule",
+ "name": "rule_",
+ "type": "address"
+ }
+ ],
+ "name": "containsRule",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "created",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "destroyed",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestrictionFrom",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getRoleAdmin",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTokenBound",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTokenBounds",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "grantRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "hasRole",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "isTokenBound",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "forwarder",
+ "type": "address"
+ }
+ ],
+ "name": "isTrustedForwarder",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint8",
+ "name": "restrictionCode",
+ "type": "uint8"
+ }
+ ],
+ "name": "messageForTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule",
+ "name": "rule_",
+ "type": "address"
+ }
+ ],
+ "name": "removeRule",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "callerConfirmation",
+ "type": "address"
+ }
+ ],
+ "name": "renounceRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "revokeRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "ruleId",
+ "type": "uint256"
+ }
+ ],
+ "name": "rule",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "rules",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "rulesCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule[]",
+ "name": "rules_",
+ "type": "address[]"
+ }
+ ],
+ "name": "setRules",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes4",
+ "name": "interfaceId",
+ "type": "bytes4"
+ }
+ ],
+ "name": "supportsInterface",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "trustedForwarder",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "unbindToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "version_",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x60a060405234801561000f575f5ffd5b5060405161316338038061316383398181016040528101906100319190610641565b81808073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036100ce576040517f21c89ccc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610111576101108161012c60201b60201c565b5b6101235f5f1b8461026060201b60201c565b5050505061079a565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610191576040517fdc418b8000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101a581600361035560201b90919060201c565b156101dc576040517ff423354700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101f081600361038860201b90919060201c565b610226576040517f369bb9e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f2de35142b19ed5a07796cf30791959c592018f70b1d2d7c460eef8ffe713692b8160405161025591906106a0565b60405180910390a150565b5f61027183836103bb60201b60201c565b61034b5760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506102e86103f560201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001905061034f565b5f90505b92915050565b5f610380835f018373ffffffffffffffffffffffffffffffffffffffff165f1b61040960201b60201c565b905092915050565b5f6103b3835f018373ffffffffffffffffffffffffffffffffffffffff165f1b61042960201b60201c565b905092915050565b5f6103ce5f5f1b8361049660201b60201c565b156103dc57600190506103ef565b6103ec838361049660201b60201c565b90505b92915050565b5f6104046104f960201b60201c565b905090565b5f5f836001015f8481526020019081526020015f20541415905092915050565b5f61043a838361040960201b60201c565b61048c57825f0182908060018154018082558091505060019003905f5260205f20015f9091909190915055825f0180549050836001015f8481526020019081526020015f208190555060019050610490565b5f90505b92915050565b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f5f36905090505f61051061057360201b60201c565b905080821015801561052d575061052c3361058760201b60201c565b5b1561055d575f36828403908092610546939291906106c1565b90610551919061073c565b60601c92505050610570565b61056b6105cb60201b60201c565b925050505b90565b5f6105826105d260201b60201c565b905090565b5f6105966105da60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b5f33905090565b5f6014905090565b5f608051905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610610826105e7565b9050919050565b61062081610606565b811461062a575f5ffd5b50565b5f8151905061063b81610617565b92915050565b5f5f5f60608486031215610658576106576105e3565b5b5f6106658682870161062d565b93505060206106768682870161062d565b92505060406106878682870161062d565b9150509250925092565b61069a81610606565b82525050565b5f6020820190506106b35f830184610691565b92915050565b5f5ffd5b5f5ffd5b5f5f858511156106d4576106d36106b9565b5b838611156106e5576106e46106bd565b5b6001850283019150848603905094509492505050565b5f82905092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b5f82821b905092915050565b5f61074783836106fb565b826107528135610705565b925060148210156107925761078d7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802610730565b831692505b505092915050565b6080516129b16107b25f395f610a4701526129b15ff3fe608060405234801561000f575f5ffd5b5060043610610204575f3560e01c80638baf29b411610118578063bc13eacc116100ab578063db18af6c1161007a578063db18af6c146105fa578063df21950f1461062a578063e3c4602c14610646578063e46638e614610662578063e54621d21461069257610204565b8063bc13eacc14610560578063d32c7bb51461057e578063d4ce1415146105ae578063d547741f146105de57610204565b80639b11c115116100e75780639b11c115146104fe578063a217fddf1461051c578063b043572e1461053a578063b27aef3a1461054457610204565b80638baf29b4146104665780638d2ea7721461048257806391d148541461049e578063993e8b95146104ce57610204565b806352f6747a1161019b5780635f8dead31161016a5780635f8dead3146103ae5780636a3edf28146103ca5780637157797f146103e85780637da0a877146104185780637f4ab1dd1461043657610204565b806352f6747a1461031257806354e4b9451461033057806354fd4d5014610360578063572b6c051461037e57610204565b806336568abe116101d757806336568abe146102a25780633e5af4ca146102be5780633ff5aa02146102da57806340db3b50146102f657610204565b806301ffc9a71461020857806303c26bcd14610238578063248a9ca3146102565780632f2ff15d14610286575b5f5ffd5b610222600480360381019061021d9190611ed6565b6106b0565b60405161022f9190611f1b565b60405180910390f35b610240610729565b60405161024d9190611f4c565b60405180910390f35b610270600480360381019061026b9190611f8f565b61074d565b60405161027d9190611f4c565b60405180910390f35b6102a0600480360381019061029b9190612014565b610769565b005b6102bc60048036038101906102b79190612014565b61078b565b005b6102d860048036038101906102d39190612085565b610806565b005b6102f460048036038101906102ef91906120e9565b610869565b005b610310600480360381019061030b91906120e9565b6108a0565b005b61031a6108d7565b60405161032791906121cb565b60405180910390f35b61034a60048036038101906103459190612226565b6108e8565b6040516103579190611f1b565b60405180910390f35b610368610904565b60405161037591906122c1565b60405180910390f35b610398600480360381019061039391906120e9565b610941565b6040516103a59190611f1b565b60405180910390f35b6103c860048036038101906103c391906122e1565b61097f565b005b6103d26109df565b6040516103df919061232e565b60405180910390f35b61040260048036038101906103fd9190612085565b610a13565b60405161040f9190611f1b565b60405180910390f35b610420610a44565b60405161042d919061232e565b60405180910390f35b610450600480360381019061044b919061237d565b610a6b565b60405161045d91906122c1565b60405180910390f35b610480600480360381019061047b91906123a8565b610be1565b005b61049c600480360381019061049791906122e1565b610c42565b005b6104b860048036038101906104b39190612014565b610ca2565b6040516104c59190611f1b565b60405180910390f35b6104e860048036038101906104e391906120e9565b610cd0565b6040516104f59190611f1b565b60405180910390f35b610506610cec565b6040516105139190611f4c565b60405180910390f35b610524610d10565b6040516105319190611f4c565b60405180910390f35b610542610d16565b005b61055e60048036038101906105599190612459565b610d4b565b005b610568610ef7565b60405161057591906124b3565b60405180910390f35b61059860048036038101906105939190612085565b610f07565b6040516105a591906124db565b60405180910390f35b6105c860048036038101906105c391906123a8565b610feb565b6040516105d591906124db565b60405180910390f35b6105f860048036038101906105f39190612014565b6110cc565b005b610614600480360381019061060f91906124f4565b6110ee565b604051610621919061232e565b60405180910390f35b610644600480360381019061063f9190612226565b611124565b005b610660600480360381019061065b9190612226565b6111a5565b005b61067c600480360381019061067791906123a8565b611269565b6040516106899190611f1b565b60405180910390f35b61069a611298565b6040516106a791906121cb565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806107225750610721826112a9565b5b9050919050565b7fe5c50d0927e06141e032cb9a67e1d7092dc85c0b0825191f7e1cede60002856881565b5f5f5f8381526020019081526020015f20600101549050919050565b6107728261074d565b61077b81611312565b6107858383611326565b50505050565b61079361140f565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146107f7576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610801828261141d565b505050565b61082161081161140f565b600361150690919063ffffffff16565b610857576040517fe39b3c8f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61086384848484611533565b50505050565b7fe5c50d0927e06141e032cb9a67e1d7092dc85c0b0825191f7e1cede60002856861089381611312565b61089c826115df565b5050565b7fe5c50d0927e06141e032cb9a67e1d7092dc85c0b0825191f7e1cede6000285686108ca81611312565b6108d382611713565b5050565b60606108e360016117e1565b905090565b5f6108fd82600161150690919063ffffffff16565b9050919050565b60606040518060400160405280600581526020017f332e302e30000000000000000000000000000000000000000000000000000000815250905090565b5f61094a610a44565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b61099a61098a61140f565b600361150690919063ffffffff16565b6109d0576040517fe39b3c8f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109db5f8383611800565b5050565b5f5f6109eb60036118a9565b1115610a0c57610a055f60036118bc90919063ffffffff16565b9050610a10565b5f90505b90565b5f5f6006811115610a2757610a2661251f565b5b60ff16610a3686868686610f07565b60ff16149050949350505050565b5f7f0000000000000000000000000000000000000000000000000000000000000000905090565b60605f610a76610ef7565b90505f5f90505b81811015610ba157610a8e816110ee565b73ffffffffffffffffffffffffffffffffffffffff16637d045df6856040518263ffffffff1660e01b8152600401610ac691906124db565b602060405180830381865afa158015610ae1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b059190612576565b15610b9657610b13816110ee565b73ffffffffffffffffffffffffffffffffffffffff16637f4ab1dd856040518263ffffffff1660e01b8152600401610b4b91906124db565b5f60405180830381865afa158015610b65573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610b8d91906126bb565b92505050610bdc565b806001019050610a7d565b506040518060400160405280601881526020017f556e6b6e6f776e207265737472696374696f6e20636f646500000000000000008152509150505b919050565b610bfc610bec61140f565b600361150690919063ffffffff16565b610c32576040517fe39b3c8f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c3d838383611800565b505050565b610c5d610c4d61140f565b600361150690919063ffffffff16565b610c93576040517fe39b3c8f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c9e825f83611800565b5050565b5f610caf5f5f1b836118d3565b15610cbd5760019050610cca565b610cc783836118d3565b90505b92915050565b5f610ce582600361150690919063ffffffff16565b9050919050565b7fea5f4eb72290e50c32abd6c23e45de3d8300b3286e1cbc2e293114b92e034e5e81565b5f5f1b81565b7fea5f4eb72290e50c32abd6c23e45de3d8300b3286e1cbc2e293114b92e034e5e610d4081611312565b610d48611936565b50565b7fea5f4eb72290e50c32abd6c23e45de3d8300b3286e1cbc2e293114b92e034e5e610d7581611312565b5f8383905003610db1576040517f59203cb900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610dbc60016118a9565b1115610dcb57610dca611936565b5b5f5f90505b83839050811015610ef157610e0b848483818110610df157610df0612702565b5b9050602002016020810190610e069190612226565b61196e565b610e46848483818110610e2157610e20612702565b5b9050602002016020810190610e369190612226565b6001611a2190919063ffffffff16565b610e7c576040517ff280d16100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b838382818110610e8f57610e8e612702565b5b9050602002016020810190610ea49190612226565b73ffffffffffffffffffffffffffffffffffffffff167f60305ce6c9104acd0969d358f926bf391174340660aaf5e6215261fd6847bf4660405160405180910390a2806001019050610dd0565b50505050565b5f610f0260016118a9565b905090565b5f5f610f11610ef7565b90505f5f90505b81811015610fcb575f610f2a826110ee565b73ffffffffffffffffffffffffffffffffffffffff1663d32c7bb5898989896040518563ffffffff1660e01b8152600401610f68949392919061272f565b602060405180830381865afa158015610f83573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fa79190612786565b90505f8160ff161115610fbf57809350505050610fe3565b50806001019050610f18565b505f6006811115610fdf57610fde61251f565b5b9150505b949350505050565b5f5f610ff5610ef7565b90505f5f90505b818110156110ad575f61100e826110ee565b73ffffffffffffffffffffffffffffffffffffffff1663d4ce14158888886040518463ffffffff1660e01b815260040161104a939291906127b1565b602060405180830381865afa158015611065573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110899190612786565b90505f8160ff1611156110a1578093505050506110c5565b50806001019050610ffc565b505f60068111156110c1576110c061251f565b5b9150505b9392505050565b6110d58261074d565b6110de81611312565b6110e8838361141d565b50505050565b5f6110f960016118a9565b82101561111b576111148260016118bc90919063ffffffff16565b905061111f565b5f90505b919050565b7fea5f4eb72290e50c32abd6c23e45de3d8300b3286e1cbc2e293114b92e034e5e61114e81611312565b61116282600161150690919063ffffffff16565b611198576040517fb370e90400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111a182611a4e565b5050565b7fea5f4eb72290e50c32abd6c23e45de3d8300b3286e1cbc2e293114b92e034e5e6111cf81611312565b6111d88261196e565b6111ec826001611a2190919063ffffffff16565b611222576040517ff280d16100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff167f60305ce6c9104acd0969d358f926bf391174340660aaf5e6215261fd6847bf4660405160405180910390a25050565b5f5f600681111561127d5761127c61251f565b5b60ff1661128b858585610feb565b60ff161490509392505050565b60606112a460036117e1565b905090565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6113238161131e61140f565b611ade565b50565b5f6113318383610ca2565b6114055760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506113a261140f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050611409565b5f90505b92915050565b5f611418611b2f565b905090565b5f6114288383610ca2565b156114fc575f5f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061149961140f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050611500565b5f90505b92915050565b5f61152b835f018373ffffffffffffffffffffffffffffffffffffffff165f1b611b97565b905092915050565b5f61153e60016118a9565b90505f5f90505b818110156115d7576115618160016118bc90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff16633e5af4ca878787876040518563ffffffff1660e01b815260040161159f949392919061272f565b5f604051808303815f87803b1580156115b6575f5ffd5b505af11580156115c8573d5f5f3e3d5ffd5b50505050806001019050611545565b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611644576040517fdc418b8000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61165881600361150690919063ffffffff16565b1561168f576040517ff423354700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116a3816003611a2190919063ffffffff16565b6116d9576040517f369bb9e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f2de35142b19ed5a07796cf30791959c592018f70b1d2d7c460eef8ffe713692b81604051611708919061232e565b60405180910390a150565b61172781600361150690919063ffffffff16565b61175d576040517fd456910600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611771816003611bb790919063ffffffff16565b6117a7576040517f369bb9e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f28a4ca7134a3b3f9aff286e79ad3daadb4a06d1b43d037a3a98bdc074edd9b7a816040516117d6919061232e565b60405180910390a150565b60605f6117ef835f01611be4565b905060608190508092505050919050565b5f61180b60016118a9565b90505f5f90505b818110156118a25761182e8160016118bc90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff16638baf29b48686866040518463ffffffff1660e01b815260040161186a939291906127b1565b5f604051808303815f87803b158015611881575f5ffd5b505af1158015611893573d5f5f3e3d5ffd5b50505050806001019050611812565b5050505050565b5f6118b5825f01611c3d565b9050919050565b5f6118c9835f0183611c4c565b5f1c905092915050565b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b7fdbf61473843cd9be1c9791ce51ef66d0da6c9026d62ba80c1ca433b13fb729b260405160405180910390a161196c6001611c73565b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119d3576040517ff9d152fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119e781600161150690919063ffffffff16565b15611a1e576040517fcc790a4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b5f611a46835f018373ffffffffffffffffffffffffffffffffffffffff165f1b611c81565b905092915050565b611a62816001611bb790919063ffffffff16565b611a98576040517ff280d16100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff167f6d83315c9718799346b67584ec64301b1457e989c8e35a8e2982a7776c04bfc460405160405180910390a250565b611ae88282610ca2565b611b2b5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401611b229291906127e6565b60405180910390fd5b5050565b5f5f5f36905090505f611b40611ce8565b9050808210158015611b575750611b5633610941565b5b15611b87575f36828403908092611b7093929190612815565b90611b7b9190612890565b60601c92505050611b94565b611b8f611cf6565b925050505b90565b5f5f836001015f8481526020019081526020015f20541415905092915050565b5f611bdc835f018373ffffffffffffffffffffffffffffffffffffffff165f1b611cfd565b905092915050565b6060815f01805480602002602001604051908101604052809291908181526020018280548015611c3157602002820191905f5260205f20905b815481526020019060010190808311611c1d575b50505050509050919050565b5f815f01805490509050919050565b5f825f018281548110611c6257611c61612702565b5b905f5260205f200154905092915050565b611c7e815f01611df9565b50565b5f611c8c8383611b97565b611cde57825f0182908060018154018082558091505060019003905f5260205f20015f9091909190915055825f0180549050836001015f8481526020019081526020015f208190555060019050611ce2565b5f90505b92915050565b5f611cf1611e61565b905090565b5f33905090565b5f5f836001015f8481526020019081526020015f205490505f8114611dee575f600182611d2a919061291b565b90505f6001865f0180549050611d40919061291b565b9050808214611da6575f865f018281548110611d5f57611d5e612702565b5b905f5260205f200154905080875f018481548110611d8057611d7f612702565b5b905f5260205f20018190555083876001015f8381526020019081526020015f2081905550505b855f01805480611db957611db861294e565b5b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050611df3565b5f9150505b92915050565b5f611e0382611c3d565b90505f5f90505b81811015611e5057826001015f845f018381548110611e2c57611e2b612702565b5b905f5260205f20015481526020019081526020015f205f9055806001019050611e0a565b50611e5d825f015f611e69565b5050565b5f6014905090565b8082555050565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611eb581611e81565b8114611ebf575f5ffd5b50565b5f81359050611ed081611eac565b92915050565b5f60208284031215611eeb57611eea611e79565b5b5f611ef884828501611ec2565b91505092915050565b5f8115159050919050565b611f1581611f01565b82525050565b5f602082019050611f2e5f830184611f0c565b92915050565b5f819050919050565b611f4681611f34565b82525050565b5f602082019050611f5f5f830184611f3d565b92915050565b611f6e81611f34565b8114611f78575f5ffd5b50565b5f81359050611f8981611f65565b92915050565b5f60208284031215611fa457611fa3611e79565b5b5f611fb184828501611f7b565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611fe382611fba565b9050919050565b611ff381611fd9565b8114611ffd575f5ffd5b50565b5f8135905061200e81611fea565b92915050565b5f5f6040838503121561202a57612029611e79565b5b5f61203785828601611f7b565b925050602061204885828601612000565b9150509250929050565b5f819050919050565b61206481612052565b811461206e575f5ffd5b50565b5f8135905061207f8161205b565b92915050565b5f5f5f5f6080858703121561209d5761209c611e79565b5b5f6120aa87828801612000565b94505060206120bb87828801612000565b93505060406120cc87828801612000565b92505060606120dd87828801612071565b91505092959194509250565b5f602082840312156120fe576120fd611e79565b5b5f61210b84828501612000565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61214681611fd9565b82525050565b5f612157838361213d565b60208301905092915050565b5f602082019050919050565b5f61217982612114565b612183818561211e565b935061218e8361212e565b805f5b838110156121be5781516121a5888261214c565b97506121b083612163565b925050600181019050612191565b5085935050505092915050565b5f6020820190508181035f8301526121e3818461216f565b905092915050565b5f6121f582611fd9565b9050919050565b612205816121eb565b811461220f575f5ffd5b50565b5f81359050612220816121fc565b92915050565b5f6020828403121561223b5761223a611e79565b5b5f61224884828501612212565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61229382612251565b61229d818561225b565b93506122ad81856020860161226b565b6122b681612279565b840191505092915050565b5f6020820190508181035f8301526122d98184612289565b905092915050565b5f5f604083850312156122f7576122f6611e79565b5b5f61230485828601612000565b925050602061231585828601612071565b9150509250929050565b61232881611fd9565b82525050565b5f6020820190506123415f83018461231f565b92915050565b5f60ff82169050919050565b61235c81612347565b8114612366575f5ffd5b50565b5f8135905061237781612353565b92915050565b5f6020828403121561239257612391611e79565b5b5f61239f84828501612369565b91505092915050565b5f5f5f606084860312156123bf576123be611e79565b5b5f6123cc86828701612000565b93505060206123dd86828701612000565b92505060406123ee86828701612071565b9150509250925092565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f840112612419576124186123f8565b5b8235905067ffffffffffffffff811115612436576124356123fc565b5b60208301915083602082028301111561245257612451612400565b5b9250929050565b5f5f6020838503121561246f5761246e611e79565b5b5f83013567ffffffffffffffff81111561248c5761248b611e7d565b5b61249885828601612404565b92509250509250929050565b6124ad81612052565b82525050565b5f6020820190506124c65f8301846124a4565b92915050565b6124d581612347565b82525050565b5f6020820190506124ee5f8301846124cc565b92915050565b5f6020828403121561250957612508611e79565b5b5f61251684828501612071565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b61255581611f01565b811461255f575f5ffd5b50565b5f815190506125708161254c565b92915050565b5f6020828403121561258b5761258a611e79565b5b5f61259884828501612562565b91505092915050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6125db82612279565b810181811067ffffffffffffffff821117156125fa576125f96125a5565b5b80604052505050565b5f61260c611e70565b905061261882826125d2565b919050565b5f67ffffffffffffffff821115612637576126366125a5565b5b61264082612279565b9050602081019050919050565b5f61265f61265a8461261d565b612603565b90508281526020810184848401111561267b5761267a6125a1565b5b61268684828561226b565b509392505050565b5f82601f8301126126a2576126a16123f8565b5b81516126b284826020860161264d565b91505092915050565b5f602082840312156126d0576126cf611e79565b5b5f82015167ffffffffffffffff8111156126ed576126ec611e7d565b5b6126f98482850161268e565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6080820190506127425f83018761231f565b61274f602083018661231f565b61275c604083018561231f565b61276960608301846124a4565b95945050505050565b5f8151905061278081612353565b92915050565b5f6020828403121561279b5761279a611e79565b5b5f6127a884828501612772565b91505092915050565b5f6060820190506127c45f83018661231f565b6127d1602083018561231f565b6127de60408301846124a4565b949350505050565b5f6040820190506127f95f83018561231f565b6128066020830184611f3d565b9392505050565b5f5ffd5b5f5ffd5b5f5f858511156128285761282761280d565b5b8386111561283957612838612811565b5b6001850283019150848603905094509492505050565b5f82905092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b5f82821b905092915050565b5f61289b838361284f565b826128a68135612859565b925060148210156128e6576128e17fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802612884565b831692505b505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61292582612052565b915061293083612052565b9250828203905081811115612948576129476128ee565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220424f0794bba77302c7f954fbeba7cfe1f1e71aaf9ccfb51c88b7fc8c64e5082264736f6c634300081e0033",
+ "deployedBytecode": "0x608060405234801561000f575f5ffd5b5060043610610204575f3560e01c80638baf29b411610118578063bc13eacc116100ab578063db18af6c1161007a578063db18af6c146105fa578063df21950f1461062a578063e3c4602c14610646578063e46638e614610662578063e54621d21461069257610204565b8063bc13eacc14610560578063d32c7bb51461057e578063d4ce1415146105ae578063d547741f146105de57610204565b80639b11c115116100e75780639b11c115146104fe578063a217fddf1461051c578063b043572e1461053a578063b27aef3a1461054457610204565b80638baf29b4146104665780638d2ea7721461048257806391d148541461049e578063993e8b95146104ce57610204565b806352f6747a1161019b5780635f8dead31161016a5780635f8dead3146103ae5780636a3edf28146103ca5780637157797f146103e85780637da0a877146104185780637f4ab1dd1461043657610204565b806352f6747a1461031257806354e4b9451461033057806354fd4d5014610360578063572b6c051461037e57610204565b806336568abe116101d757806336568abe146102a25780633e5af4ca146102be5780633ff5aa02146102da57806340db3b50146102f657610204565b806301ffc9a71461020857806303c26bcd14610238578063248a9ca3146102565780632f2ff15d14610286575b5f5ffd5b610222600480360381019061021d9190611ed6565b6106b0565b60405161022f9190611f1b565b60405180910390f35b610240610729565b60405161024d9190611f4c565b60405180910390f35b610270600480360381019061026b9190611f8f565b61074d565b60405161027d9190611f4c565b60405180910390f35b6102a0600480360381019061029b9190612014565b610769565b005b6102bc60048036038101906102b79190612014565b61078b565b005b6102d860048036038101906102d39190612085565b610806565b005b6102f460048036038101906102ef91906120e9565b610869565b005b610310600480360381019061030b91906120e9565b6108a0565b005b61031a6108d7565b60405161032791906121cb565b60405180910390f35b61034a60048036038101906103459190612226565b6108e8565b6040516103579190611f1b565b60405180910390f35b610368610904565b60405161037591906122c1565b60405180910390f35b610398600480360381019061039391906120e9565b610941565b6040516103a59190611f1b565b60405180910390f35b6103c860048036038101906103c391906122e1565b61097f565b005b6103d26109df565b6040516103df919061232e565b60405180910390f35b61040260048036038101906103fd9190612085565b610a13565b60405161040f9190611f1b565b60405180910390f35b610420610a44565b60405161042d919061232e565b60405180910390f35b610450600480360381019061044b919061237d565b610a6b565b60405161045d91906122c1565b60405180910390f35b610480600480360381019061047b91906123a8565b610be1565b005b61049c600480360381019061049791906122e1565b610c42565b005b6104b860048036038101906104b39190612014565b610ca2565b6040516104c59190611f1b565b60405180910390f35b6104e860048036038101906104e391906120e9565b610cd0565b6040516104f59190611f1b565b60405180910390f35b610506610cec565b6040516105139190611f4c565b60405180910390f35b610524610d10565b6040516105319190611f4c565b60405180910390f35b610542610d16565b005b61055e60048036038101906105599190612459565b610d4b565b005b610568610ef7565b60405161057591906124b3565b60405180910390f35b61059860048036038101906105939190612085565b610f07565b6040516105a591906124db565b60405180910390f35b6105c860048036038101906105c391906123a8565b610feb565b6040516105d591906124db565b60405180910390f35b6105f860048036038101906105f39190612014565b6110cc565b005b610614600480360381019061060f91906124f4565b6110ee565b604051610621919061232e565b60405180910390f35b610644600480360381019061063f9190612226565b611124565b005b610660600480360381019061065b9190612226565b6111a5565b005b61067c600480360381019061067791906123a8565b611269565b6040516106899190611f1b565b60405180910390f35b61069a611298565b6040516106a791906121cb565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806107225750610721826112a9565b5b9050919050565b7fe5c50d0927e06141e032cb9a67e1d7092dc85c0b0825191f7e1cede60002856881565b5f5f5f8381526020019081526020015f20600101549050919050565b6107728261074d565b61077b81611312565b6107858383611326565b50505050565b61079361140f565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146107f7576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610801828261141d565b505050565b61082161081161140f565b600361150690919063ffffffff16565b610857576040517fe39b3c8f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61086384848484611533565b50505050565b7fe5c50d0927e06141e032cb9a67e1d7092dc85c0b0825191f7e1cede60002856861089381611312565b61089c826115df565b5050565b7fe5c50d0927e06141e032cb9a67e1d7092dc85c0b0825191f7e1cede6000285686108ca81611312565b6108d382611713565b5050565b60606108e360016117e1565b905090565b5f6108fd82600161150690919063ffffffff16565b9050919050565b60606040518060400160405280600581526020017f332e302e30000000000000000000000000000000000000000000000000000000815250905090565b5f61094a610a44565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b61099a61098a61140f565b600361150690919063ffffffff16565b6109d0576040517fe39b3c8f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109db5f8383611800565b5050565b5f5f6109eb60036118a9565b1115610a0c57610a055f60036118bc90919063ffffffff16565b9050610a10565b5f90505b90565b5f5f6006811115610a2757610a2661251f565b5b60ff16610a3686868686610f07565b60ff16149050949350505050565b5f7f0000000000000000000000000000000000000000000000000000000000000000905090565b60605f610a76610ef7565b90505f5f90505b81811015610ba157610a8e816110ee565b73ffffffffffffffffffffffffffffffffffffffff16637d045df6856040518263ffffffff1660e01b8152600401610ac691906124db565b602060405180830381865afa158015610ae1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b059190612576565b15610b9657610b13816110ee565b73ffffffffffffffffffffffffffffffffffffffff16637f4ab1dd856040518263ffffffff1660e01b8152600401610b4b91906124db565b5f60405180830381865afa158015610b65573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610b8d91906126bb565b92505050610bdc565b806001019050610a7d565b506040518060400160405280601881526020017f556e6b6e6f776e207265737472696374696f6e20636f646500000000000000008152509150505b919050565b610bfc610bec61140f565b600361150690919063ffffffff16565b610c32576040517fe39b3c8f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c3d838383611800565b505050565b610c5d610c4d61140f565b600361150690919063ffffffff16565b610c93576040517fe39b3c8f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c9e825f83611800565b5050565b5f610caf5f5f1b836118d3565b15610cbd5760019050610cca565b610cc783836118d3565b90505b92915050565b5f610ce582600361150690919063ffffffff16565b9050919050565b7fea5f4eb72290e50c32abd6c23e45de3d8300b3286e1cbc2e293114b92e034e5e81565b5f5f1b81565b7fea5f4eb72290e50c32abd6c23e45de3d8300b3286e1cbc2e293114b92e034e5e610d4081611312565b610d48611936565b50565b7fea5f4eb72290e50c32abd6c23e45de3d8300b3286e1cbc2e293114b92e034e5e610d7581611312565b5f8383905003610db1576040517f59203cb900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610dbc60016118a9565b1115610dcb57610dca611936565b5b5f5f90505b83839050811015610ef157610e0b848483818110610df157610df0612702565b5b9050602002016020810190610e069190612226565b61196e565b610e46848483818110610e2157610e20612702565b5b9050602002016020810190610e369190612226565b6001611a2190919063ffffffff16565b610e7c576040517ff280d16100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b838382818110610e8f57610e8e612702565b5b9050602002016020810190610ea49190612226565b73ffffffffffffffffffffffffffffffffffffffff167f60305ce6c9104acd0969d358f926bf391174340660aaf5e6215261fd6847bf4660405160405180910390a2806001019050610dd0565b50505050565b5f610f0260016118a9565b905090565b5f5f610f11610ef7565b90505f5f90505b81811015610fcb575f610f2a826110ee565b73ffffffffffffffffffffffffffffffffffffffff1663d32c7bb5898989896040518563ffffffff1660e01b8152600401610f68949392919061272f565b602060405180830381865afa158015610f83573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fa79190612786565b90505f8160ff161115610fbf57809350505050610fe3565b50806001019050610f18565b505f6006811115610fdf57610fde61251f565b5b9150505b949350505050565b5f5f610ff5610ef7565b90505f5f90505b818110156110ad575f61100e826110ee565b73ffffffffffffffffffffffffffffffffffffffff1663d4ce14158888886040518463ffffffff1660e01b815260040161104a939291906127b1565b602060405180830381865afa158015611065573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110899190612786565b90505f8160ff1611156110a1578093505050506110c5565b50806001019050610ffc565b505f60068111156110c1576110c061251f565b5b9150505b9392505050565b6110d58261074d565b6110de81611312565b6110e8838361141d565b50505050565b5f6110f960016118a9565b82101561111b576111148260016118bc90919063ffffffff16565b905061111f565b5f90505b919050565b7fea5f4eb72290e50c32abd6c23e45de3d8300b3286e1cbc2e293114b92e034e5e61114e81611312565b61116282600161150690919063ffffffff16565b611198576040517fb370e90400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111a182611a4e565b5050565b7fea5f4eb72290e50c32abd6c23e45de3d8300b3286e1cbc2e293114b92e034e5e6111cf81611312565b6111d88261196e565b6111ec826001611a2190919063ffffffff16565b611222576040517ff280d16100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff167f60305ce6c9104acd0969d358f926bf391174340660aaf5e6215261fd6847bf4660405160405180910390a25050565b5f5f600681111561127d5761127c61251f565b5b60ff1661128b858585610feb565b60ff161490509392505050565b60606112a460036117e1565b905090565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6113238161131e61140f565b611ade565b50565b5f6113318383610ca2565b6114055760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506113a261140f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050611409565b5f90505b92915050565b5f611418611b2f565b905090565b5f6114288383610ca2565b156114fc575f5f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061149961140f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050611500565b5f90505b92915050565b5f61152b835f018373ffffffffffffffffffffffffffffffffffffffff165f1b611b97565b905092915050565b5f61153e60016118a9565b90505f5f90505b818110156115d7576115618160016118bc90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff16633e5af4ca878787876040518563ffffffff1660e01b815260040161159f949392919061272f565b5f604051808303815f87803b1580156115b6575f5ffd5b505af11580156115c8573d5f5f3e3d5ffd5b50505050806001019050611545565b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611644576040517fdc418b8000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61165881600361150690919063ffffffff16565b1561168f576040517ff423354700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116a3816003611a2190919063ffffffff16565b6116d9576040517f369bb9e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f2de35142b19ed5a07796cf30791959c592018f70b1d2d7c460eef8ffe713692b81604051611708919061232e565b60405180910390a150565b61172781600361150690919063ffffffff16565b61175d576040517fd456910600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611771816003611bb790919063ffffffff16565b6117a7576040517f369bb9e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f28a4ca7134a3b3f9aff286e79ad3daadb4a06d1b43d037a3a98bdc074edd9b7a816040516117d6919061232e565b60405180910390a150565b60605f6117ef835f01611be4565b905060608190508092505050919050565b5f61180b60016118a9565b90505f5f90505b818110156118a25761182e8160016118bc90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff16638baf29b48686866040518463ffffffff1660e01b815260040161186a939291906127b1565b5f604051808303815f87803b158015611881575f5ffd5b505af1158015611893573d5f5f3e3d5ffd5b50505050806001019050611812565b5050505050565b5f6118b5825f01611c3d565b9050919050565b5f6118c9835f0183611c4c565b5f1c905092915050565b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b7fdbf61473843cd9be1c9791ce51ef66d0da6c9026d62ba80c1ca433b13fb729b260405160405180910390a161196c6001611c73565b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119d3576040517ff9d152fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119e781600161150690919063ffffffff16565b15611a1e576040517fcc790a4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b5f611a46835f018373ffffffffffffffffffffffffffffffffffffffff165f1b611c81565b905092915050565b611a62816001611bb790919063ffffffff16565b611a98576040517ff280d16100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff167f6d83315c9718799346b67584ec64301b1457e989c8e35a8e2982a7776c04bfc460405160405180910390a250565b611ae88282610ca2565b611b2b5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401611b229291906127e6565b60405180910390fd5b5050565b5f5f5f36905090505f611b40611ce8565b9050808210158015611b575750611b5633610941565b5b15611b87575f36828403908092611b7093929190612815565b90611b7b9190612890565b60601c92505050611b94565b611b8f611cf6565b925050505b90565b5f5f836001015f8481526020019081526020015f20541415905092915050565b5f611bdc835f018373ffffffffffffffffffffffffffffffffffffffff165f1b611cfd565b905092915050565b6060815f01805480602002602001604051908101604052809291908181526020018280548015611c3157602002820191905f5260205f20905b815481526020019060010190808311611c1d575b50505050509050919050565b5f815f01805490509050919050565b5f825f018281548110611c6257611c61612702565b5b905f5260205f200154905092915050565b611c7e815f01611df9565b50565b5f611c8c8383611b97565b611cde57825f0182908060018154018082558091505060019003905f5260205f20015f9091909190915055825f0180549050836001015f8481526020019081526020015f208190555060019050611ce2565b5f90505b92915050565b5f611cf1611e61565b905090565b5f33905090565b5f5f836001015f8481526020019081526020015f205490505f8114611dee575f600182611d2a919061291b565b90505f6001865f0180549050611d40919061291b565b9050808214611da6575f865f018281548110611d5f57611d5e612702565b5b905f5260205f200154905080875f018481548110611d8057611d7f612702565b5b905f5260205f20018190555083876001015f8381526020019081526020015f2081905550505b855f01805480611db957611db861294e565b5b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050611df3565b5f9150505b92915050565b5f611e0382611c3d565b90505f5f90505b81811015611e5057826001015f845f018381548110611e2c57611e2b612702565b5b905f5260205f20015481526020019081526020015f205f9055806001019050611e0a565b50611e5d825f015f611e69565b5050565b5f6014905090565b8082555050565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611eb581611e81565b8114611ebf575f5ffd5b50565b5f81359050611ed081611eac565b92915050565b5f60208284031215611eeb57611eea611e79565b5b5f611ef884828501611ec2565b91505092915050565b5f8115159050919050565b611f1581611f01565b82525050565b5f602082019050611f2e5f830184611f0c565b92915050565b5f819050919050565b611f4681611f34565b82525050565b5f602082019050611f5f5f830184611f3d565b92915050565b611f6e81611f34565b8114611f78575f5ffd5b50565b5f81359050611f8981611f65565b92915050565b5f60208284031215611fa457611fa3611e79565b5b5f611fb184828501611f7b565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611fe382611fba565b9050919050565b611ff381611fd9565b8114611ffd575f5ffd5b50565b5f8135905061200e81611fea565b92915050565b5f5f6040838503121561202a57612029611e79565b5b5f61203785828601611f7b565b925050602061204885828601612000565b9150509250929050565b5f819050919050565b61206481612052565b811461206e575f5ffd5b50565b5f8135905061207f8161205b565b92915050565b5f5f5f5f6080858703121561209d5761209c611e79565b5b5f6120aa87828801612000565b94505060206120bb87828801612000565b93505060406120cc87828801612000565b92505060606120dd87828801612071565b91505092959194509250565b5f602082840312156120fe576120fd611e79565b5b5f61210b84828501612000565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61214681611fd9565b82525050565b5f612157838361213d565b60208301905092915050565b5f602082019050919050565b5f61217982612114565b612183818561211e565b935061218e8361212e565b805f5b838110156121be5781516121a5888261214c565b97506121b083612163565b925050600181019050612191565b5085935050505092915050565b5f6020820190508181035f8301526121e3818461216f565b905092915050565b5f6121f582611fd9565b9050919050565b612205816121eb565b811461220f575f5ffd5b50565b5f81359050612220816121fc565b92915050565b5f6020828403121561223b5761223a611e79565b5b5f61224884828501612212565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61229382612251565b61229d818561225b565b93506122ad81856020860161226b565b6122b681612279565b840191505092915050565b5f6020820190508181035f8301526122d98184612289565b905092915050565b5f5f604083850312156122f7576122f6611e79565b5b5f61230485828601612000565b925050602061231585828601612071565b9150509250929050565b61232881611fd9565b82525050565b5f6020820190506123415f83018461231f565b92915050565b5f60ff82169050919050565b61235c81612347565b8114612366575f5ffd5b50565b5f8135905061237781612353565b92915050565b5f6020828403121561239257612391611e79565b5b5f61239f84828501612369565b91505092915050565b5f5f5f606084860312156123bf576123be611e79565b5b5f6123cc86828701612000565b93505060206123dd86828701612000565b92505060406123ee86828701612071565b9150509250925092565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f840112612419576124186123f8565b5b8235905067ffffffffffffffff811115612436576124356123fc565b5b60208301915083602082028301111561245257612451612400565b5b9250929050565b5f5f6020838503121561246f5761246e611e79565b5b5f83013567ffffffffffffffff81111561248c5761248b611e7d565b5b61249885828601612404565b92509250509250929050565b6124ad81612052565b82525050565b5f6020820190506124c65f8301846124a4565b92915050565b6124d581612347565b82525050565b5f6020820190506124ee5f8301846124cc565b92915050565b5f6020828403121561250957612508611e79565b5b5f61251684828501612071565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b61255581611f01565b811461255f575f5ffd5b50565b5f815190506125708161254c565b92915050565b5f6020828403121561258b5761258a611e79565b5b5f61259884828501612562565b91505092915050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6125db82612279565b810181811067ffffffffffffffff821117156125fa576125f96125a5565b5b80604052505050565b5f61260c611e70565b905061261882826125d2565b919050565b5f67ffffffffffffffff821115612637576126366125a5565b5b61264082612279565b9050602081019050919050565b5f61265f61265a8461261d565b612603565b90508281526020810184848401111561267b5761267a6125a1565b5b61268684828561226b565b509392505050565b5f82601f8301126126a2576126a16123f8565b5b81516126b284826020860161264d565b91505092915050565b5f602082840312156126d0576126cf611e79565b5b5f82015167ffffffffffffffff8111156126ed576126ec611e7d565b5b6126f98482850161268e565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6080820190506127425f83018761231f565b61274f602083018661231f565b61275c604083018561231f565b61276960608301846124a4565b95945050505050565b5f8151905061278081612353565b92915050565b5f6020828403121561279b5761279a611e79565b5b5f6127a884828501612772565b91505092915050565b5f6060820190506127c45f83018661231f565b6127d1602083018561231f565b6127de60408301846124a4565b949350505050565b5f6040820190506127f95f83018561231f565b6128066020830184611f3d565b9392505050565b5f5ffd5b5f5ffd5b5f5f858511156128285761282761280d565b5b8386111561283957612838612811565b5b6001850283019150848603905094509492505050565b5f82905092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b5f82821b905092915050565b5f61289b838361284f565b826128a68135612859565b925060148210156128e6576128e17fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802612884565b831692505b505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61292582612052565b915061293083612052565b9250828203905081811115612948576129476128ee565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220424f0794bba77302c7f954fbeba7cfe1f1e71aaf9ccfb51c88b7fc8c64e5082264736f6c634300081e0033",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/RuleEngineBase.sol/RuleEngineBase.dbg.json b/doc/compilation/hardhat/src/RuleEngineBase.sol/RuleEngineBase.dbg.json
new file mode 100644
index 0000000..4d68568
--- /dev/null
+++ b/doc/compilation/hardhat/src/RuleEngineBase.sol/RuleEngineBase.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/RuleEngineBase.sol/RuleEngineBase.json b/doc/compilation/hardhat/src/RuleEngineBase.sol/RuleEngineBase.json
new file mode 100644
index 0000000..2c66cc2
--- /dev/null
+++ b/doc/compilation/hardhat/src/RuleEngineBase.sol/RuleEngineBase.json
@@ -0,0 +1,801 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleEngineBase",
+ "sourceName": "src/RuleEngineBase.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "AccessControlBadConfirmation",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "neededRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AccessControlUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_AdminWithAddressZeroNotAllowed",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_InvalidTokenAddress",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_OperationNotSuccessful",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_TokenAlreadyBound",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_TokenNotBound",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_UnauthorizedCaller",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_ArrayIsEmpty",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_OperationNotSuccessful",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_RuleAddressZeroNotAllowed",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_RuleAlreadyExists",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_RuleDoNotMatch",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "contract IRule",
+ "name": "rule",
+ "type": "address"
+ }
+ ],
+ "name": "AddRule",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "ClearRules",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "contract IRule",
+ "name": "rule",
+ "type": "address"
+ }
+ ],
+ "name": "RemoveRule",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "previousAdminRole",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "newAdminRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RoleAdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleGranted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleRevoked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "TokenBound",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "TokenUnbound",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "COMPLIANCE_MANAGER_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "DEFAULT_ADMIN_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "RULES_MANAGEMENT_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule",
+ "name": "rule_",
+ "type": "address"
+ }
+ ],
+ "name": "addRule",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "bindToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "clearRules",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule",
+ "name": "rule_",
+ "type": "address"
+ }
+ ],
+ "name": "containsRule",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "created",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "destroyed",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestrictionFrom",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getRoleAdmin",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTokenBound",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTokenBounds",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "grantRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "hasRole",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "isTokenBound",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint8",
+ "name": "restrictionCode",
+ "type": "uint8"
+ }
+ ],
+ "name": "messageForTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule",
+ "name": "rule_",
+ "type": "address"
+ }
+ ],
+ "name": "removeRule",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "callerConfirmation",
+ "type": "address"
+ }
+ ],
+ "name": "renounceRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "revokeRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "ruleId",
+ "type": "uint256"
+ }
+ ],
+ "name": "rule",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "rules",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "rulesCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule[]",
+ "name": "rules_",
+ "type": "address[]"
+ }
+ ],
+ "name": "setRules",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes4",
+ "name": "interfaceId",
+ "type": "bytes4"
+ }
+ ],
+ "name": "supportsInterface",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "unbindToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "version_",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/interfaces/IERC3643Compliance.sol/IERC3643Compliance.dbg.json b/doc/compilation/hardhat/src/interfaces/IERC3643Compliance.sol/IERC3643Compliance.dbg.json
new file mode 100644
index 0000000..30bf738
--- /dev/null
+++ b/doc/compilation/hardhat/src/interfaces/IERC3643Compliance.sol/IERC3643Compliance.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/interfaces/IERC3643Compliance.sol/IERC3643Compliance.json b/doc/compilation/hardhat/src/interfaces/IERC3643Compliance.sol/IERC3643Compliance.json
new file mode 100644
index 0000000..120674e
--- /dev/null
+++ b/doc/compilation/hardhat/src/interfaces/IERC3643Compliance.sol/IERC3643Compliance.json
@@ -0,0 +1,196 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "IERC3643Compliance",
+ "sourceName": "src/interfaces/IERC3643Compliance.sol",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "TokenBound",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "TokenUnbound",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "bindToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "isValid",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "created",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "destroyed",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTokenBound",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTokenBounds",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "tokens",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "isTokenBound",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "isBound",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "unbindToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/interfaces/IRule.sol/IRule.dbg.json b/doc/compilation/hardhat/src/interfaces/IRule.sol/IRule.dbg.json
new file mode 100644
index 0000000..30bf738
--- /dev/null
+++ b/doc/compilation/hardhat/src/interfaces/IRule.sol/IRule.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/interfaces/IRule.sol/IRule.json b/doc/compilation/hardhat/src/interfaces/IRule.sol/IRule.json
new file mode 100644
index 0000000..6af72d9
--- /dev/null
+++ b/doc/compilation/hardhat/src/interfaces/IRule.sol/IRule.json
@@ -0,0 +1,226 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "IRule",
+ "sourceName": "src/interfaces/IRule.sol",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "uint8",
+ "name": "restrictionCode",
+ "type": "uint8"
+ }
+ ],
+ "name": "canReturnTransferRestrictionCode",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "isValid",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestrictionFrom",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint8",
+ "name": "restrictionCode",
+ "type": "uint8"
+ }
+ ],
+ "name": "messageForTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/interfaces/IRulesManagementModule.sol/IRulesManagementModule.dbg.json b/doc/compilation/hardhat/src/interfaces/IRulesManagementModule.sol/IRulesManagementModule.dbg.json
new file mode 100644
index 0000000..30bf738
--- /dev/null
+++ b/doc/compilation/hardhat/src/interfaces/IRulesManagementModule.sol/IRulesManagementModule.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/interfaces/IRulesManagementModule.sol/IRulesManagementModule.json b/doc/compilation/hardhat/src/interfaces/IRulesManagementModule.sol/IRulesManagementModule.json
new file mode 100644
index 0000000..0d1057e
--- /dev/null
+++ b/doc/compilation/hardhat/src/interfaces/IRulesManagementModule.sol/IRulesManagementModule.json
@@ -0,0 +1,121 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "IRulesManagementModule",
+ "sourceName": "src/interfaces/IRulesManagementModule.sol",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule",
+ "name": "rule_",
+ "type": "address"
+ }
+ ],
+ "name": "addRule",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "clearRules",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule",
+ "name": "rule_",
+ "type": "address"
+ }
+ ],
+ "name": "containsRule",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "exists",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule",
+ "name": "rule_",
+ "type": "address"
+ }
+ ],
+ "name": "removeRule",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "ruleId",
+ "type": "uint256"
+ }
+ ],
+ "name": "rule",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "ruleAddress",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "rules",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "ruleAddresses",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "rulesCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "numberOfrules",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule[]",
+ "name": "rules_",
+ "type": "address[]"
+ }
+ ],
+ "name": "setRules",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/operation/RuleConditionalTransferLight.sol/RuleConditionalTransferLight.dbg.json b/doc/compilation/hardhat/src/mocks/rules/operation/RuleConditionalTransferLight.sol/RuleConditionalTransferLight.dbg.json
new file mode 100644
index 0000000..603ee8f
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/operation/RuleConditionalTransferLight.sol/RuleConditionalTransferLight.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/operation/RuleConditionalTransferLight.sol/RuleConditionalTransferLight.json b/doc/compilation/hardhat/src/mocks/rules/operation/RuleConditionalTransferLight.sol/RuleConditionalTransferLight.json
new file mode 100644
index 0000000..926f9f6
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/operation/RuleConditionalTransferLight.sol/RuleConditionalTransferLight.json
@@ -0,0 +1,644 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleConditionalTransferLight",
+ "sourceName": "src/mocks/rules/operation/RuleConditionalTransferLight.sol",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "admin",
+ "type": "address"
+ },
+ {
+ "internalType": "contract IRuleEngine",
+ "name": "ruleEngineContract",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "inputs": [],
+ "name": "AccessControlBadConfirmation",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "neededRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AccessControlUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "TransferNotApproved",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "previousAdminRole",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "newAdminRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RoleAdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleGranted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleRevoked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "name": "TransferApproved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "remaining",
+ "type": "uint256"
+ }
+ ],
+ "name": "TransferExecuted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "CODE_TRANSFER_REQUEST_NOT_APPROVED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "DEFAULT_ADMIN_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "OPERATOR_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "RULE_ENGINE_CONTRACT_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "approvalCounts",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approveTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approvedCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint8",
+ "name": "restrictionCode",
+ "type": "uint8"
+ }
+ ],
+ "name": "canReturnTransferRestrictionCode",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "isValid",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestrictionFrom",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getRoleAdmin",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "grantRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "hasRole",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint8",
+ "name": "restrictionCode",
+ "type": "uint8"
+ }
+ ],
+ "name": "messageForTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "callerConfirmation",
+ "type": "address"
+ }
+ ],
+ "name": "renounceRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "revokeRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes4",
+ "name": "interfaceId",
+ "type": "bytes4"
+ }
+ ],
+ "name": "supportsInterface",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x608060405234801561000f575f5ffd5b5060405161174138038061174183398181016040528101906100319190610347565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361009f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610096906103df565b60405180910390fd5b6100b15f5f1b3361014f60201b60201c565b506100e27f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298361014f60201b60201c565b505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610148576101467f5007339590b47d4786f4ab2ef7ffa0ec54bc5fe7244dd97bc6efa6ab3799807b8261014f60201b60201c565b505b50506103fd565b5f610160838361024460201b60201c565b61023a5760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506101d76102a760201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001905061023e565b5f90505b92915050565b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f33905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6102db826102b2565b9050919050565b6102eb816102d1565b81146102f5575f5ffd5b50565b5f81519050610306816102e2565b92915050565b5f610316826102d1565b9050919050565b6103268161030c565b8114610330575f5ffd5b50565b5f815190506103418161031d565b92915050565b5f5f6040838503121561035d5761035c6102ae565b5b5f61036a858286016102f8565b925050602061037b85828601610333565b9150509250929050565b5f82825260208201905092915050565b7f496e76616c6964206f70657261746f72000000000000000000000000000000005f82015250565b5f6103c9601083610385565b91506103d482610395565b602082019050919050565b5f6020820190508181035f8301526103f6816103bd565b9050919050565b6113378061040a5f395ff3fe608060405234801561000f575f5ffd5b5060043610610135575f3560e01c80638abed32b116100b6578063d4ce14151161007a578063d4ce141514610393578063d547741f146103c3578063dfdc49b9146103df578063e46638e6146103fd578063f02322f01461042d578063f5b541a61461044b57610135565b80638abed32b146102c95780638baf29b4146102f957806391d1485414610315578063a217fddf14610345578063d32c7bb51461036357610135565b80633e5af4ca116100fd5780633e5af4ca146102015780637157797f1461021d5780637d045df61461024d5780637f4ab1dd1461027d57806382580805146102ad57610135565b806301ffc9a714610139578063248a9ca31461016957806325005a41146101995780632f2ff15d146101c957806336568abe146101e5575b5f5ffd5b610153600480360381019061014e9190610d6a565b610469565b6040516101609190610daf565b60405180910390f35b610183600480360381019061017e9190610dfb565b6104e2565b6040516101909190610e35565b60405180910390f35b6101b360048036038101906101ae9190610edb565b6104fe565b6040516101c09190610f3a565b60405180910390f35b6101e360048036038101906101de9190610f53565b610549565b005b6101ff60048036038101906101fa9190610f53565b61056b565b005b61021b60048036038101906102169190610f91565b6105e6565b005b61023760048036038101906102329190610f91565b6105f7565b6040516102449190610daf565b60405180910390f35b6102676004803603810190610262919061102b565b610628565b6040516102749190610daf565b60405180910390f35b6102976004803603810190610292919061102b565b61063a565b6040516102a491906110c6565b60405180910390f35b6102c760048036038101906102c29190610edb565b6106a8565b005b6102e360048036038101906102de9190610dfb565b6107a6565b6040516102f09190610f3a565b60405180910390f35b610313600480360381019061030e9190610edb565b6107bb565b005b61032f600480360381019061032a9190610f53565b6108d8565b60405161033c9190610daf565b60405180910390f35b61034d61093b565b60405161035a9190610e35565b60405180910390f35b61037d60048036038101906103789190610f91565b610941565b60405161038a91906110f5565b60405180910390f35b6103ad60048036038101906103a89190610edb565b610957565b6040516103ba91906110f5565b60405180910390f35b6103dd60048036038101906103d89190610f53565b6109cc565b005b6103e76109ee565b6040516103f491906110f5565b60405180910390f35b61041760048036038101906104129190610edb565b6109f3565b6040516104249190610daf565b60405180910390f35b610435610a22565b6040516104429190610e35565b60405180910390f35b610453610a46565b6040516104609190610e35565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104db57506104da82610a6a565b5b9050919050565b5f5f5f8381526020019081526020015f20600101549050919050565b5f5f84848460405160200161051593929190611173565b60405160208183030381529060405280519060200120905060015f8281526020019081526020015f20549150509392505050565b610552826104e2565b61055b81610ad3565b6105658383610ae7565b50505050565b610573610bd0565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146105d7576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105e18282610bd7565b505050565b6105f18383836107bb565b50505050565b5f5f600681111561060b5761060a6111af565b5b60ff1661061a86868686610941565b60ff16149050949350505050565b5f604760ff168260ff16149050919050565b6060604760ff168260ff160361066a576040518060600160405280603581526020016112cd6035913990506106a3565b6040518060400160405280601881526020017f556e6b6e6f776e207265737472696374696f6e20636f6465000000000000000081525090505b919050565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9296106d281610ad3565b5f8484846040516020016106e893929190611173565b6040516020818303038152906040528051906020012090506001805f8381526020019081526020015f205f8282546107209190611209565b925050819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167feccbdf7c486b88cbffbd8100b22951057ab0de2b73f27f625cc468ccabc3d08a8560015f8681526020019081526020015f205460405161079792919061123c565b60405180910390a35050505050565b6001602052805f5260405f205f915090505481565b5f8383836040516020016107d193929190611173565b6040516020818303038152906040528051906020012090505f60015f8381526020019081526020015f205490505f8103610837576040517ff82ba75a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816108449190611263565b60015f8481526020019081526020015f20819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f8e386ea29f37964fdbdb87193d773dea74e258b0f6108461c88c712051fb27bc8560015f8781526020019081526020015f20546040516108c992919061123c565b60405180910390a35050505050565b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f1b81565b5f61094d848484610957565b9050949350505050565b5f5f84848460405160200161096e93929190611173565b6040516020818303038152906040528051906020012090505f60015f8381526020019081526020015f205490505f81036109ad576047925050506109c5565b5f60068111156109c0576109bf6111af565b5b925050505b9392505050565b6109d5826104e2565b6109de81610ad3565b6109e88383610bd7565b50505050565b604781565b5f5f6006811115610a0757610a066111af565b5b60ff16610a15858585610957565b60ff161490509392505050565b7f5007339590b47d4786f4ab2ef7ffa0ec54bc5fe7244dd97bc6efa6ab3799807b81565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92981565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610ae481610adf610bd0565b610cc0565b50565b5f610af283836108d8565b610bc65760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550610b63610bd0565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050610bca565b5f90505b92915050565b5f33905090565b5f610be283836108d8565b15610cb6575f5f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550610c53610bd0565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050610cba565b5f90505b92915050565b610cca82826108d8565b610d0d5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401610d049291906112a5565b60405180910390fd5b5050565b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610d4981610d15565b8114610d53575f5ffd5b50565b5f81359050610d6481610d40565b92915050565b5f60208284031215610d7f57610d7e610d11565b5b5f610d8c84828501610d56565b91505092915050565b5f8115159050919050565b610da981610d95565b82525050565b5f602082019050610dc25f830184610da0565b92915050565b5f819050919050565b610dda81610dc8565b8114610de4575f5ffd5b50565b5f81359050610df581610dd1565b92915050565b5f60208284031215610e1057610e0f610d11565b5b5f610e1d84828501610de7565b91505092915050565b610e2f81610dc8565b82525050565b5f602082019050610e485f830184610e26565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610e7782610e4e565b9050919050565b610e8781610e6d565b8114610e91575f5ffd5b50565b5f81359050610ea281610e7e565b92915050565b5f819050919050565b610eba81610ea8565b8114610ec4575f5ffd5b50565b5f81359050610ed581610eb1565b92915050565b5f5f5f60608486031215610ef257610ef1610d11565b5b5f610eff86828701610e94565b9350506020610f1086828701610e94565b9250506040610f2186828701610ec7565b9150509250925092565b610f3481610ea8565b82525050565b5f602082019050610f4d5f830184610f2b565b92915050565b5f5f60408385031215610f6957610f68610d11565b5b5f610f7685828601610de7565b9250506020610f8785828601610e94565b9150509250929050565b5f5f5f5f60808587031215610fa957610fa8610d11565b5b5f610fb687828801610e94565b9450506020610fc787828801610e94565b9350506040610fd887828801610e94565b9250506060610fe987828801610ec7565b91505092959194509250565b5f60ff82169050919050565b61100a81610ff5565b8114611014575f5ffd5b50565b5f8135905061102581611001565b92915050565b5f602082840312156110405761103f610d11565b5b5f61104d84828501611017565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61109882611056565b6110a28185611060565b93506110b2818560208601611070565b6110bb8161107e565b840191505092915050565b5f6020820190508181035f8301526110de818461108e565b905092915050565b6110ef81610ff5565b82525050565b5f6020820190506111085f8301846110e6565b92915050565b5f8160601b9050919050565b5f6111248261110e565b9050919050565b5f6111358261111a565b9050919050565b61114d61114882610e6d565b61112b565b82525050565b5f819050919050565b61116d61116882610ea8565b611153565b82525050565b5f61117e828661113c565b60148201915061118e828561113c565b60148201915061119e828461115c565b602082019150819050949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61121382610ea8565b915061121e83610ea8565b9250828201905080821115611236576112356111dc565b5b92915050565b5f60408201905061124f5f830185610f2b565b61125c6020830184610f2b565b9392505050565b5f61126d82610ea8565b915061127883610ea8565b92508282039050818111156112905761128f6111dc565b5b92915050565b61129f81610e6d565b82525050565b5f6040820190506112b85f830185611296565b6112c56020830184610e26565b939250505056fe436f6e646974696f6e616c5472616e736665724c696768743a205468652072657175657374206973206e6f7420617070726f766564a264697066735822122037b97360116ec69b2e625d68757383c571efc8b26affda74da34e99c87ee96d864736f6c634300081e0033",
+ "deployedBytecode": "0x608060405234801561000f575f5ffd5b5060043610610135575f3560e01c80638abed32b116100b6578063d4ce14151161007a578063d4ce141514610393578063d547741f146103c3578063dfdc49b9146103df578063e46638e6146103fd578063f02322f01461042d578063f5b541a61461044b57610135565b80638abed32b146102c95780638baf29b4146102f957806391d1485414610315578063a217fddf14610345578063d32c7bb51461036357610135565b80633e5af4ca116100fd5780633e5af4ca146102015780637157797f1461021d5780637d045df61461024d5780637f4ab1dd1461027d57806382580805146102ad57610135565b806301ffc9a714610139578063248a9ca31461016957806325005a41146101995780632f2ff15d146101c957806336568abe146101e5575b5f5ffd5b610153600480360381019061014e9190610d6a565b610469565b6040516101609190610daf565b60405180910390f35b610183600480360381019061017e9190610dfb565b6104e2565b6040516101909190610e35565b60405180910390f35b6101b360048036038101906101ae9190610edb565b6104fe565b6040516101c09190610f3a565b60405180910390f35b6101e360048036038101906101de9190610f53565b610549565b005b6101ff60048036038101906101fa9190610f53565b61056b565b005b61021b60048036038101906102169190610f91565b6105e6565b005b61023760048036038101906102329190610f91565b6105f7565b6040516102449190610daf565b60405180910390f35b6102676004803603810190610262919061102b565b610628565b6040516102749190610daf565b60405180910390f35b6102976004803603810190610292919061102b565b61063a565b6040516102a491906110c6565b60405180910390f35b6102c760048036038101906102c29190610edb565b6106a8565b005b6102e360048036038101906102de9190610dfb565b6107a6565b6040516102f09190610f3a565b60405180910390f35b610313600480360381019061030e9190610edb565b6107bb565b005b61032f600480360381019061032a9190610f53565b6108d8565b60405161033c9190610daf565b60405180910390f35b61034d61093b565b60405161035a9190610e35565b60405180910390f35b61037d60048036038101906103789190610f91565b610941565b60405161038a91906110f5565b60405180910390f35b6103ad60048036038101906103a89190610edb565b610957565b6040516103ba91906110f5565b60405180910390f35b6103dd60048036038101906103d89190610f53565b6109cc565b005b6103e76109ee565b6040516103f491906110f5565b60405180910390f35b61041760048036038101906104129190610edb565b6109f3565b6040516104249190610daf565b60405180910390f35b610435610a22565b6040516104429190610e35565b60405180910390f35b610453610a46565b6040516104609190610e35565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104db57506104da82610a6a565b5b9050919050565b5f5f5f8381526020019081526020015f20600101549050919050565b5f5f84848460405160200161051593929190611173565b60405160208183030381529060405280519060200120905060015f8281526020019081526020015f20549150509392505050565b610552826104e2565b61055b81610ad3565b6105658383610ae7565b50505050565b610573610bd0565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146105d7576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105e18282610bd7565b505050565b6105f18383836107bb565b50505050565b5f5f600681111561060b5761060a6111af565b5b60ff1661061a86868686610941565b60ff16149050949350505050565b5f604760ff168260ff16149050919050565b6060604760ff168260ff160361066a576040518060600160405280603581526020016112cd6035913990506106a3565b6040518060400160405280601881526020017f556e6b6e6f776e207265737472696374696f6e20636f6465000000000000000081525090505b919050565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9296106d281610ad3565b5f8484846040516020016106e893929190611173565b6040516020818303038152906040528051906020012090506001805f8381526020019081526020015f205f8282546107209190611209565b925050819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167feccbdf7c486b88cbffbd8100b22951057ab0de2b73f27f625cc468ccabc3d08a8560015f8681526020019081526020015f205460405161079792919061123c565b60405180910390a35050505050565b6001602052805f5260405f205f915090505481565b5f8383836040516020016107d193929190611173565b6040516020818303038152906040528051906020012090505f60015f8381526020019081526020015f205490505f8103610837576040517ff82ba75a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816108449190611263565b60015f8481526020019081526020015f20819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f8e386ea29f37964fdbdb87193d773dea74e258b0f6108461c88c712051fb27bc8560015f8781526020019081526020015f20546040516108c992919061123c565b60405180910390a35050505050565b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f1b81565b5f61094d848484610957565b9050949350505050565b5f5f84848460405160200161096e93929190611173565b6040516020818303038152906040528051906020012090505f60015f8381526020019081526020015f205490505f81036109ad576047925050506109c5565b5f60068111156109c0576109bf6111af565b5b925050505b9392505050565b6109d5826104e2565b6109de81610ad3565b6109e88383610bd7565b50505050565b604781565b5f5f6006811115610a0757610a066111af565b5b60ff16610a15858585610957565b60ff161490509392505050565b7f5007339590b47d4786f4ab2ef7ffa0ec54bc5fe7244dd97bc6efa6ab3799807b81565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92981565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610ae481610adf610bd0565b610cc0565b50565b5f610af283836108d8565b610bc65760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550610b63610bd0565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050610bca565b5f90505b92915050565b5f33905090565b5f610be283836108d8565b15610cb6575f5f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550610c53610bd0565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050610cba565b5f90505b92915050565b610cca82826108d8565b610d0d5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401610d049291906112a5565b60405180910390fd5b5050565b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610d4981610d15565b8114610d53575f5ffd5b50565b5f81359050610d6481610d40565b92915050565b5f60208284031215610d7f57610d7e610d11565b5b5f610d8c84828501610d56565b91505092915050565b5f8115159050919050565b610da981610d95565b82525050565b5f602082019050610dc25f830184610da0565b92915050565b5f819050919050565b610dda81610dc8565b8114610de4575f5ffd5b50565b5f81359050610df581610dd1565b92915050565b5f60208284031215610e1057610e0f610d11565b5b5f610e1d84828501610de7565b91505092915050565b610e2f81610dc8565b82525050565b5f602082019050610e485f830184610e26565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610e7782610e4e565b9050919050565b610e8781610e6d565b8114610e91575f5ffd5b50565b5f81359050610ea281610e7e565b92915050565b5f819050919050565b610eba81610ea8565b8114610ec4575f5ffd5b50565b5f81359050610ed581610eb1565b92915050565b5f5f5f60608486031215610ef257610ef1610d11565b5b5f610eff86828701610e94565b9350506020610f1086828701610e94565b9250506040610f2186828701610ec7565b9150509250925092565b610f3481610ea8565b82525050565b5f602082019050610f4d5f830184610f2b565b92915050565b5f5f60408385031215610f6957610f68610d11565b5b5f610f7685828601610de7565b9250506020610f8785828601610e94565b9150509250929050565b5f5f5f5f60808587031215610fa957610fa8610d11565b5b5f610fb687828801610e94565b9450506020610fc787828801610e94565b9350506040610fd887828801610e94565b9250506060610fe987828801610ec7565b91505092959194509250565b5f60ff82169050919050565b61100a81610ff5565b8114611014575f5ffd5b50565b5f8135905061102581611001565b92915050565b5f602082840312156110405761103f610d11565b5b5f61104d84828501611017565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61109882611056565b6110a28185611060565b93506110b2818560208601611070565b6110bb8161107e565b840191505092915050565b5f6020820190508181035f8301526110de818461108e565b905092915050565b6110ef81610ff5565b82525050565b5f6020820190506111085f8301846110e6565b92915050565b5f8160601b9050919050565b5f6111248261110e565b9050919050565b5f6111358261111a565b9050919050565b61114d61114882610e6d565b61112b565b82525050565b5f819050919050565b61116d61116882610ea8565b611153565b82525050565b5f61117e828661113c565b60148201915061118e828561113c565b60148201915061119e828461115c565b602082019150819050949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61121382610ea8565b915061121e83610ea8565b9250828201905080821115611236576112356111dc565b5b92915050565b5f60408201905061124f5f830185610f2b565b61125c6020830184610f2b565b9392505050565b5f61126d82610ea8565b915061127883610ea8565b92508282039050818111156112905761128f6111dc565b5b92915050565b61129f81610e6d565b82525050565b5f6040820190506112b85f830185611296565b6112c56020830184610e26565b939250505056fe436f6e646974696f6e616c5472616e736665724c696768743a205468652072657175657374206973206e6f7420617070726f766564a264697066735822122037b97360116ec69b2e625d68757383c571efc8b26affda74da34e99c87ee96d864736f6c634300081e0033",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/operation/RuleOperationRevert.sol/RuleOperationRevert.dbg.json b/doc/compilation/hardhat/src/mocks/rules/operation/RuleOperationRevert.sol/RuleOperationRevert.dbg.json
new file mode 100644
index 0000000..603ee8f
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/operation/RuleOperationRevert.sol/RuleOperationRevert.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/operation/RuleOperationRevert.sol/RuleOperationRevert.json b/doc/compilation/hardhat/src/mocks/rules/operation/RuleOperationRevert.sol/RuleOperationRevert.json
new file mode 100644
index 0000000..3dd23aa
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/operation/RuleOperationRevert.sol/RuleOperationRevert.json
@@ -0,0 +1,469 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleOperationRevert",
+ "sourceName": "src/mocks/rules/operation/RuleOperationRevert.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "AccessControlBadConfirmation",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "neededRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AccessControlUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleConditionalTransferLight_InvalidTransfer",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "previousAdminRole",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "newAdminRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RoleAdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleGranted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleRevoked",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "CODE_TRANSFER_REQUEST_NOT_APPROVED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "DEFAULT_ADMIN_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint8",
+ "name": "restrictionCode",
+ "type": "uint8"
+ }
+ ],
+ "name": "canReturnTransferRestrictionCode",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "isValid",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestrictionFrom",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getRoleAdmin",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "grantRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "hasRole",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "name": "messageForTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "callerConfirmation",
+ "type": "address"
+ }
+ ],
+ "name": "renounceRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "revokeRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes4",
+ "name": "interfaceId",
+ "type": "bytes4"
+ }
+ ],
+ "name": "supportsInterface",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "pure",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x6080604052348015600e575f5ffd5b50610d998061001c5f395ff3fe608060405234801561000f575f5ffd5b50600436106100fe575f3560e01c80638baf29b411610095578063d4ce141511610064578063d4ce1415146102e0578063d547741f14610310578063dfdc49b91461032c578063e46638e61461034a576100fe565b80638baf29b41461024657806391d1485414610262578063a217fddf14610292578063d32c7bb5146102b0576100fe565b80633e5af4ca116100d15780633e5af4ca1461019a5780637157797f146101b65780637d045df6146101e65780637f4ab1dd14610216576100fe565b806301ffc9a714610102578063248a9ca3146101325780632f2ff15d1461016257806336568abe1461017e575b5f5ffd5b61011c60048036038101906101179190610984565b61037a565b60405161012991906109c9565b60405180910390f35b61014c60048036038101906101479190610a15565b6103f3565b6040516101599190610a4f565b60405180910390f35b61017c60048036038101906101779190610ac2565b61040f565b005b61019860048036038101906101939190610ac2565b610431565b005b6101b460048036038101906101af9190610b33565b6104ac565b005b6101d060048036038101906101cb9190610b33565b6104de565b6040516101dd91906109c9565b60405180910390f35b61020060048036038101906101fb9190610bcd565b61050f565b60405161020d91906109c9565b60405180910390f35b610230600480360381019061022b9190610bcd565b610521565b60405161023d9190610c68565b60405180910390f35b610260600480360381019061025b9190610c88565b610560565b005b61027c60048036038101906102779190610ac2565b610592565b60405161028991906109c9565b60405180910390f35b61029a6105f5565b6040516102a79190610a4f565b60405180910390f35b6102ca60048036038101906102c59190610b33565b6105fb565b6040516102d79190610ce7565b60405180910390f35b6102fa60048036038101906102f59190610c88565b610611565b6040516103079190610ce7565b60405180910390f35b61032a60048036038101906103259190610ac2565b61062e565b005b610334610650565b6040516103419190610ce7565b60405180910390f35b610364600480360381019061035f9190610c88565b610655565b60405161037191906109c9565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103ec57506103eb82610684565b5b9050919050565b5f5f5f8381526020019081526020015f20600101549050919050565b610418826103f3565b610421816106ed565b61042b8383610701565b50505050565b6104396107ea565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461049d576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104a782826107f1565b505050565b6040517f15ec568600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f60068111156104f2576104f1610d00565b5b60ff16610501868686866105fb565b60ff16149050949350505050565b5f604760ff168260ff16149050919050565b60606040518060400160405280601881526020017f556e6b6e6f776e207265737472696374696f6e20636f646500000000000000008152509050919050565b6040517f15ec568600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f1b81565b5f610607848484610611565b9050949350505050565b5f5f600681111561062557610624610d00565b5b90509392505050565b610637826103f3565b610640816106ed565b61064a83836107f1565b50505050565b604781565b5f5f600681111561066957610668610d00565b5b60ff16610677858585610611565b60ff161490509392505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6106fe816106f96107ea565b6108da565b50565b5f61070c8383610592565b6107e05760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061077d6107ea565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600190506107e4565b5f90505b92915050565b5f33905090565b5f6107fc8383610592565b156108d0575f5f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061086d6107ea565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a4600190506108d4565b5f90505b92915050565b6108e48282610592565b6109275780826040517fe2517d3f00000000000000000000000000000000000000000000000000000000815260040161091e929190610d3c565b60405180910390fd5b5050565b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6109638161092f565b811461096d575f5ffd5b50565b5f8135905061097e8161095a565b92915050565b5f602082840312156109995761099861092b565b5b5f6109a684828501610970565b91505092915050565b5f8115159050919050565b6109c3816109af565b82525050565b5f6020820190506109dc5f8301846109ba565b92915050565b5f819050919050565b6109f4816109e2565b81146109fe575f5ffd5b50565b5f81359050610a0f816109eb565b92915050565b5f60208284031215610a2a57610a2961092b565b5b5f610a3784828501610a01565b91505092915050565b610a49816109e2565b82525050565b5f602082019050610a625f830184610a40565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610a9182610a68565b9050919050565b610aa181610a87565b8114610aab575f5ffd5b50565b5f81359050610abc81610a98565b92915050565b5f5f60408385031215610ad857610ad761092b565b5b5f610ae585828601610a01565b9250506020610af685828601610aae565b9150509250929050565b5f819050919050565b610b1281610b00565b8114610b1c575f5ffd5b50565b5f81359050610b2d81610b09565b92915050565b5f5f5f5f60808587031215610b4b57610b4a61092b565b5b5f610b5887828801610aae565b9450506020610b6987828801610aae565b9350506040610b7a87828801610aae565b9250506060610b8b87828801610b1f565b91505092959194509250565b5f60ff82169050919050565b610bac81610b97565b8114610bb6575f5ffd5b50565b5f81359050610bc781610ba3565b92915050565b5f60208284031215610be257610be161092b565b5b5f610bef84828501610bb9565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f610c3a82610bf8565b610c448185610c02565b9350610c54818560208601610c12565b610c5d81610c20565b840191505092915050565b5f6020820190508181035f830152610c808184610c30565b905092915050565b5f5f5f60608486031215610c9f57610c9e61092b565b5b5f610cac86828701610aae565b9350506020610cbd86828701610aae565b9250506040610cce86828701610b1f565b9150509250925092565b610ce181610b97565b82525050565b5f602082019050610cfa5f830184610cd8565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b610d3681610a87565b82525050565b5f604082019050610d4f5f830185610d2d565b610d5c6020830184610a40565b939250505056fea26469706673582212209e6a01fafca16b63fb72447553c976985562ee8379b4b404c7ec81afe6659d5264736f6c634300081e0033",
+ "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106100fe575f3560e01c80638baf29b411610095578063d4ce141511610064578063d4ce1415146102e0578063d547741f14610310578063dfdc49b91461032c578063e46638e61461034a576100fe565b80638baf29b41461024657806391d1485414610262578063a217fddf14610292578063d32c7bb5146102b0576100fe565b80633e5af4ca116100d15780633e5af4ca1461019a5780637157797f146101b65780637d045df6146101e65780637f4ab1dd14610216576100fe565b806301ffc9a714610102578063248a9ca3146101325780632f2ff15d1461016257806336568abe1461017e575b5f5ffd5b61011c60048036038101906101179190610984565b61037a565b60405161012991906109c9565b60405180910390f35b61014c60048036038101906101479190610a15565b6103f3565b6040516101599190610a4f565b60405180910390f35b61017c60048036038101906101779190610ac2565b61040f565b005b61019860048036038101906101939190610ac2565b610431565b005b6101b460048036038101906101af9190610b33565b6104ac565b005b6101d060048036038101906101cb9190610b33565b6104de565b6040516101dd91906109c9565b60405180910390f35b61020060048036038101906101fb9190610bcd565b61050f565b60405161020d91906109c9565b60405180910390f35b610230600480360381019061022b9190610bcd565b610521565b60405161023d9190610c68565b60405180910390f35b610260600480360381019061025b9190610c88565b610560565b005b61027c60048036038101906102779190610ac2565b610592565b60405161028991906109c9565b60405180910390f35b61029a6105f5565b6040516102a79190610a4f565b60405180910390f35b6102ca60048036038101906102c59190610b33565b6105fb565b6040516102d79190610ce7565b60405180910390f35b6102fa60048036038101906102f59190610c88565b610611565b6040516103079190610ce7565b60405180910390f35b61032a60048036038101906103259190610ac2565b61062e565b005b610334610650565b6040516103419190610ce7565b60405180910390f35b610364600480360381019061035f9190610c88565b610655565b60405161037191906109c9565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103ec57506103eb82610684565b5b9050919050565b5f5f5f8381526020019081526020015f20600101549050919050565b610418826103f3565b610421816106ed565b61042b8383610701565b50505050565b6104396107ea565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461049d576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104a782826107f1565b505050565b6040517f15ec568600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f60068111156104f2576104f1610d00565b5b60ff16610501868686866105fb565b60ff16149050949350505050565b5f604760ff168260ff16149050919050565b60606040518060400160405280601881526020017f556e6b6e6f776e207265737472696374696f6e20636f646500000000000000008152509050919050565b6040517f15ec568600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f1b81565b5f610607848484610611565b9050949350505050565b5f5f600681111561062557610624610d00565b5b90509392505050565b610637826103f3565b610640816106ed565b61064a83836107f1565b50505050565b604781565b5f5f600681111561066957610668610d00565b5b60ff16610677858585610611565b60ff161490509392505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6106fe816106f96107ea565b6108da565b50565b5f61070c8383610592565b6107e05760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061077d6107ea565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600190506107e4565b5f90505b92915050565b5f33905090565b5f6107fc8383610592565b156108d0575f5f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061086d6107ea565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a4600190506108d4565b5f90505b92915050565b6108e48282610592565b6109275780826040517fe2517d3f00000000000000000000000000000000000000000000000000000000815260040161091e929190610d3c565b60405180910390fd5b5050565b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6109638161092f565b811461096d575f5ffd5b50565b5f8135905061097e8161095a565b92915050565b5f602082840312156109995761099861092b565b5b5f6109a684828501610970565b91505092915050565b5f8115159050919050565b6109c3816109af565b82525050565b5f6020820190506109dc5f8301846109ba565b92915050565b5f819050919050565b6109f4816109e2565b81146109fe575f5ffd5b50565b5f81359050610a0f816109eb565b92915050565b5f60208284031215610a2a57610a2961092b565b5b5f610a3784828501610a01565b91505092915050565b610a49816109e2565b82525050565b5f602082019050610a625f830184610a40565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610a9182610a68565b9050919050565b610aa181610a87565b8114610aab575f5ffd5b50565b5f81359050610abc81610a98565b92915050565b5f5f60408385031215610ad857610ad761092b565b5b5f610ae585828601610a01565b9250506020610af685828601610aae565b9150509250929050565b5f819050919050565b610b1281610b00565b8114610b1c575f5ffd5b50565b5f81359050610b2d81610b09565b92915050565b5f5f5f5f60808587031215610b4b57610b4a61092b565b5b5f610b5887828801610aae565b9450506020610b6987828801610aae565b9350506040610b7a87828801610aae565b9250506060610b8b87828801610b1f565b91505092959194509250565b5f60ff82169050919050565b610bac81610b97565b8114610bb6575f5ffd5b50565b5f81359050610bc781610ba3565b92915050565b5f60208284031215610be257610be161092b565b5b5f610bef84828501610bb9565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f610c3a82610bf8565b610c448185610c02565b9350610c54818560208601610c12565b610c5d81610c20565b840191505092915050565b5f6020820190508181035f830152610c808184610c30565b905092915050565b5f5f5f60608486031215610c9f57610c9e61092b565b5b5f610cac86828701610aae565b9350506020610cbd86828701610aae565b9250506040610cce86828701610b1f565b9150509250925092565b610ce181610b97565b82525050565b5f602082019050610cfa5f830184610cd8565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b610d3681610a87565b82525050565b5f604082019050610d4f5f830185610d2d565b610d5c6020830184610a40565b939250505056fea26469706673582212209e6a01fafca16b63fb72447553c976985562ee8379b4b404c7ec81afe6659d5264736f6c634300081e0033",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/operation/abstract/RuleConditionalTransferLightInvariantStorage.sol/RuleConditionalTransferLightInvariantStorage.dbg.json b/doc/compilation/hardhat/src/mocks/rules/operation/abstract/RuleConditionalTransferLightInvariantStorage.sol/RuleConditionalTransferLightInvariantStorage.dbg.json
new file mode 100644
index 0000000..00f772e
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/operation/abstract/RuleConditionalTransferLightInvariantStorage.sol/RuleConditionalTransferLightInvariantStorage.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/operation/abstract/RuleConditionalTransferLightInvariantStorage.sol/RuleConditionalTransferLightInvariantStorage.json b/doc/compilation/hardhat/src/mocks/rules/operation/abstract/RuleConditionalTransferLightInvariantStorage.sol/RuleConditionalTransferLightInvariantStorage.json
new file mode 100644
index 0000000..249f8f6
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/operation/abstract/RuleConditionalTransferLightInvariantStorage.sol/RuleConditionalTransferLightInvariantStorage.json
@@ -0,0 +1,117 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleConditionalTransferLightInvariantStorage",
+ "sourceName": "src/mocks/rules/operation/abstract/RuleConditionalTransferLightInvariantStorage.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "TransferNotApproved",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "name": "TransferApproved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "remaining",
+ "type": "uint256"
+ }
+ ],
+ "name": "TransferExecuted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "CODE_TRANSFER_REQUEST_NOT_APPROVED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "OPERATOR_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "RULE_ENGINE_CONTRACT_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/RuleWhitelist.sol/RuleWhitelist.dbg.json b/doc/compilation/hardhat/src/mocks/rules/validation/RuleWhitelist.sol/RuleWhitelist.dbg.json
new file mode 100644
index 0000000..603ee8f
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/RuleWhitelist.sol/RuleWhitelist.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/RuleWhitelist.sol/RuleWhitelist.json b/doc/compilation/hardhat/src/mocks/rules/validation/RuleWhitelist.sol/RuleWhitelist.json
new file mode 100644
index 0000000..6a8e028
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/RuleWhitelist.sol/RuleWhitelist.json
@@ -0,0 +1,760 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleWhitelist",
+ "sourceName": "src/mocks/rules/validation/RuleWhitelist.sol",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "admin",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "forwarderIrrevocable",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "inputs": [],
+ "name": "AccessControlBadConfirmation",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "neededRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AccessControlUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleAddressList_AdminWithAddressZeroNotAllowed",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint8",
+ "name": "code",
+ "type": "uint8"
+ }
+ ],
+ "name": "RuleWhitelist_InvalidTransfer",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "Rulelist_AddressAlreadylisted",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "Rulelist_AddressNotPresent",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "targetAddress",
+ "type": "address"
+ }
+ ],
+ "name": "AddAddressToTheList",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address[]",
+ "name": "listTargetAddresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "AddAddressesToTheList",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "targetAddress",
+ "type": "address"
+ }
+ ],
+ "name": "RemoveAddressFromTheList",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address[]",
+ "name": "listTargetAddresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "RemoveAddressesFromTheList",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "previousAdminRole",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "newAdminRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RoleAdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleGranted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleRevoked",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "ADDRESS_LIST_ADD_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "ADDRESS_LIST_REMOVE_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "CODE_ADDRESS_FROM_NOT_WHITELISTED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "CODE_ADDRESS_SPENDER_NOT_WHITELISTED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "CODE_ADDRESS_TO_NOT_WHITELISTED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "DEFAULT_ADMIN_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "targetAddress",
+ "type": "address"
+ }
+ ],
+ "name": "addAddressToTheList",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "listTargetAddresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "addAddressesToTheList",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_targetAddress",
+ "type": "address"
+ }
+ ],
+ "name": "addressIsListed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_targetAddresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "addressIsListedBatch",
+ "outputs": [
+ {
+ "internalType": "bool[]",
+ "name": "",
+ "type": "bool[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint8",
+ "name": "restrictionCode",
+ "type": "uint8"
+ }
+ ],
+ "name": "canReturnTransferRestrictionCode",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "isValid",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestrictionFrom",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getRoleAdmin",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "grantRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "hasRole",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "forwarder",
+ "type": "address"
+ }
+ ],
+ "name": "isTrustedForwarder",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint8",
+ "name": "restrictionCode",
+ "type": "uint8"
+ }
+ ],
+ "name": "messageForTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "numberListedAddress",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "targetAddress",
+ "type": "address"
+ }
+ ],
+ "name": "removeAddressFromTheList",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "listTargetAddresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "removeAddressesFromTheList",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "callerConfirmation",
+ "type": "address"
+ }
+ ],
+ "name": "renounceRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "revokeRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes4",
+ "name": "interfaceId",
+ "type": "bytes4"
+ }
+ ],
+ "name": "supportsInterface",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "trustedForwarder",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x60a060405234801561000f575f5ffd5b506040516125fc3803806125fc833981810160405281019061003191906103da565b818180808073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036100d0576040517f5f1a6c0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6100e25f5f1b836100ec60201b60201c565b50505050506104f9565b5f6100fd83836101e160201b60201c565b6101d75760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061017461021b60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600190506101db565b5f90505b92915050565b5f6101f45f5f1b8361022f60201b60201c565b156102025760019050610215565b610212838361022f60201b60201c565b90505b92915050565b5f61022a61029260201b60201c565b905090565b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f5f36905090505f6102a961030c60201b60201c565b90508082101580156102c657506102c53361032060201b60201c565b5b156102f6575f368284039080926102df93929190610420565b906102ea919061049b565b60601c92505050610309565b61030461036460201b60201c565b925050505b90565b5f61031b61036b60201b60201c565b905090565b5f61032f61037360201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b5f33905090565b5f6014905090565b5f608051905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6103a982610380565b9050919050565b6103b98161039f565b81146103c3575f5ffd5b50565b5f815190506103d4816103b0565b92915050565b5f5f604083850312156103f0576103ef61037c565b5b5f6103fd858286016103c6565b925050602061040e858286016103c6565b9150509250929050565b5f5ffd5b5f5ffd5b5f5f8585111561043357610432610418565b5b838611156104445761044361041c565b5b6001850283019150848603905094509492505050565b5f82905092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b5f82821b905092915050565b5f6104a6838361045a565b826104b18135610464565b925060148210156104f1576104ec7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008360140360080261048f565b831692505b505092915050565b6080516120eb6105115f395f610a1c01526120eb5ff3fe608060405234801561000f575f5ffd5b50600436106101cd575f3560e01c80637d045df611610102578063a217fddf116100a0578063daafd1c71161006f578063daafd1c714610575578063db136dad14610591578063e46638e6146105af578063fa83a2da146105df576101cd565b8063a217fddf146104db578063d32c7bb5146104f9578063d4ce141514610529578063d547741f14610559576101cd565b8063893c1440116100dc578063893c1440146104555780638baf29b41461047157806391d148541461048d578063948b851e146104bd576101cd565b80637d045df6146103d75780637da0a877146104075780637f4ab1dd14610425576101cd565b806336568abe1161016f578063572b6c0511610149578063572b6c05146103295780635b119c0a146103595780635b577f66146103775780637157797f146103a7576101cd565b806336568abe146102d35780633e5af4ca146102ef578063421069171461030b576101cd565b806313be3212116101ab57806313be32121461024d578063248a9ca31461026b5780632f2ff15d1461029b5780633630e2ea146102b7576101cd565b806301ffc9a7146101d15780630a3640d21461020157806311d1c5ca14610231575b5f5ffd5b6101eb60048036038101906101e69190611634565b6105fd565b6040516101f89190611679565b60405180910390f35b61021b6004803603810190610216919061183c565b610676565b604051610228919061193a565b60405180910390f35b61024b600480360381019061024691906119b3565b610730565b005b6102556107a2565b6040516102629190611a16565b60405180910390f35b61028560048036038101906102809190611a62565b6107b0565b6040516102929190611a9c565b60405180910390f35b6102b560048036038101906102b09190611ab5565b6107cc565b005b6102d160048036038101906102cc91906119b3565b6107ee565b005b6102ed60048036038101906102e89190611ab5565b610860565b005b61030960048036038101906103049190611b1d565b6108db565b005b61031361095b565b6040516103209190611b9c565b60405180910390f35b610343600480360381019061033e9190611bb5565b610960565b6040516103509190611679565b60405180910390f35b61036161099e565b60405161036e9190611b9c565b60405180910390f35b610391600480360381019061038c9190611bb5565b6109a3565b60405161039e9190611679565b60405180910390f35b6103c160048036038101906103bc9190611b1d565b6109b4565b6040516103ce9190611679565b60405180910390f35b6103f160048036038101906103ec9190611c0a565b6109e5565b6040516103fe9190611679565b60405180910390f35b61040f610a19565b60405161041c9190611c44565b60405180910390f35b61043f600480360381019061043a9190611c0a565b610a40565b60405161044c9190611cbd565b60405180910390f35b61046f600480360381019061046a9190611bb5565b610b0a565b005b61048b60048036038101906104869190611cdd565b610b78565b005b6104a760048036038101906104a29190611ab5565b610bf6565b6040516104b49190611679565b60405180910390f35b6104c5610c24565b6040516104d29190611a9c565b60405180910390f35b6104e3610c48565b6040516104f09190611a9c565b60405180910390f35b610513600480360381019061050e9190611b1d565b610c4e565b6040516105209190611b9c565b60405180910390f35b610543600480360381019061053e9190611cdd565b610c7b565b6040516105509190611b9c565b60405180910390f35b610573600480360381019061056e9190611ab5565b610cc5565b005b61058f600480360381019061058a9190611bb5565b610ce7565b005b610599610d55565b6040516105a69190611b9c565b60405180910390f35b6105c960048036038101906105c49190611cdd565b610d5a565b6040516105d69190611679565b60405180910390f35b6105e7610d89565b6040516105f49190611a9c565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061066f575061066e82610dad565b5b9050919050565b60605f825167ffffffffffffffff811115610694576106936116a6565b5b6040519080825280602002602001820160405280156106c25781602001602082028036833780820191505090505b5090505f5f90505b8351811015610726576106f68482815181106106e9576106e8611d2d565b5b6020026020010151610e16565b82828151811061070957610708611d2d565b5b6020026020010190151590811515815250508060010190506106ca565b5080915050919050565b7f1b03c849816e077359373cf0a8d6d8f741d643bc1e95273ffe11515f83bebf6161075a81610e68565b6107648383610e7c565b7f9f3dfa145deb5071c94eb9a1393634e982a46367c42dce9622f49213d8f427bd8383604051610795929190611e16565b60405180910390a1505050565b5f6107ab610fa7565b905090565b5f5f5f8381526020019081526020015f20600101549050919050565b6107d5826107b0565b6107de81610e68565b6107e88383610fb0565b50505050565b7f1b94c92b564251ed6b49246d9a82eb7a486b6490f3b3a3bf3b28d2e99801f3ec61081881610e68565b6108228383611099565b7f3be9b663c544556a256ca6ed9f2f6875dba1b09a6eee2571196227f7ec8c621c8383604051610853929190611e16565b60405180910390a1505050565b6108686111c5565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108cc576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108d682826111d3565b505050565b5f6108e885858585610c4e565b90505f60068111156108fd576108fc611e38565b5b60ff168160ff16148484848490919293610950576040517fd9ead46f0000000000000000000000000000000000000000000000000000000081526004016109479493929190611e65565b60405180910390fd5b505050505050505050565b601781565b5f610969610a19565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b601581565b5f6109ad82610e16565b9050919050565b5f5f60068111156109c8576109c7611e38565b5b60ff166109d786868686610c4e565b60ff16149050949350505050565b5f601560ff168260ff161480610a015750601660ff168260ff16145b80610a125750601760ff168260ff16145b9050919050565b5f7f0000000000000000000000000000000000000000000000000000000000000000905090565b6060601560ff168260ff1603610a7057604051806060016040528060228152602001612094602291399050610b05565b601660ff168260ff1603610a9e5760405180606001604052806025815260200161206f602591399050610b05565b601760ff168260ff1603610acc5760405180606001604052806023815260200161204c602391399050610b05565b6040518060400160405280601881526020017f556e6b6e6f776e207265737472696374696f6e20636f6465000000000000000081525090505b919050565b7f1b94c92b564251ed6b49246d9a82eb7a486b6490f3b3a3bf3b28d2e99801f3ec610b3481610e68565b610b3d826112bc565b7fe46e95d98efc7b1a5d9359155b9137734ac3be3f4b32eab0f697558c27f2d99c82604051610b6c9190611c44565b60405180910390a15050565b5f610b84848484610c7b565b90505f6006811115610b9957610b98611e38565b5b60ff168160ff16148484848490919293610bec576040517fd9ead46f000000000000000000000000000000000000000000000000000000008152600401610be39493929190611e65565b60405180910390fd5b5050505050505050565b5f610c035f5f1b836113a8565b15610c115760019050610c1e565b610c1b83836113a8565b90505b92915050565b7f1b03c849816e077359373cf0a8d6d8f741d643bc1e95273ffe11515f83bebf6181565b5f5f1b81565b5f610c58856109a3565b610c655760179050610c73565b610c70848484610c7b565b90505b949350505050565b5f610c85846109a3565b610c925760159050610cbe565b610c9b836109a3565b610ca85760169050610cbe565b5f6006811115610cbb57610cba611e38565b5b90505b9392505050565b610cce826107b0565b610cd781610e68565b610ce183836111d3565b50505050565b7f1b03c849816e077359373cf0a8d6d8f741d643bc1e95273ffe11515f83bebf61610d1181610e68565b610d1a8261140b565b7f7802fa8b90d406b2eb85b620cecde734206f390fa73c61e824384474b734cd9382604051610d499190611c44565b60405180910390a15050565b601681565b5f5f6006811115610d6e57610d6d611e38565b5b60ff16610d7c858585610c7b565b60ff161490509392505050565b7f1b94c92b564251ed6b49246d9a82eb7a486b6490f3b3a3bf3b28d2e99801f3ec81565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f60015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff169050919050565b610e7981610e746111c5565b6114f8565b50565b5f60025490505f5f90505b83839050811015610f9a5760015f858584818110610ea857610ea7611d2d565b5b9050602002016020810190610ebd9190611bb5565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16610f8f576001805f868685818110610f1e57610f1d611d2d565b5b9050602002016020810190610f339190611bb5565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555081610f8c90611ed5565b91505b806001019050610e87565b5080600281905550505050565b5f600254905090565b5f610fbb8383610bf6565b61108f5760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061102c6111c5565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050611093565b5f90505b92915050565b5f60025490505f5f90505b838390508110156111b85760015f8585848181106110c5576110c4611d2d565b5b90506020020160208101906110da9190611bb5565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16156111ad575f60015f86868581811061113c5761113b611d2d565b5b90506020020160208101906111519190611bb5565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550816111aa90611f1c565b91505b8060010190506110a4565b5080600281905550505050565b5f6111ce611549565b905090565b5f6111de8383610bf6565b156112b2575f5f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061124f6111c5565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a4600190506112b6565b5f90505b92915050565b60015f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1661133c576040517fcfc5cc9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555060025f815461139e90611f1c565b9190508190555050565b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b60015f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff161561148c576040517f57845b8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555060025f81546114ee90611ed5565b9190508190555050565b6115028282610bf6565b6115455780826040517fe2517d3f00000000000000000000000000000000000000000000000000000000815260040161153c929190611f43565b60405180910390fd5b5050565b5f5f5f36905090505f61155a6115b1565b9050808210158015611571575061157033610960565b5b156115a1575f3682840390809261158a93929190611f72565b906115959190611fed565b60601c925050506115ae565b6115a96115bf565b925050505b90565b5f6115ba6115c6565b905090565b5f33905090565b5f6014905090565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611613816115df565b811461161d575f5ffd5b50565b5f8135905061162e8161160a565b92915050565b5f60208284031215611649576116486115d7565b5b5f61165684828501611620565b91505092915050565b5f8115159050919050565b6116738161165f565b82525050565b5f60208201905061168c5f83018461166a565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6116dc82611696565b810181811067ffffffffffffffff821117156116fb576116fa6116a6565b5b80604052505050565b5f61170d6115ce565b905061171982826116d3565b919050565b5f67ffffffffffffffff821115611738576117376116a6565b5b602082029050602081019050919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6117768261174d565b9050919050565b6117868161176c565b8114611790575f5ffd5b50565b5f813590506117a18161177d565b92915050565b5f6117b96117b48461171e565b611704565b905080838252602082019050602084028301858111156117dc576117db611749565b5b835b8181101561180557806117f18882611793565b8452602084019350506020810190506117de565b5050509392505050565b5f82601f83011261182357611822611692565b5b81356118338482602086016117a7565b91505092915050565b5f60208284031215611851576118506115d7565b5b5f82013567ffffffffffffffff81111561186e5761186d6115db565b5b61187a8482850161180f565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6118b58161165f565b82525050565b5f6118c683836118ac565b60208301905092915050565b5f602082019050919050565b5f6118e882611883565b6118f2818561188d565b93506118fd8361189d565b805f5b8381101561192d57815161191488826118bb565b975061191f836118d2565b925050600181019050611900565b5085935050505092915050565b5f6020820190508181035f83015261195281846118de565b905092915050565b5f5ffd5b5f5f83601f84011261197357611972611692565b5b8235905067ffffffffffffffff8111156119905761198f61195a565b5b6020830191508360208202830111156119ac576119ab611749565b5b9250929050565b5f5f602083850312156119c9576119c86115d7565b5b5f83013567ffffffffffffffff8111156119e6576119e56115db565b5b6119f28582860161195e565b92509250509250929050565b5f819050919050565b611a10816119fe565b82525050565b5f602082019050611a295f830184611a07565b92915050565b5f819050919050565b611a4181611a2f565b8114611a4b575f5ffd5b50565b5f81359050611a5c81611a38565b92915050565b5f60208284031215611a7757611a766115d7565b5b5f611a8484828501611a4e565b91505092915050565b611a9681611a2f565b82525050565b5f602082019050611aaf5f830184611a8d565b92915050565b5f5f60408385031215611acb57611aca6115d7565b5b5f611ad885828601611a4e565b9250506020611ae985828601611793565b9150509250929050565b611afc816119fe565b8114611b06575f5ffd5b50565b5f81359050611b1781611af3565b92915050565b5f5f5f5f60808587031215611b3557611b346115d7565b5b5f611b4287828801611793565b9450506020611b5387828801611793565b9350506040611b6487828801611793565b9250506060611b7587828801611b09565b91505092959194509250565b5f60ff82169050919050565b611b9681611b81565b82525050565b5f602082019050611baf5f830184611b8d565b92915050565b5f60208284031215611bca57611bc96115d7565b5b5f611bd784828501611793565b91505092915050565b611be981611b81565b8114611bf3575f5ffd5b50565b5f81359050611c0481611be0565b92915050565b5f60208284031215611c1f57611c1e6115d7565b5b5f611c2c84828501611bf6565b91505092915050565b611c3e8161176c565b82525050565b5f602082019050611c575f830184611c35565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f611c8f82611c5d565b611c998185611c67565b9350611ca9818560208601611c77565b611cb281611696565b840191505092915050565b5f6020820190508181035f830152611cd58184611c85565b905092915050565b5f5f5f60608486031215611cf457611cf36115d7565b5b5f611d0186828701611793565b9350506020611d1286828701611793565b9250506040611d2386828701611b09565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82825260208201905092915050565b5f819050919050565b611d7c8161176c565b82525050565b5f611d8d8383611d73565b60208301905092915050565b5f611da76020840184611793565b905092915050565b5f602082019050919050565b5f611dc68385611d5a565b9350611dd182611d6a565b805f5b85811015611e0957611de68284611d99565b611df08882611d82565b9750611dfb83611daf565b925050600181019050611dd4565b5085925050509392505050565b5f6020820190508181035f830152611e2f818486611dbb565b90509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f608082019050611e785f830187611c35565b611e856020830186611c35565b611e926040830185611a07565b611e9f6060830184611b8d565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611edf826119fe565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611f1157611f10611ea8565b5b600182019050919050565b5f611f26826119fe565b91505f8203611f3857611f37611ea8565b5b600182039050919050565b5f604082019050611f565f830185611c35565b611f636020830184611a8d565b9392505050565b5f5ffd5b5f5ffd5b5f5f85851115611f8557611f84611f6a565b5b83861115611f9657611f95611f6e565b5b6001850283019150848603905094509492505050565b5f82905092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b5f82821b905092915050565b5f611ff88383611fac565b826120038135611fb6565b925060148210156120435761203e7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802611fe1565b831692505b50509291505056fe546865207370656e646572206973206e6f7420696e207468652077686974656c69737454686520726563697069656e74206973206e6f7420696e207468652077686974656c6973745468652073656e646572206973206e6f7420696e207468652077686974656c697374a2646970667358221220c5d9366742fb111255ac42ea02b6428161121fb7b40f452a8bf8a4365b3f041364736f6c634300081e0033",
+ "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106101cd575f3560e01c80637d045df611610102578063a217fddf116100a0578063daafd1c71161006f578063daafd1c714610575578063db136dad14610591578063e46638e6146105af578063fa83a2da146105df576101cd565b8063a217fddf146104db578063d32c7bb5146104f9578063d4ce141514610529578063d547741f14610559576101cd565b8063893c1440116100dc578063893c1440146104555780638baf29b41461047157806391d148541461048d578063948b851e146104bd576101cd565b80637d045df6146103d75780637da0a877146104075780637f4ab1dd14610425576101cd565b806336568abe1161016f578063572b6c0511610149578063572b6c05146103295780635b119c0a146103595780635b577f66146103775780637157797f146103a7576101cd565b806336568abe146102d35780633e5af4ca146102ef578063421069171461030b576101cd565b806313be3212116101ab57806313be32121461024d578063248a9ca31461026b5780632f2ff15d1461029b5780633630e2ea146102b7576101cd565b806301ffc9a7146101d15780630a3640d21461020157806311d1c5ca14610231575b5f5ffd5b6101eb60048036038101906101e69190611634565b6105fd565b6040516101f89190611679565b60405180910390f35b61021b6004803603810190610216919061183c565b610676565b604051610228919061193a565b60405180910390f35b61024b600480360381019061024691906119b3565b610730565b005b6102556107a2565b6040516102629190611a16565b60405180910390f35b61028560048036038101906102809190611a62565b6107b0565b6040516102929190611a9c565b60405180910390f35b6102b560048036038101906102b09190611ab5565b6107cc565b005b6102d160048036038101906102cc91906119b3565b6107ee565b005b6102ed60048036038101906102e89190611ab5565b610860565b005b61030960048036038101906103049190611b1d565b6108db565b005b61031361095b565b6040516103209190611b9c565b60405180910390f35b610343600480360381019061033e9190611bb5565b610960565b6040516103509190611679565b60405180910390f35b61036161099e565b60405161036e9190611b9c565b60405180910390f35b610391600480360381019061038c9190611bb5565b6109a3565b60405161039e9190611679565b60405180910390f35b6103c160048036038101906103bc9190611b1d565b6109b4565b6040516103ce9190611679565b60405180910390f35b6103f160048036038101906103ec9190611c0a565b6109e5565b6040516103fe9190611679565b60405180910390f35b61040f610a19565b60405161041c9190611c44565b60405180910390f35b61043f600480360381019061043a9190611c0a565b610a40565b60405161044c9190611cbd565b60405180910390f35b61046f600480360381019061046a9190611bb5565b610b0a565b005b61048b60048036038101906104869190611cdd565b610b78565b005b6104a760048036038101906104a29190611ab5565b610bf6565b6040516104b49190611679565b60405180910390f35b6104c5610c24565b6040516104d29190611a9c565b60405180910390f35b6104e3610c48565b6040516104f09190611a9c565b60405180910390f35b610513600480360381019061050e9190611b1d565b610c4e565b6040516105209190611b9c565b60405180910390f35b610543600480360381019061053e9190611cdd565b610c7b565b6040516105509190611b9c565b60405180910390f35b610573600480360381019061056e9190611ab5565b610cc5565b005b61058f600480360381019061058a9190611bb5565b610ce7565b005b610599610d55565b6040516105a69190611b9c565b60405180910390f35b6105c960048036038101906105c49190611cdd565b610d5a565b6040516105d69190611679565b60405180910390f35b6105e7610d89565b6040516105f49190611a9c565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061066f575061066e82610dad565b5b9050919050565b60605f825167ffffffffffffffff811115610694576106936116a6565b5b6040519080825280602002602001820160405280156106c25781602001602082028036833780820191505090505b5090505f5f90505b8351811015610726576106f68482815181106106e9576106e8611d2d565b5b6020026020010151610e16565b82828151811061070957610708611d2d565b5b6020026020010190151590811515815250508060010190506106ca565b5080915050919050565b7f1b03c849816e077359373cf0a8d6d8f741d643bc1e95273ffe11515f83bebf6161075a81610e68565b6107648383610e7c565b7f9f3dfa145deb5071c94eb9a1393634e982a46367c42dce9622f49213d8f427bd8383604051610795929190611e16565b60405180910390a1505050565b5f6107ab610fa7565b905090565b5f5f5f8381526020019081526020015f20600101549050919050565b6107d5826107b0565b6107de81610e68565b6107e88383610fb0565b50505050565b7f1b94c92b564251ed6b49246d9a82eb7a486b6490f3b3a3bf3b28d2e99801f3ec61081881610e68565b6108228383611099565b7f3be9b663c544556a256ca6ed9f2f6875dba1b09a6eee2571196227f7ec8c621c8383604051610853929190611e16565b60405180910390a1505050565b6108686111c5565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108cc576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108d682826111d3565b505050565b5f6108e885858585610c4e565b90505f60068111156108fd576108fc611e38565b5b60ff168160ff16148484848490919293610950576040517fd9ead46f0000000000000000000000000000000000000000000000000000000081526004016109479493929190611e65565b60405180910390fd5b505050505050505050565b601781565b5f610969610a19565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b601581565b5f6109ad82610e16565b9050919050565b5f5f60068111156109c8576109c7611e38565b5b60ff166109d786868686610c4e565b60ff16149050949350505050565b5f601560ff168260ff161480610a015750601660ff168260ff16145b80610a125750601760ff168260ff16145b9050919050565b5f7f0000000000000000000000000000000000000000000000000000000000000000905090565b6060601560ff168260ff1603610a7057604051806060016040528060228152602001612094602291399050610b05565b601660ff168260ff1603610a9e5760405180606001604052806025815260200161206f602591399050610b05565b601760ff168260ff1603610acc5760405180606001604052806023815260200161204c602391399050610b05565b6040518060400160405280601881526020017f556e6b6e6f776e207265737472696374696f6e20636f6465000000000000000081525090505b919050565b7f1b94c92b564251ed6b49246d9a82eb7a486b6490f3b3a3bf3b28d2e99801f3ec610b3481610e68565b610b3d826112bc565b7fe46e95d98efc7b1a5d9359155b9137734ac3be3f4b32eab0f697558c27f2d99c82604051610b6c9190611c44565b60405180910390a15050565b5f610b84848484610c7b565b90505f6006811115610b9957610b98611e38565b5b60ff168160ff16148484848490919293610bec576040517fd9ead46f000000000000000000000000000000000000000000000000000000008152600401610be39493929190611e65565b60405180910390fd5b5050505050505050565b5f610c035f5f1b836113a8565b15610c115760019050610c1e565b610c1b83836113a8565b90505b92915050565b7f1b03c849816e077359373cf0a8d6d8f741d643bc1e95273ffe11515f83bebf6181565b5f5f1b81565b5f610c58856109a3565b610c655760179050610c73565b610c70848484610c7b565b90505b949350505050565b5f610c85846109a3565b610c925760159050610cbe565b610c9b836109a3565b610ca85760169050610cbe565b5f6006811115610cbb57610cba611e38565b5b90505b9392505050565b610cce826107b0565b610cd781610e68565b610ce183836111d3565b50505050565b7f1b03c849816e077359373cf0a8d6d8f741d643bc1e95273ffe11515f83bebf61610d1181610e68565b610d1a8261140b565b7f7802fa8b90d406b2eb85b620cecde734206f390fa73c61e824384474b734cd9382604051610d499190611c44565b60405180910390a15050565b601681565b5f5f6006811115610d6e57610d6d611e38565b5b60ff16610d7c858585610c7b565b60ff161490509392505050565b7f1b94c92b564251ed6b49246d9a82eb7a486b6490f3b3a3bf3b28d2e99801f3ec81565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f60015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff169050919050565b610e7981610e746111c5565b6114f8565b50565b5f60025490505f5f90505b83839050811015610f9a5760015f858584818110610ea857610ea7611d2d565b5b9050602002016020810190610ebd9190611bb5565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16610f8f576001805f868685818110610f1e57610f1d611d2d565b5b9050602002016020810190610f339190611bb5565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555081610f8c90611ed5565b91505b806001019050610e87565b5080600281905550505050565b5f600254905090565b5f610fbb8383610bf6565b61108f5760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061102c6111c5565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050611093565b5f90505b92915050565b5f60025490505f5f90505b838390508110156111b85760015f8585848181106110c5576110c4611d2d565b5b90506020020160208101906110da9190611bb5565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16156111ad575f60015f86868581811061113c5761113b611d2d565b5b90506020020160208101906111519190611bb5565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550816111aa90611f1c565b91505b8060010190506110a4565b5080600281905550505050565b5f6111ce611549565b905090565b5f6111de8383610bf6565b156112b2575f5f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061124f6111c5565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a4600190506112b6565b5f90505b92915050565b60015f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1661133c576040517fcfc5cc9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555060025f815461139e90611f1c565b9190508190555050565b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b60015f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff161561148c576040517f57845b8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555060025f81546114ee90611ed5565b9190508190555050565b6115028282610bf6565b6115455780826040517fe2517d3f00000000000000000000000000000000000000000000000000000000815260040161153c929190611f43565b60405180910390fd5b5050565b5f5f5f36905090505f61155a6115b1565b9050808210158015611571575061157033610960565b5b156115a1575f3682840390809261158a93929190611f72565b906115959190611fed565b60601c925050506115ae565b6115a96115bf565b925050505b90565b5f6115ba6115c6565b905090565b5f33905090565b5f6014905090565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611613816115df565b811461161d575f5ffd5b50565b5f8135905061162e8161160a565b92915050565b5f60208284031215611649576116486115d7565b5b5f61165684828501611620565b91505092915050565b5f8115159050919050565b6116738161165f565b82525050565b5f60208201905061168c5f83018461166a565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6116dc82611696565b810181811067ffffffffffffffff821117156116fb576116fa6116a6565b5b80604052505050565b5f61170d6115ce565b905061171982826116d3565b919050565b5f67ffffffffffffffff821115611738576117376116a6565b5b602082029050602081019050919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6117768261174d565b9050919050565b6117868161176c565b8114611790575f5ffd5b50565b5f813590506117a18161177d565b92915050565b5f6117b96117b48461171e565b611704565b905080838252602082019050602084028301858111156117dc576117db611749565b5b835b8181101561180557806117f18882611793565b8452602084019350506020810190506117de565b5050509392505050565b5f82601f83011261182357611822611692565b5b81356118338482602086016117a7565b91505092915050565b5f60208284031215611851576118506115d7565b5b5f82013567ffffffffffffffff81111561186e5761186d6115db565b5b61187a8482850161180f565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6118b58161165f565b82525050565b5f6118c683836118ac565b60208301905092915050565b5f602082019050919050565b5f6118e882611883565b6118f2818561188d565b93506118fd8361189d565b805f5b8381101561192d57815161191488826118bb565b975061191f836118d2565b925050600181019050611900565b5085935050505092915050565b5f6020820190508181035f83015261195281846118de565b905092915050565b5f5ffd5b5f5f83601f84011261197357611972611692565b5b8235905067ffffffffffffffff8111156119905761198f61195a565b5b6020830191508360208202830111156119ac576119ab611749565b5b9250929050565b5f5f602083850312156119c9576119c86115d7565b5b5f83013567ffffffffffffffff8111156119e6576119e56115db565b5b6119f28582860161195e565b92509250509250929050565b5f819050919050565b611a10816119fe565b82525050565b5f602082019050611a295f830184611a07565b92915050565b5f819050919050565b611a4181611a2f565b8114611a4b575f5ffd5b50565b5f81359050611a5c81611a38565b92915050565b5f60208284031215611a7757611a766115d7565b5b5f611a8484828501611a4e565b91505092915050565b611a9681611a2f565b82525050565b5f602082019050611aaf5f830184611a8d565b92915050565b5f5f60408385031215611acb57611aca6115d7565b5b5f611ad885828601611a4e565b9250506020611ae985828601611793565b9150509250929050565b611afc816119fe565b8114611b06575f5ffd5b50565b5f81359050611b1781611af3565b92915050565b5f5f5f5f60808587031215611b3557611b346115d7565b5b5f611b4287828801611793565b9450506020611b5387828801611793565b9350506040611b6487828801611793565b9250506060611b7587828801611b09565b91505092959194509250565b5f60ff82169050919050565b611b9681611b81565b82525050565b5f602082019050611baf5f830184611b8d565b92915050565b5f60208284031215611bca57611bc96115d7565b5b5f611bd784828501611793565b91505092915050565b611be981611b81565b8114611bf3575f5ffd5b50565b5f81359050611c0481611be0565b92915050565b5f60208284031215611c1f57611c1e6115d7565b5b5f611c2c84828501611bf6565b91505092915050565b611c3e8161176c565b82525050565b5f602082019050611c575f830184611c35565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f611c8f82611c5d565b611c998185611c67565b9350611ca9818560208601611c77565b611cb281611696565b840191505092915050565b5f6020820190508181035f830152611cd58184611c85565b905092915050565b5f5f5f60608486031215611cf457611cf36115d7565b5b5f611d0186828701611793565b9350506020611d1286828701611793565b9250506040611d2386828701611b09565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82825260208201905092915050565b5f819050919050565b611d7c8161176c565b82525050565b5f611d8d8383611d73565b60208301905092915050565b5f611da76020840184611793565b905092915050565b5f602082019050919050565b5f611dc68385611d5a565b9350611dd182611d6a565b805f5b85811015611e0957611de68284611d99565b611df08882611d82565b9750611dfb83611daf565b925050600181019050611dd4565b5085925050509392505050565b5f6020820190508181035f830152611e2f818486611dbb565b90509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f608082019050611e785f830187611c35565b611e856020830186611c35565b611e926040830185611a07565b611e9f6060830184611b8d565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611edf826119fe565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611f1157611f10611ea8565b5b600182019050919050565b5f611f26826119fe565b91505f8203611f3857611f37611ea8565b5b600182039050919050565b5f604082019050611f565f830185611c35565b611f636020830184611a8d565b9392505050565b5f5ffd5b5f5ffd5b5f5f85851115611f8557611f84611f6a565b5b83861115611f9657611f95611f6e565b5b6001850283019150848603905094509492505050565b5f82905092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b5f82821b905092915050565b5f611ff88383611fac565b826120038135611fb6565b925060148210156120435761203e7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802611fe1565b831692505b50509291505056fe546865207370656e646572206973206e6f7420696e207468652077686974656c69737454686520726563697069656e74206973206e6f7420696e207468652077686974656c6973745468652073656e646572206973206e6f7420696e207468652077686974656c697374a2646970667358221220c5d9366742fb111255ac42ea02b6428161121fb7b40f452a8bf8a4365b3f041364736f6c634300081e0033",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressList.sol/RuleAddressList.dbg.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressList.sol/RuleAddressList.dbg.json
new file mode 100644
index 0000000..c4bdbe7
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressList.sol/RuleAddressList.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressList.sol/RuleAddressList.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressList.sol/RuleAddressList.json
new file mode 100644
index 0000000..22e00ec
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressList.sol/RuleAddressList.json
@@ -0,0 +1,464 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleAddressList",
+ "sourceName": "src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressList.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "AccessControlBadConfirmation",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "neededRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AccessControlUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleAddressList_AdminWithAddressZeroNotAllowed",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "Rulelist_AddressAlreadylisted",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "Rulelist_AddressNotPresent",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "targetAddress",
+ "type": "address"
+ }
+ ],
+ "name": "AddAddressToTheList",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address[]",
+ "name": "listTargetAddresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "AddAddressesToTheList",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "targetAddress",
+ "type": "address"
+ }
+ ],
+ "name": "RemoveAddressFromTheList",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address[]",
+ "name": "listTargetAddresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "RemoveAddressesFromTheList",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "previousAdminRole",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "newAdminRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RoleAdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleGranted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleRevoked",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "ADDRESS_LIST_ADD_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "ADDRESS_LIST_REMOVE_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "DEFAULT_ADMIN_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "targetAddress",
+ "type": "address"
+ }
+ ],
+ "name": "addAddressToTheList",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "listTargetAddresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "addAddressesToTheList",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_targetAddress",
+ "type": "address"
+ }
+ ],
+ "name": "addressIsListed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_targetAddresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "addressIsListedBatch",
+ "outputs": [
+ {
+ "internalType": "bool[]",
+ "name": "",
+ "type": "bool[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getRoleAdmin",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "grantRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "hasRole",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "forwarder",
+ "type": "address"
+ }
+ ],
+ "name": "isTrustedForwarder",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "numberListedAddress",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "targetAddress",
+ "type": "address"
+ }
+ ],
+ "name": "removeAddressFromTheList",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "listTargetAddresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "removeAddressesFromTheList",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "callerConfirmation",
+ "type": "address"
+ }
+ ],
+ "name": "renounceRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "revokeRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes4",
+ "name": "interfaceId",
+ "type": "bytes4"
+ }
+ ],
+ "name": "supportsInterface",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "trustedForwarder",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol/RuleAddressListInternal.dbg.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol/RuleAddressListInternal.dbg.json
new file mode 100644
index 0000000..c4bdbe7
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol/RuleAddressListInternal.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol/RuleAddressListInternal.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol/RuleAddressListInternal.json
new file mode 100644
index 0000000..85304d6
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol/RuleAddressListInternal.json
@@ -0,0 +1,21 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleAddressListInternal",
+ "sourceName": "src/mocks/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "Rulelist_AddressAlreadylisted",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "Rulelist_AddressNotPresent",
+ "type": "error"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol/RuleAddressListInvariantStorage.dbg.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol/RuleAddressListInvariantStorage.dbg.json
new file mode 100644
index 0000000..26657ff
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol/RuleAddressListInvariantStorage.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol/RuleAddressListInvariantStorage.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol/RuleAddressListInvariantStorage.json
new file mode 100644
index 0000000..4d9250d
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol/RuleAddressListInvariantStorage.json
@@ -0,0 +1,94 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleAddressListInvariantStorage",
+ "sourceName": "src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "RuleAddressList_AdminWithAddressZeroNotAllowed",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "targetAddress",
+ "type": "address"
+ }
+ ],
+ "name": "AddAddressToTheList",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address[]",
+ "name": "listTargetAddresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "AddAddressesToTheList",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "targetAddress",
+ "type": "address"
+ }
+ ],
+ "name": "RemoveAddressFromTheList",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address[]",
+ "name": "listTargetAddresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "RemoveAddressesFromTheList",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "ADDRESS_LIST_ADD_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "ADDRESS_LIST_REMOVE_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol/RuleBlacklistInvariantStorage.dbg.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol/RuleBlacklistInvariantStorage.dbg.json
new file mode 100644
index 0000000..26657ff
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol/RuleBlacklistInvariantStorage.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol/RuleBlacklistInvariantStorage.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol/RuleBlacklistInvariantStorage.json
new file mode 100644
index 0000000..4f1de1f
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol/RuleBlacklistInvariantStorage.json
@@ -0,0 +1,50 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleBlacklistInvariantStorage",
+ "sourceName": "src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "CODE_ADDRESS_FROM_IS_BLACKLISTED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "CODE_ADDRESS_SPENDER_IS_BLACKLISTED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "CODE_ADDRESS_TO_IS_BLACKLISTED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol/RuleWhitelistInvariantStorage.dbg.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol/RuleWhitelistInvariantStorage.dbg.json
new file mode 100644
index 0000000..26657ff
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol/RuleWhitelistInvariantStorage.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol/RuleWhitelistInvariantStorage.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol/RuleWhitelistInvariantStorage.json
new file mode 100644
index 0000000..3c24ddf
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol/RuleWhitelistInvariantStorage.json
@@ -0,0 +1,50 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleWhitelistInvariantStorage",
+ "sourceName": "src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "CODE_ADDRESS_FROM_NOT_WHITELISTED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "CODE_ADDRESS_SPENDER_NOT_WHITELISTED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "CODE_ADDRESS_TO_NOT_WHITELISTED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleCommonInvariantStorage.sol/RuleCommonInvariantStorage.dbg.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleCommonInvariantStorage.sol/RuleCommonInvariantStorage.dbg.json
new file mode 100644
index 0000000..00f772e
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleCommonInvariantStorage.sol/RuleCommonInvariantStorage.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleCommonInvariantStorage.sol/RuleCommonInvariantStorage.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleCommonInvariantStorage.sol/RuleCommonInvariantStorage.json
new file mode 100644
index 0000000..6ba6397
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleCommonInvariantStorage.sol/RuleCommonInvariantStorage.json
@@ -0,0 +1,10 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleCommonInvariantStorage",
+ "sourceName": "src/mocks/rules/validation/abstract/RuleCommonInvariantStorage.sol",
+ "abi": [],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleWhitelistCommon.sol/RuleWhitelistCommon.dbg.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleWhitelistCommon.sol/RuleWhitelistCommon.dbg.json
new file mode 100644
index 0000000..00f772e
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleWhitelistCommon.sol/RuleWhitelistCommon.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleWhitelistCommon.sol/RuleWhitelistCommon.json b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleWhitelistCommon.sol/RuleWhitelistCommon.json
new file mode 100644
index 0000000..43733dd
--- /dev/null
+++ b/doc/compilation/hardhat/src/mocks/rules/validation/abstract/RuleWhitelistCommon.sol/RuleWhitelistCommon.json
@@ -0,0 +1,265 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleWhitelistCommon",
+ "sourceName": "src/mocks/rules/validation/abstract/RuleWhitelistCommon.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "CODE_ADDRESS_FROM_NOT_WHITELISTED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "CODE_ADDRESS_SPENDER_NOT_WHITELISTED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "CODE_ADDRESS_TO_NOT_WHITELISTED",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint8",
+ "name": "restrictionCode",
+ "type": "uint8"
+ }
+ ],
+ "name": "canReturnTransferRestrictionCode",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "isValid",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "detectTransferRestrictionFrom",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint8",
+ "name": "restrictionCode",
+ "type": "uint8"
+ }
+ ],
+ "name": "messageForTransferRestriction",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/modules/ERC2771ModuleStandalone.sol/ERC2771ModuleStandalone.dbg.json b/doc/compilation/hardhat/src/modules/ERC2771ModuleStandalone.sol/ERC2771ModuleStandalone.dbg.json
new file mode 100644
index 0000000..30bf738
--- /dev/null
+++ b/doc/compilation/hardhat/src/modules/ERC2771ModuleStandalone.sol/ERC2771ModuleStandalone.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/modules/ERC2771ModuleStandalone.sol/ERC2771ModuleStandalone.json b/doc/compilation/hardhat/src/modules/ERC2771ModuleStandalone.sol/ERC2771ModuleStandalone.json
new file mode 100644
index 0000000..3db37a7
--- /dev/null
+++ b/doc/compilation/hardhat/src/modules/ERC2771ModuleStandalone.sol/ERC2771ModuleStandalone.json
@@ -0,0 +1,43 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "ERC2771ModuleStandalone",
+ "sourceName": "src/modules/ERC2771ModuleStandalone.sol",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "forwarder",
+ "type": "address"
+ }
+ ],
+ "name": "isTrustedForwarder",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "trustedForwarder",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/modules/ERC3643ComplianceModule.sol/ERC3643ComplianceModule.dbg.json b/doc/compilation/hardhat/src/modules/ERC3643ComplianceModule.sol/ERC3643ComplianceModule.dbg.json
new file mode 100644
index 0000000..30bf738
--- /dev/null
+++ b/doc/compilation/hardhat/src/modules/ERC3643ComplianceModule.sol/ERC3643ComplianceModule.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/modules/ERC3643ComplianceModule.sol/ERC3643ComplianceModule.json b/doc/compilation/hardhat/src/modules/ERC3643ComplianceModule.sol/ERC3643ComplianceModule.json
new file mode 100644
index 0000000..021c6e0
--- /dev/null
+++ b/doc/compilation/hardhat/src/modules/ERC3643ComplianceModule.sol/ERC3643ComplianceModule.json
@@ -0,0 +1,459 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "ERC3643ComplianceModule",
+ "sourceName": "src/modules/ERC3643ComplianceModule.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "AccessControlBadConfirmation",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "neededRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AccessControlUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_InvalidTokenAddress",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_OperationNotSuccessful",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_TokenAlreadyBound",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_TokenNotBound",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_ERC3643Compliance_UnauthorizedCaller",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "previousAdminRole",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "newAdminRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RoleAdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleGranted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleRevoked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "TokenBound",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "TokenUnbound",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "COMPLIANCE_MANAGER_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "DEFAULT_ADMIN_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "bindToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "canTransfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "isValid",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "created",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "destroyed",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getRoleAdmin",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTokenBound",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTokenBounds",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "grantRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "hasRole",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "isTokenBound",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "callerConfirmation",
+ "type": "address"
+ }
+ ],
+ "name": "renounceRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "revokeRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes4",
+ "name": "interfaceId",
+ "type": "bytes4"
+ }
+ ],
+ "name": "supportsInterface",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferred",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "unbindToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/modules/RulesManagementModule.sol/RulesManagementModule.dbg.json b/doc/compilation/hardhat/src/modules/RulesManagementModule.sol/RulesManagementModule.dbg.json
new file mode 100644
index 0000000..30bf738
--- /dev/null
+++ b/doc/compilation/hardhat/src/modules/RulesManagementModule.sol/RulesManagementModule.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/modules/RulesManagementModule.sol/RulesManagementModule.json b/doc/compilation/hardhat/src/modules/RulesManagementModule.sol/RulesManagementModule.json
new file mode 100644
index 0000000..3e54488
--- /dev/null
+++ b/doc/compilation/hardhat/src/modules/RulesManagementModule.sol/RulesManagementModule.json
@@ -0,0 +1,416 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RulesManagementModule",
+ "sourceName": "src/modules/RulesManagementModule.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "AccessControlBadConfirmation",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "neededRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AccessControlUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_ArrayIsEmpty",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_OperationNotSuccessful",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_RuleAddressZeroNotAllowed",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_RuleAlreadyExists",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_RuleDoNotMatch",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "contract IRule",
+ "name": "rule",
+ "type": "address"
+ }
+ ],
+ "name": "AddRule",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "ClearRules",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "contract IRule",
+ "name": "rule",
+ "type": "address"
+ }
+ ],
+ "name": "RemoveRule",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "previousAdminRole",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "newAdminRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RoleAdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleGranted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleRevoked",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "DEFAULT_ADMIN_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "RULES_MANAGEMENT_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule",
+ "name": "rule_",
+ "type": "address"
+ }
+ ],
+ "name": "addRule",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "clearRules",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule",
+ "name": "rule_",
+ "type": "address"
+ }
+ ],
+ "name": "containsRule",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getRoleAdmin",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "grantRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "hasRole",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule",
+ "name": "rule_",
+ "type": "address"
+ }
+ ],
+ "name": "removeRule",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "callerConfirmation",
+ "type": "address"
+ }
+ ],
+ "name": "renounceRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "revokeRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "ruleId",
+ "type": "uint256"
+ }
+ ],
+ "name": "rule",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "rules",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "rulesCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract IRule[]",
+ "name": "rules_",
+ "type": "address[]"
+ }
+ ],
+ "name": "setRules",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes4",
+ "name": "interfaceId",
+ "type": "bytes4"
+ }
+ ],
+ "name": "supportsInterface",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/modules/VersionModule.sol/VersionModule.dbg.json b/doc/compilation/hardhat/src/modules/VersionModule.sol/VersionModule.dbg.json
new file mode 100644
index 0000000..30bf738
--- /dev/null
+++ b/doc/compilation/hardhat/src/modules/VersionModule.sol/VersionModule.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/modules/VersionModule.sol/VersionModule.json b/doc/compilation/hardhat/src/modules/VersionModule.sol/VersionModule.json
new file mode 100644
index 0000000..dfa523f
--- /dev/null
+++ b/doc/compilation/hardhat/src/modules/VersionModule.sol/VersionModule.json
@@ -0,0 +1,24 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "VersionModule",
+ "sourceName": "src/modules/VersionModule.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "version_",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/modules/library/RuleEngineInvariantStorage.sol/RuleEngineInvariantStorage.dbg.json b/doc/compilation/hardhat/src/modules/library/RuleEngineInvariantStorage.sol/RuleEngineInvariantStorage.dbg.json
new file mode 100644
index 0000000..cb2dc52
--- /dev/null
+++ b/doc/compilation/hardhat/src/modules/library/RuleEngineInvariantStorage.sol/RuleEngineInvariantStorage.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/modules/library/RuleEngineInvariantStorage.sol/RuleEngineInvariantStorage.json b/doc/compilation/hardhat/src/modules/library/RuleEngineInvariantStorage.sol/RuleEngineInvariantStorage.json
new file mode 100644
index 0000000..6162b92
--- /dev/null
+++ b/doc/compilation/hardhat/src/modules/library/RuleEngineInvariantStorage.sol/RuleEngineInvariantStorage.json
@@ -0,0 +1,16 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RuleEngineInvariantStorage",
+ "sourceName": "src/modules/library/RuleEngineInvariantStorage.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "RuleEngine_AdminWithAddressZeroNotAllowed",
+ "type": "error"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/compilation/hardhat/src/modules/library/RulesManagementModuleInvariantStorage.sol/RulesManagementModuleInvariantStorage.dbg.json b/doc/compilation/hardhat/src/modules/library/RulesManagementModuleInvariantStorage.sol/RulesManagementModuleInvariantStorage.dbg.json
new file mode 100644
index 0000000..cb2dc52
--- /dev/null
+++ b/doc/compilation/hardhat/src/modules/library/RulesManagementModuleInvariantStorage.sol/RulesManagementModuleInvariantStorage.dbg.json
@@ -0,0 +1,4 @@
+{
+ "_format": "hh-sol-dbg-1",
+ "buildInfo": "../../../../build-info/0d8630f2c04bc3d6d290fc92cebd01e5.json"
+}
diff --git a/doc/compilation/hardhat/src/modules/library/RulesManagementModuleInvariantStorage.sol/RulesManagementModuleInvariantStorage.json b/doc/compilation/hardhat/src/modules/library/RulesManagementModuleInvariantStorage.sol/RulesManagementModuleInvariantStorage.json
new file mode 100644
index 0000000..74d32fe
--- /dev/null
+++ b/doc/compilation/hardhat/src/modules/library/RulesManagementModuleInvariantStorage.sol/RulesManagementModuleInvariantStorage.json
@@ -0,0 +1,81 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "RulesManagementModuleInvariantStorage",
+ "sourceName": "src/modules/library/RulesManagementModuleInvariantStorage.sol",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_ArrayIsEmpty",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_OperationNotSuccessful",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_RuleAddressZeroNotAllowed",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_RuleAlreadyExists",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RuleEngine_RulesManagementModule_RuleDoNotMatch",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "contract IRule",
+ "name": "rule",
+ "type": "address"
+ }
+ ],
+ "name": "AddRule",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "ClearRules",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "contract IRule",
+ "name": "rule",
+ "type": "address"
+ }
+ ],
+ "name": "RemoveRule",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "RULES_MANAGEMENT_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x",
+ "deployedBytecode": "0x",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/doc/coverage/code-coverage.png b/doc/coverage/code-coverage.png
new file mode 100644
index 0000000..198329f
Binary files /dev/null and b/doc/coverage/code-coverage.png differ
diff --git a/doc/coverage/coverage/index-sort-b.html b/doc/coverage/coverage/index-sort-b.html
index 79c22e9..840a305 100644
--- a/doc/coverage/coverage/index-sort-b.html
+++ b/doc/coverage/coverage/index-sort-b.html
@@ -31,27 +31,27 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
-
+
+
+
 |
@@ -81,125 +81,29 @@
Functions  |
Branches  |
-
- | script |
-
-
- |
- 0.0 % |
- 0 / 26 |
- 0.0 % |
- 0 / 2 |
- 0.0 % |
- 0 / 2 |
-
-
- | test/RuleConditionalTransfer/utils |
-
-
- |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
- | test/utils |
-
-
- |
- 85.7 % |
- 6 / 7 |
- 80.0 % |
- 4 / 5 |
- - |
- 0 / 0 |
-
-
- | src/rules/validation/abstract |
-
-
- |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 3 / 3 |
- 100.0 % |
- 4 / 4 |
-
-
- | src/rules/validation/abstract/RuleAddressList |
-
-
- |
- 97.8 % |
- 44 / 45 |
- 94.4 % |
- 17 / 18 |
- 100.0 % |
- 6 / 6 |
-
-
- | src |
-
-
- |
- 97.4 % |
- 38 / 39 |
- 88.9 % |
- 8 / 9 |
- 100.0 % |
- 8 / 8 |
-
| src/modules |
|
100.0 % |
- 81 / 81 |
- 100.0 % |
- 27 / 27 |
- 100.0 % |
- 12 / 12 |
-
-
- | src/rules/operation/abstract |
-
-
- |
- 100.0 % |
- 113 / 113 |
- 100.0 % |
- 20 / 20 |
+ 73 / 73 |
100.0 % |
- 31 / 31 |
+ 21 / 21 |
+ 81.5 % |
+ 22 / 27 |
- | src/rules/validation |
-
-
- |
- 97.3 % |
- 72 / 74 |
- 90.9 % |
- 20 / 22 |
- 100.0 % |
- 32 / 32 |
-
-
- | src/rules/operation |
+ src |
-
+
|
- 99.1 % |
- 105 / 106 |
- 94.4 % |
- 17 / 18 |
+ 96.2 % |
+ 50 / 52 |
+ 92.3 % |
+ 12 / 13 |
100.0 % |
- 33 / 33 |
+ 7 / 7 |
diff --git a/doc/coverage/coverage/index-sort-f.html b/doc/coverage/coverage/index-sort-f.html
index 4c104bd..15b6e4d 100644
--- a/doc/coverage/coverage/index-sort-f.html
+++ b/doc/coverage/coverage/index-sort-f.html
@@ -31,27 +31,27 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
-
+
+
+
 |
@@ -81,113 +81,17 @@
Functions  |
Branches  |
-
- | script |
-
-
- |
- 0.0 % |
- 0 / 26 |
- 0.0 % |
- 0 / 2 |
- 0.0 % |
- 0 / 2 |
-
-
- | test/utils |
-
-
- |
- 85.7 % |
- 6 / 7 |
- 80.0 % |
- 4 / 5 |
- - |
- 0 / 0 |
-
| src |
-
- |
- 97.4 % |
- 38 / 39 |
- 88.9 % |
- 8 / 9 |
- 100.0 % |
- 8 / 8 |
-
-
- | src/rules/validation |
-
-
+
|
- 97.3 % |
- 72 / 74 |
- 90.9 % |
- 20 / 22 |
+ 96.2 % |
+ 50 / 52 |
+ 92.3 % |
+ 12 / 13 |
100.0 % |
- 32 / 32 |
-
-
- | src/rules/validation/abstract/RuleAddressList |
-
-
- |
- 97.8 % |
- 44 / 45 |
- 94.4 % |
- 17 / 18 |
- 100.0 % |
- 6 / 6 |
-
-
- | src/rules/operation |
-
-
- |
- 99.1 % |
- 105 / 106 |
- 94.4 % |
- 17 / 18 |
- 100.0 % |
- 33 / 33 |
-
-
- | test/RuleConditionalTransfer/utils |
-
-
- |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
- | src/rules/validation/abstract |
-
-
- |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 3 / 3 |
- 100.0 % |
- 4 / 4 |
-
-
- | src/rules/operation/abstract |
-
-
- |
- 100.0 % |
- 113 / 113 |
- 100.0 % |
- 20 / 20 |
- 100.0 % |
- 31 / 31 |
+ 7 / 7 |
| src/modules |
@@ -195,11 +99,11 @@
100.0 % |
- 81 / 81 |
- 100.0 % |
- 27 / 27 |
+ 73 / 73 |
100.0 % |
- 12 / 12 |
+ 21 / 21 |
+ 81.5 % |
+ 22 / 27 |
diff --git a/doc/coverage/coverage/index-sort-l.html b/doc/coverage/coverage/index-sort-l.html
index f352c82..4273893 100644
--- a/doc/coverage/coverage/index-sort-l.html
+++ b/doc/coverage/coverage/index-sort-l.html
@@ -31,27 +31,27 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
-
+
+
+
 |
@@ -81,101 +81,17 @@
Functions  |
Branches  |
-
- | script |
-
-
- |
- 0.0 % |
- 0 / 26 |
- 0.0 % |
- 0 / 2 |
- 0.0 % |
- 0 / 2 |
-
-
- | test/utils |
-
-
- |
- 85.7 % |
- 6 / 7 |
- 80.0 % |
- 4 / 5 |
- - |
- 0 / 0 |
-
-
- | src/rules/validation |
-
-
- |
- 97.3 % |
- 72 / 74 |
- 90.9 % |
- 20 / 22 |
- 100.0 % |
- 32 / 32 |
-
| src |
-
+
|
- 97.4 % |
- 38 / 39 |
- 88.9 % |
- 8 / 9 |
+ 96.2 % |
+ 50 / 52 |
+ 92.3 % |
+ 12 / 13 |
100.0 % |
- 8 / 8 |
-
-
- | src/rules/validation/abstract/RuleAddressList |
-
-
- |
- 97.8 % |
- 44 / 45 |
- 94.4 % |
- 17 / 18 |
- 100.0 % |
- 6 / 6 |
-
-
- | src/rules/operation |
-
-
- |
- 99.1 % |
- 105 / 106 |
- 94.4 % |
- 17 / 18 |
- 100.0 % |
- 33 / 33 |
-
-
- | src/rules/validation/abstract |
-
-
- |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 3 / 3 |
- 100.0 % |
- 4 / 4 |
-
-
- | test/RuleConditionalTransfer/utils |
-
-
- |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
+ 7 / 7 |
| src/modules |
@@ -183,23 +99,11 @@
100.0 % |
- 81 / 81 |
- 100.0 % |
- 27 / 27 |
- 100.0 % |
- 12 / 12 |
-
-
- | src/rules/operation/abstract |
-
-
- |
- 100.0 % |
- 113 / 113 |
- 100.0 % |
- 20 / 20 |
+ 73 / 73 |
100.0 % |
- 31 / 31 |
+ 21 / 21 |
+ 81.5 % |
+ 22 / 27 |
diff --git a/doc/coverage/coverage/index.html b/doc/coverage/coverage/index.html
index 92f429f..41a2530 100644
--- a/doc/coverage/coverage/index.html
+++ b/doc/coverage/coverage/index.html
@@ -31,27 +31,27 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
-
+
+
+
 |
@@ -81,29 +81,17 @@
Functions  |
Branches  |
-
- | script |
-
-
- |
- 0.0 % |
- 0 / 26 |
- 0.0 % |
- 0 / 2 |
- 0.0 % |
- 0 / 2 |
-
| src |
-
+
|
- 97.4 % |
- 38 / 39 |
- 88.9 % |
- 8 / 9 |
+ 96.2 % |
+ 50 / 52 |
+ 92.3 % |
+ 12 / 13 |
100.0 % |
- 8 / 8 |
+ 7 / 7 |
| src/modules |
@@ -111,95 +99,11 @@
100.0 % |
- 81 / 81 |
- 100.0 % |
- 27 / 27 |
- 100.0 % |
- 12 / 12 |
-
-
- | src/rules/operation |
-
-
- |
- 99.1 % |
- 105 / 106 |
- 94.4 % |
- 17 / 18 |
- 100.0 % |
- 33 / 33 |
-
-
- | src/rules/operation/abstract |
-
-
- |
- 100.0 % |
- 113 / 113 |
- 100.0 % |
- 20 / 20 |
+ 73 / 73 |
100.0 % |
- 31 / 31 |
-
-
- | src/rules/validation |
-
-
- |
- 97.3 % |
- 72 / 74 |
- 90.9 % |
- 20 / 22 |
- 100.0 % |
- 32 / 32 |
-
-
- | src/rules/validation/abstract |
-
-
- |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 3 / 3 |
- 100.0 % |
- 4 / 4 |
-
-
- | src/rules/validation/abstract/RuleAddressList |
-
-
- |
- 97.8 % |
- 44 / 45 |
- 94.4 % |
- 17 / 18 |
- 100.0 % |
- 6 / 6 |
-
-
- | test/RuleConditionalTransfer/utils |
-
-
- |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
- | test/utils |
-
-
- |
- 85.7 % |
- 6 / 7 |
- 80.0 % |
- 4 / 5 |
- - |
- 0 / 0 |
+ 21 / 21 |
+ 81.5 % |
+ 22 / 27 |
diff --git a/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html
deleted file mode 100644
index 9ab57f2..0000000
--- a/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - script/CMTATWithRuleEngineScript.s.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html
deleted file mode 100644
index 6dcfe5d..0000000
--- a/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - script/CMTATWithRuleEngineScript.s.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html
deleted file mode 100644
index 0600472..0000000
--- a/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html
+++ /dev/null
@@ -1,128 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - script/CMTATWithRuleEngineScript.s.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/script/RuleEngineScript.s.sol.func-sort-c.html b/doc/coverage/coverage/script/RuleEngineScript.s.sol.func-sort-c.html
deleted file mode 100644
index 347d446..0000000
--- a/doc/coverage/coverage/script/RuleEngineScript.s.sol.func-sort-c.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - script/RuleEngineScript.s.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/script/RuleEngineScript.s.sol.func.html b/doc/coverage/coverage/script/RuleEngineScript.s.sol.func.html
deleted file mode 100644
index 29ef250..0000000
--- a/doc/coverage/coverage/script/RuleEngineScript.s.sol.func.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - script/RuleEngineScript.s.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/script/RuleEngineScript.s.sol.gcov.html b/doc/coverage/coverage/script/RuleEngineScript.s.sol.gcov.html
deleted file mode 100644
index 3b01d2b..0000000
--- a/doc/coverage/coverage/script/RuleEngineScript.s.sol.gcov.html
+++ /dev/null
@@ -1,121 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - script/RuleEngineScript.s.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/script/index-sort-b.html b/doc/coverage/coverage/script/index-sort-b.html
deleted file mode 100644
index 9a13b3e..0000000
--- a/doc/coverage/coverage/script/index-sort-b.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - script
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/script/index-sort-f.html b/doc/coverage/coverage/script/index-sort-f.html
deleted file mode 100644
index 89cfad4..0000000
--- a/doc/coverage/coverage/script/index-sort-f.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - script
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/script/index-sort-l.html b/doc/coverage/coverage/script/index-sort-l.html
deleted file mode 100644
index 0303269..0000000
--- a/doc/coverage/coverage/script/index-sort-l.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - script
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/script/index.html b/doc/coverage/coverage/script/index.html
deleted file mode 100644
index 11ddb92..0000000
--- a/doc/coverage/coverage/script/index.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - script
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/RuleEngine.sol.func-sort-c.html b/doc/coverage/coverage/src/RuleEngine.sol.func-sort-c.html
index eabf2d9..75b792f 100644
--- a/doc/coverage/coverage/src/RuleEngine.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/RuleEngine.sol.func-sort-c.html
@@ -31,26 +31,26 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
+
+
 |
@@ -69,40 +69,20 @@
Hit count  |
- | RuleEngine._msgData |
+ RuleEngine._msgData |
0 |
- | RuleEngine.validateTransfer |
- 12 |
+ RuleEngine.constructor |
+ 90 |
- | RuleEngine.messageForTransferRestriction |
- 18 |
+ RuleEngine._contextSuffixLength |
+ 300 |
- | RuleEngine.detectTransferRestriction |
- 20 |
-
-
- | RuleEngine.operateOnTransfer |
- 69 |
-
-
- | RuleEngine. |
- 205 |
-
-
- | RuleEngine.hasRole |
- 299 |
-
-
- | RuleEngine._contextSuffixLength |
- 588 |
-
-
- | RuleEngine._msgSender |
- 588 |
+ RuleEngine._msgSender |
+ 300 |
diff --git a/doc/coverage/coverage/src/RuleEngine.sol.func.html b/doc/coverage/coverage/src/RuleEngine.sol.func.html
index f12d35b..20dc8f4 100644
--- a/doc/coverage/coverage/src/RuleEngine.sol.func.html
+++ b/doc/coverage/coverage/src/RuleEngine.sol.func.html
@@ -31,26 +31,26 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
+
+
 |
@@ -69,40 +69,20 @@
Hit count  |
- | RuleEngine. |
- 205 |
+ RuleEngine._contextSuffixLength |
+ 300 |
- | RuleEngine._contextSuffixLength |
- 588 |
-
-
- | RuleEngine._msgData |
+ RuleEngine._msgData |
0 |
- | RuleEngine._msgSender |
- 588 |
-
-
- | RuleEngine.detectTransferRestriction |
- 20 |
-
-
- | RuleEngine.hasRole |
- 299 |
-
-
- | RuleEngine.messageForTransferRestriction |
- 18 |
-
-
- | RuleEngine.operateOnTransfer |
- 69 |
+ RuleEngine._msgSender |
+ 300 |
- | RuleEngine.validateTransfer |
- 12 |
+ RuleEngine.constructor |
+ 90 |
diff --git a/doc/coverage/coverage/src/RuleEngine.sol.gcov.html b/doc/coverage/coverage/src/RuleEngine.sol.gcov.html
index b32d492..3ef64f3 100644
--- a/doc/coverage/coverage/src/RuleEngine.sol.gcov.html
+++ b/doc/coverage/coverage/src/RuleEngine.sol.gcov.html
@@ -31,26 +31,26 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
+
+
 |
@@ -73,204 +73,80 @@
2 : :
3 : : pragma solidity ^0.8.20;
4 : :
- 5 : : import "CMTAT/interfaces/engine/IRuleEngine.sol";
- 6 : : import "./modules/MetaTxModuleStandalone.sol";
- 7 : : import "./modules/RuleEngineOperation.sol";
- 8 : : import "./modules/RuleEngineValidation.sol";
- 9 : :
- 10 : : /**
- 11 : : * @title Implementation of a ruleEngine as defined by the CMTAT
- 12 : : */
- 13 : : contract RuleEngine is
- 14 : : IRuleEngine,
- 15 : : RuleEngineOperation,
- 16 : : RuleEngineValidation,
- 17 : : MetaTxModuleStandalone
- 18 : : {
- 19 : : /**
- 20 : : * @notice
- 21 : : * Get the current version of the smart contract
- 22 : : */
- 23 : : string public constant VERSION = "2.0.4";
- 24 : :
- 25 : : /**
- 26 : : * @param admin Address of the contract (Access Control)
- 27 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- 28 : : */
- 29 : : constructor(
- 30 : : address admin,
- 31 : : address forwarderIrrevocable,
- 32 : : address tokenContract
- 33 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
- 34 [ + ]: 205 : if (admin == address(0)) {
- 35 : 1 : revert RuleEngine_AdminWithAddressZeroNotAllowed();
- 36 : : }
- 37 [ + ]: 204 : if (tokenContract != address(0)) {
- 38 : 86 : _grantRole(TOKEN_CONTRACT_ROLE, tokenContract);
- 39 : : }
- 40 : 204 : _grantRole(DEFAULT_ADMIN_ROLE, admin);
- 41 : : }
- 42 : :
- 43 : : /**
- 44 : : * @notice Go through all the rule to know if a restriction exists on the transfer
- 45 : : * @param _from the origin address
- 46 : : * @param _to the destination address
- 47 : : * @param _amount to transfer
- 48 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- 49 : : **/
- 50 : : function detectTransferRestriction(
- 51 : : address _from,
- 52 : : address _to,
- 53 : : uint256 _amount
- 54 : : ) public view override returns (uint8) {
- 55 : : // Validation
- 56 : 32 : uint8 code = RuleEngineValidation.detectTransferRestrictionValidation(
- 57 : : _from,
- 58 : : _to,
- 59 : : _amount
- 60 : : );
- 61 [ + ]: 32 : if (code != uint8(REJECTED_CODE_BASE.TRANSFER_OK)) {
- 62 : 15 : return code;
- 63 : : }
- 64 : :
- 65 : : // Operation
- 66 : 17 : uint256 rulesLength = _rulesOperation.length;
- 67 : 17 : for (uint256 i = 0; i < rulesLength; ++i) {
- 68 : 12 : uint8 restriction = IRuleValidation(_rulesOperation[i])
- 69 : : .detectTransferRestriction(_from, _to, _amount);
- 70 [ + ]: 12 : if (restriction > 0) {
- 71 : 11 : return restriction;
- 72 : : }
- 73 : : }
- 74 : :
- 75 : 6 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 76 : : }
- 77 : :
- 78 : : /**
- 79 : : * @notice Validate a transfer
- 80 : : * @param _from the origin address
- 81 : : * @param _to the destination address
- 82 : : * @param _amount to transfer
- 83 : : * @return True if the transfer is valid, false otherwise
- 84 : : **/
- 85 : : function validateTransfer(
- 86 : : address _from,
- 87 : : address _to,
- 88 : : uint256 _amount
- 89 : : ) public view override returns (bool) {
- 90 : 12 : return
- 91 : 12 : detectTransferRestriction(_from, _to, _amount) ==
- 92 : : uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 93 : : }
- 94 : :
- 95 : : /**
- 96 : : * @notice Return the message corresponding to the code
- 97 : : * @param _restrictionCode The target restriction code
- 98 : : * @return True if the transfer is valid, false otherwise
- 99 : : **/
- 100 : : function messageForTransferRestriction(
- 101 : : uint8 _restrictionCode
- 102 : : ) external view override returns (string memory) {
- 103 : : // Validation
- 104 : 18 : uint256 rulesLength = _rulesValidation.length;
- 105 : 18 : for (uint256 i = 0; i < rulesLength; ++i) {
- 106 : : if (
- 107 : 13 : IRuleValidation(_rulesValidation[i])
- 108 : : .canReturnTransferRestrictionCode(_restrictionCode)
- 109 [ + ]: 10 : ) {
- 110 : 10 : return
- 111 : 10 : IRuleValidation(_rulesValidation[i])
- 112 : : .messageForTransferRestriction(_restrictionCode);
- 113 : : }
- 114 : : }
- 115 : : // operation
- 116 : 8 : rulesLength = _rulesOperation.length;
- 117 : 8 : for (uint256 i = 0; i < rulesLength; ++i) {
- 118 : : if (
- 119 : 2 : IRuleValidation(_rulesOperation[i])
- 120 : : .canReturnTransferRestrictionCode(_restrictionCode)
- 121 [ + ]: 1 : ) {
- 122 : 1 : return
- 123 : 1 : IRuleValidation(_rulesOperation[i])
- 124 : : .messageForTransferRestriction(_restrictionCode);
- 125 : : }
- 126 : : }
- 127 : 7 : return "Unknown restriction code";
- 128 : : }
- 129 : :
- 130 : : /*
- 131 : : * @notice function protected by access control
- 132 : : */
- 133 : : function operateOnTransfer(
- 134 : : address from,
- 135 : : address to,
- 136 : : uint256 amount
- 137 : : ) external override onlyRole(TOKEN_CONTRACT_ROLE) returns (bool isValid) {
- 138 : : // Validate the transfer
- 139 : : if (
- 140 : 68 : !RuleEngineValidation.validateTransferValidation(from, to, amount)
- 141 [ + ]: 10 : ) {
- 142 : 10 : return false;
- 143 : : }
- 144 : : // Apply operation on RuleEngine
- 145 : 58 : return RuleEngineOperation._operateOnTransfer(from, to, amount);
- 146 : : }
- 147 : :
- 148 : : /* ============ ACCESS CONTROL ============ */
- 149 : : /**
- 150 : : * @dev Returns `true` if `account` has been granted `role`.
- 151 : : */
- 152 : : function hasRole(
- 153 : : bytes32 role,
- 154 : : address account
- 155 : : ) public view virtual override(AccessControl) returns (bool) {
- 156 : : // The Default Admin has all roles
- 157 [ + ]: 597 : if (AccessControl.hasRole(DEFAULT_ADMIN_ROLE, account)) {
- 158 : 220 : return true;
- 159 : : }
- 160 : 377 : return AccessControl.hasRole(role, account);
- 161 : : }
- 162 : :
- 163 : : /*//////////////////////////////////////////////////////////////
- 164 : : ERC-2771
- 165 : : //////////////////////////////////////////////////////////////*/
- 166 : :
- 167 : : /**
- 168 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 169 : : */
- 170 : : function _msgSender()
- 171 : : internal
- 172 : : view
- 173 : : override(ERC2771Context, Context)
- 174 : : returns (address sender)
- 175 : : {
- 176 : 588 : return ERC2771Context._msgSender();
- 177 : : }
- 178 : :
- 179 : : /**
- 180 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 181 : : */
- 182 : : function _msgData()
- 183 : : internal
- 184 : : view
- 185 : : override(ERC2771Context, Context)
- 186 : : returns (bytes calldata)
- 187 : : {
- 188 : 0 : return ERC2771Context._msgData();
- 189 : : }
- 190 : :
- 191 : : /**
- 192 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 193 : : */
- 194 : : function _contextSuffixLength()
- 195 : : internal
- 196 : : view
- 197 : : override(ERC2771Context, Context)
- 198 : : returns (uint256)
- 199 : : {
- 200 : 588 : return ERC2771Context._contextSuffixLength();
- 201 : : }
- 202 : : }
+ 5 : : /* ==== OpenZeppelin === */
+ 6 : : import {Context} from "OZ/utils/Context.sol";
+ 7 : : /* ==== Modules === */
+ 8 : : import {ERC2771ModuleStandalone, ERC2771Context} from "./modules/ERC2771ModuleStandalone.sol";
+ 9 : : /* ==== Base contract === */
+ 10 : : import {RuleEngineBase} from "./RuleEngineBase.sol";
+ 11 : : /**
+ 12 : : * @title Implementation of a ruleEngine as defined by the CMTAT
+ 13 : : */
+ 14 : : contract RuleEngine is
+ 15 : : ERC2771ModuleStandalone,
+ 16 : : RuleEngineBase
+ 17 : : {
+ 18 : : /**
+ 19 : : * @param admin Address of the contract (Access Control)
+ 20 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ 21 : : */
+ 22 : 90 : constructor(
+ 23 : : address admin,
+ 24 : : address forwarderIrrevocable,
+ 25 : : address tokenContract
+ 26 : : ) ERC2771ModuleStandalone(forwarderIrrevocable) {
+ 27 [ + ]: 90 : if (admin == address(0)) {
+ 28 : 1 : revert RuleEngine_AdminWithAddressZeroNotAllowed();
+ 29 : : }
+ 30 [ + ]: 89 : if (tokenContract != address(0)) {
+ 31 : 15 : _bindToken(tokenContract);
+ 32 : : }
+ 33 : 89 : _grantRole(DEFAULT_ADMIN_ROLE, admin);
+ 34 : : }
+ 35 : :
+ 36 : : /*//////////////////////////////////////////////////////////////
+ 37 : : ERC-2771
+ 38 : : //////////////////////////////////////////////////////////////*/
+ 39 : :
+ 40 : : /**
+ 41 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 42 : : */
+ 43 : 300 : function _msgSender()
+ 44 : : internal
+ 45 : : view
+ 46 : : virtual
+ 47 : : override(ERC2771Context, Context)
+ 48 : : returns (address sender)
+ 49 : : {
+ 50 : 300 : return ERC2771Context._msgSender();
+ 51 : : }
+ 52 : :
+ 53 : : /**
+ 54 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 55 : : */
+ 56 : 0 : function _msgData()
+ 57 : : internal
+ 58 : : view
+ 59 : : virtual
+ 60 : : override(ERC2771Context, Context)
+ 61 : : returns (bytes calldata)
+ 62 : : {
+ 63 : 0 : return ERC2771Context._msgData();
+ 64 : : }
+ 65 : :
+ 66 : : /**
+ 67 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 68 : : */
+ 69 : 300 : function _contextSuffixLength()
+ 70 : : internal
+ 71 : : view
+ 72 : : virtual
+ 73 : : override(ERC2771Context, Context)
+ 74 : : returns (uint256)
+ 75 : : {
+ 76 : 300 : return ERC2771Context._contextSuffixLength();
+ 77 : : }
+ 78 : : }
diff --git a/doc/coverage/coverage/src/RuleEngineBase.sol.func-sort-c.html b/doc/coverage/coverage/src/RuleEngineBase.sol.func-sort-c.html
new file mode 100644
index 0000000..e98ecbd
--- /dev/null
+++ b/doc/coverage/coverage/src/RuleEngineBase.sol.func-sort-c.html
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+ LCOV - lcov.info - src/RuleEngineBase.sol - functions
+
+
+
+
+
+
+ | LCOV - code coverage report |
+  |
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+  |
+
+ |
+
+
+  |
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/coverage/coverage/src/RuleEngineBase.sol.func.html b/doc/coverage/coverage/src/RuleEngineBase.sol.func.html
new file mode 100644
index 0000000..8a30502
--- /dev/null
+++ b/doc/coverage/coverage/src/RuleEngineBase.sol.func.html
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+ LCOV - lcov.info - src/RuleEngineBase.sol - functions
+
+
+
+
+
+
+ | LCOV - code coverage report |
+  |
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+  |
+
+ |
+
+
+  |
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html b/doc/coverage/coverage/src/RuleEngineBase.sol.gcov.html
similarity index 55%
rename from doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html
rename to doc/coverage/coverage/src/RuleEngineBase.sol.gcov.html
index 2cd242c..bdd45c3 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html
+++ b/doc/coverage/coverage/src/RuleEngineBase.sol.gcov.html
@@ -4,22 +4,22 @@
- LCOV - lcov.info - src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol
-
+ LCOV - lcov.info - src/RuleEngineBase.sol
+
| LCOV - code coverage report |
-  |
+  |
-
+
|
|
@@ -31,34 +31,34 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
+
+
-  |
+  |
|
-  |
+  |
@@ -73,176 +73,176 @@
2 : :
3 : : pragma solidity ^0.8.20;
4 : :
- 5 : : import "OZ/access/AccessControl.sol";
- 6 : : import "./../../../../modules/MetaTxModuleStandalone.sol";
- 7 : : import "./RuleAddressListInternal.sol";
- 8 : : import "./invariantStorage/RuleAddressListInvariantStorage.sol";
- 9 : :
- 10 : : /**
- 11 : : @title an addresses list manager
- 12 : : */
- 13 : :
- 14 : : abstract contract RuleAddressList is
- 15 : : AccessControl,
- 16 : : MetaTxModuleStandalone,
- 17 : : RuleAddressListInternal,
- 18 : : RuleAddressListInvariantStorage
- 19 : : {
- 20 : : // Number of addresses in the list at the moment
- 21 : : uint256 private numAddressesWhitelisted;
- 22 : :
- 23 : : /**
- 24 : : * @param admin Address of the contract (Access Control)
- 25 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- 26 : : */
- 27 : : constructor(
- 28 : : address admin,
- 29 : : address forwarderIrrevocable
- 30 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
- 31 [ + ]: 185 : if (admin == address(0)) {
- 32 : 1 : revert RuleAddressList_AdminWithAddressZeroNotAllowed();
- 33 : : }
- 34 : 184 : _grantRole(DEFAULT_ADMIN_ROLE, admin);
- 35 : : }
- 36 : :
- 37 : : /**
- 38 : : * @notice Add addresses to the list
- 39 : : * If one of addresses already exist, there is no change for this address. The transaction remains valid (no revert).
- 40 : : * @param listTargetAddresses an array with the addresses to list
- 41 : : */
- 42 : : function addAddressesToTheList(
- 43 : : address[] calldata listTargetAddresses
- 44 : : ) public onlyRole(ADDRESS_LIST_ADD_ROLE) {
- 45 : 16 : _addAddressesToThelist(listTargetAddresses);
- 46 : 16 : emit AddAddressesToTheList(listTargetAddresses);
- 47 : : }
- 48 : :
- 49 : : /**
- 50 : : * @notice Remove addresses from the list
- 51 : : * If the address does not exist in the list, there is no change for this address.
- 52 : : * The transaction remains valid (no revert).
- 53 : : * @param listTargetAddresses an array with the addresses to remove
- 54 : : */
- 55 : : function removeAddressesFromTheList(
- 56 : : address[] calldata listTargetAddresses
- 57 : : ) public onlyRole(ADDRESS_LIST_REMOVE_ROLE) {
- 58 : 3 : _removeAddressesFromThelist(listTargetAddresses);
- 59 : 3 : emit RemoveAddressesFromTheList(listTargetAddresses);
- 60 : : }
- 61 : :
- 62 : : /**
- 63 : : * @notice Add one address to the list
- 64 : : * If the address already exists, the transaction is reverted to save gas.
- 65 : : * @param targetAddress The address to list
- 66 : : */
- 67 : : function addAddressToTheList(
- 68 : : address targetAddress
- 69 : : ) public onlyRole(ADDRESS_LIST_ADD_ROLE) {
- 70 : 51 : _addAddressToThelist(targetAddress);
- 71 : 50 : emit AddAddressToTheList(targetAddress);
- 72 : : }
- 73 : :
- 74 : : /**
- 75 : : * @notice Remove one address from the list
- 76 : : * If the address does not exist in the list, the transaction is reverted to save gas.
- 77 : : * @param targetAddress The address to remove
- 78 : : *
- 79 : : */
- 80 : : function removeAddressFromTheList(
- 81 : : address targetAddress
- 82 : : ) public onlyRole(ADDRESS_LIST_REMOVE_ROLE) {
- 83 : 2 : _removeAddressFromThelist(targetAddress);
- 84 : 1 : emit RemoveAddressFromTheList(targetAddress);
- 85 : : }
- 86 : :
- 87 : : /**
- 88 : : * @notice Get the number of listed addresses
- 89 : : * @return Number of listed addresses
- 90 : : *
- 91 : : */
- 92 : : function numberListedAddress() public view returns (uint256) {
- 93 : 24 : return _numberListedAddress();
- 94 : : }
- 95 : :
- 96 : : /**
- 97 : : * @notice Know if an address is listed or not
- 98 : : * @param _targetAddress The concerned address
- 99 : : * @return True if the address is listed, false otherwise
- 100 : : *
- 101 : : */
- 102 : : function addressIsListed(
- 103 : : address _targetAddress
- 104 : : ) public view returns (bool) {
- 105 : 159 : return _addressIsListed(_targetAddress);
- 106 : : }
- 107 : :
- 108 : : /**
- 109 : : * @notice batch version of {addressIsListed}
- 110 : : *
- 111 : : */
- 112 : : function addressIsListedBatch(
- 113 : : address[] memory _targetAddresses
- 114 : : ) public view returns (bool[] memory) {
- 115 : 28 : bool[] memory isListed = new bool[](_targetAddresses.length);
- 116 : 28 : for (uint256 i = 0; i < _targetAddresses.length; ++i) {
- 117 : 55 : isListed[i] = _addressIsListed(_targetAddresses[i]);
- 118 : : }
- 119 : 28 : return isListed;
- 120 : : }
- 121 : :
- 122 : : /* ============ ACCESS CONTROL ============ */
- 123 : : /**
- 124 : : * @dev Returns `true` if `account` has been granted `role`.
- 125 : : */
- 126 : : function hasRole(
- 127 : : bytes32 role,
- 128 : : address account
- 129 : : ) public view virtual override(AccessControl) returns (bool) {
- 130 : : // The Default Admin has all roles
- 131 [ + ]: 280 : if (AccessControl.hasRole(DEFAULT_ADMIN_ROLE, account)) {
- 132 : 78 : return true;
- 133 : : }
- 134 : 202 : return AccessControl.hasRole(role, account);
- 135 : : }
- 136 : :
- 137 : : /*//////////////////////////////////////////////////////////////
- 138 : : ERC-2771
- 139 : : //////////////////////////////////////////////////////////////*/
- 140 : :
- 141 : : /**
- 142 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 143 : : */
- 144 : : function _msgSender()
- 145 : : internal
- 146 : : view
- 147 : : override(ERC2771Context, Context)
- 148 : : returns (address sender)
- 149 : : {
- 150 : 270 : return ERC2771Context._msgSender();
- 151 : : }
- 152 : :
- 153 : : /**
- 154 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 155 : : */
- 156 : : function _msgData()
- 157 : : internal
- 158 : : view
- 159 : : override(ERC2771Context, Context)
- 160 : : returns (bytes calldata)
- 161 : : {
- 162 : 0 : return ERC2771Context._msgData();
- 163 : : }
- 164 : :
- 165 : : /**
- 166 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 167 : : */
- 168 : : function _contextSuffixLength()
- 169 : : internal
- 170 : : view
- 171 : : override(ERC2771Context, Context)
- 172 : : returns (uint256)
- 173 : : {
- 174 : 270 : return ERC2771Context._contextSuffixLength();
+ 5 : : /* ==== OpenZeppelin === */
+ 6 : : import {AccessControl} from "OZ/access/AccessControl.sol";
+ 7 : : /* ==== CMTAT === */
+ 8 : : import {IRuleEngine}from "CMTAT/interfaces/engine/IRuleEngine.sol";
+ 9 : : import {IERC1404, IERC1404Extend} from "CMTAT/interfaces/tokenization/draft-IERC1404.sol";
+ 10 : : import {IERC3643ComplianceRead, IERC3643IComplianceContract} from "CMTAT/interfaces/tokenization/IERC3643Partial.sol";
+ 11 : : import {IERC7551Compliance} from "CMTAT/interfaces/tokenization/draft-IERC7551.sol";
+ 12 : :
+ 13 : : /* ==== Modules === */
+ 14 : : import {ERC3643ComplianceModule, IERC3643Compliance} from "./modules/ERC3643ComplianceModule.sol";
+ 15 : : import {VersionModule} from "./modules/VersionModule.sol";
+ 16 : : import {RulesManagementModule} from "./modules/RulesManagementModule.sol";
+ 17 : :
+ 18 : : /* ==== Interface and other library === */
+ 19 : : import {IRule} from "./interfaces/IRule.sol";
+ 20 : : import {RuleEngineInvariantStorage} from "./modules/library/RuleEngineInvariantStorage.sol";
+ 21 : : /**
+ 22 : : * @title Implementation of a ruleEngine as defined by the CMTAT
+ 23 : : */
+ 24 : : abstract contract RuleEngineBase is
+ 25 : : VersionModule,
+ 26 : : RulesManagementModule,
+ 27 : : ERC3643ComplianceModule,
+ 28 : : RuleEngineInvariantStorage,
+ 29 : : IRuleEngine
+ 30 : : {
+ 31 : : /* ============ State functions ============ */
+ 32 : : /*
+ 33 : : * @inheritdoc IRuleEngine
+ 34 : : */
+ 35 : 3 : function transferred(
+ 36 : : address spender,
+ 37 : : address from,
+ 38 : : address to,
+ 39 : : uint256 value
+ 40 : : ) public virtual override(IRuleEngine) onlyBoundToken {
+ 41 : : // Apply on RuleEngine
+ 42 : 2 : RulesManagementModule._transferred(spender, from, to, value);
+ 43 : : }
+ 44 : :
+ 45 : : /**
+ 46 : : * @inheritdoc IERC3643IComplianceContract
+ 47 : : */
+ 48 : 9 : function transferred(
+ 49 : : address from,
+ 50 : : address to,
+ 51 : : uint256 value
+ 52 : : ) public virtual override(IERC3643IComplianceContract) onlyBoundToken {
+ 53 : 8 : _transferred(from, to, value);
+ 54 : : }
+ 55 : :
+ 56 : : /// @inheritdoc IERC3643Compliance
+ 57 : 2 : function created(address to, uint256 value) public virtual override(IERC3643Compliance) onlyBoundToken{
+ 58 : 1 : _transferred(address(0), to, value);
+ 59 : : }
+ 60 : :
+ 61 : : /// @inheritdoc IERC3643Compliance
+ 62 : 2 : function destroyed(address from, uint256 value) public virtual override(IERC3643Compliance) onlyBoundToken {
+ 63 : 1 : _transferred(from, address(0), value);
+ 64 : : }
+ 65 : :
+ 66 : :
+ 67 : :
+ 68 : : /* ============ View functions ============ */
+ 69 : : /**
+ 70 : : * @notice Go through all the rule to know if a restriction exists on the transfer
+ 71 : : * @param from the origin address
+ 72 : : * @param to the destination address
+ 73 : : * @param value to transfer
+ 74 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK (0) if the transfer is valid
+ 75 : : **/
+ 76 : 21 : function detectTransferRestriction(
+ 77 : : address from,
+ 78 : : address to,
+ 79 : : uint256 value
+ 80 : : ) public view virtual override returns (uint8) {
+ 81 : 39 : uint256 rulesLength = rulesCount();
+ 82 : 39 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 83 : 39 : uint8 restriction = IRule(rule(i))
+ 84 : : .detectTransferRestriction(from, to, value);
+ 85 [ + ]: 39 : if (restriction > 0) {
+ 86 : 28 : return restriction;
+ 87 : : }
+ 88 : : }
+ 89 : 11 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 90 : : }
+ 91 : :
+ 92 : : /**
+ 93 : : * @inheritdoc IERC1404Extend
+ 94 : : */
+ 95 : 11 : function detectTransferRestrictionFrom(
+ 96 : : address spender,
+ 97 : : address from,
+ 98 : : address to,
+ 99 : : uint256 value
+ 100 : : ) public view virtual override(IERC1404Extend) returns (uint8) {
+ 101 : 25 : uint256 rulesLength = rulesCount();
+ 102 : 25 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 103 : 25 : uint8 restriction = IRule(rule(i))
+ 104 : : .detectTransferRestrictionFrom(spender,from, to, value);
+ 105 [ + ]: 25 : if (restriction > 0) {
+ 106 : 19 : return restriction;
+ 107 : : }
+ 108 : : }
+ 109 : :
+ 110 : 6 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 111 : : }
+ 112 : :
+ 113 : : /**
+ 114 : : * @inheritdoc IERC1404
+ 115 : : */
+ 116 : 13 : function messageForTransferRestriction(
+ 117 : : uint8 restrictionCode
+ 118 : : ) public virtual view override(IERC1404) returns (string memory) {
+ 119 : : //
+ 120 : 13 : uint256 rulesLength = rulesCount();
+ 121 : 13 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 122 : : if (
+ 123 : 10 : IRule(rule(i))
+ 124 : : .canReturnTransferRestrictionCode(restrictionCode)
+ 125 [ + ]: 8 : ) {
+ 126 : 8 : return
+ 127 : 8 : IRule(rule(i))
+ 128 : : .messageForTransferRestriction(restrictionCode);
+ 129 : : }
+ 130 : : }
+ 131 : 5 : return "Unknown restriction code";
+ 132 : : }
+ 133 : :
+ 134 : : /**
+ 135 : : * @inheritdoc IERC3643ComplianceRead
+ 136 : : */
+ 137 : 18 : function canTransfer(
+ 138 : : address from,
+ 139 : : address to,
+ 140 : : uint256 value
+ 141 : : ) public virtual view override(IERC3643ComplianceRead) returns (bool) {
+ 142 : 18 : return
+ 143 : 18 : detectTransferRestriction(from, to, value) ==
+ 144 : : uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 145 : : }
+ 146 : :
+ 147 : : /**
+ 148 : : * @inheritdoc IERC7551Compliance
+ 149 : : */
+ 150 : 14 : function canTransferFrom(
+ 151 : : address spender,
+ 152 : : address from,
+ 153 : : address to,
+ 154 : : uint256 value
+ 155 : : ) public virtual view override(IERC7551Compliance) returns (bool) {
+ 156 : 14 : return
+ 157 : 14 : detectTransferRestrictionFrom(spender, from, to, value) ==
+ 158 : : uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 159 : : }
+ 160 : :
+ 161 : : /* ============ ACCESS CONTROL ============ */
+ 162 : : /**
+ 163 : : * @notice Returns `true` if `account` has been granted `role`.
+ 164 : : * @dev The Default Admin has all roles
+ 165 : : */
+ 166 : 98 : function hasRole(
+ 167 : : bytes32 role,
+ 168 : : address account
+ 169 : : ) public view virtual override(AccessControl) returns (bool) {
+ 170 [ + + ]: 293 : if (AccessControl.hasRole(DEFAULT_ADMIN_ROLE, account)) {
+ 171 : 165 : return true;
+ 172 : : } else {
+ 173 : 128 : return AccessControl.hasRole(role, account);
+ 174 : : }
175 : : }
176 : : }
@@ -252,7 +252,7 @@
diff --git a/doc/coverage/coverage/src/index-sort-b.html b/doc/coverage/coverage/src/index-sort-b.html
index 576ca6d..0f079e8 100644
--- a/doc/coverage/coverage/src/index-sort-b.html
+++ b/doc/coverage/coverage/src/index-sort-b.html
@@ -31,26 +31,26 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
+
+
 |
@@ -84,14 +84,26 @@
| RuleEngine.sol |
-
+
|
- 97.4 % |
- 38 / 39 |
- 88.9 % |
- 8 / 9 |
+ 83.3 % |
+ 10 / 12 |
+ 75.0 % |
+ 3 / 4 |
100.0 % |
- 8 / 8 |
+ 2 / 2 |
+
+
+ | RuleEngineBase.sol |
+
+
+ |
+ 100.0 % |
+ 40 / 40 |
+ 100.0 % |
+ 9 / 9 |
+ 100.0 % |
+ 5 / 5 |
diff --git a/doc/coverage/coverage/src/index-sort-f.html b/doc/coverage/coverage/src/index-sort-f.html
index 8962246..ae9a17d 100644
--- a/doc/coverage/coverage/src/index-sort-f.html
+++ b/doc/coverage/coverage/src/index-sort-f.html
@@ -31,26 +31,26 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
+
+
 |
@@ -84,14 +84,26 @@
| RuleEngine.sol |
-
+
|
- 97.4 % |
- 38 / 39 |
- 88.9 % |
- 8 / 9 |
+ 83.3 % |
+ 10 / 12 |
+ 75.0 % |
+ 3 / 4 |
100.0 % |
- 8 / 8 |
+ 2 / 2 |
+
+
+ | RuleEngineBase.sol |
+
+
+ |
+ 100.0 % |
+ 40 / 40 |
+ 100.0 % |
+ 9 / 9 |
+ 100.0 % |
+ 5 / 5 |
diff --git a/doc/coverage/coverage/src/index-sort-l.html b/doc/coverage/coverage/src/index-sort-l.html
index f6e4883..cb7432b 100644
--- a/doc/coverage/coverage/src/index-sort-l.html
+++ b/doc/coverage/coverage/src/index-sort-l.html
@@ -31,26 +31,26 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
+
+
 |
@@ -84,14 +84,26 @@
| RuleEngine.sol |
-
+
|
- 97.4 % |
- 38 / 39 |
- 88.9 % |
- 8 / 9 |
+ 83.3 % |
+ 10 / 12 |
+ 75.0 % |
+ 3 / 4 |
100.0 % |
- 8 / 8 |
+ 2 / 2 |
+
+
+ | RuleEngineBase.sol |
+
+
+ |
+ 100.0 % |
+ 40 / 40 |
+ 100.0 % |
+ 9 / 9 |
+ 100.0 % |
+ 5 / 5 |
diff --git a/doc/coverage/coverage/src/index.html b/doc/coverage/coverage/src/index.html
index 0762168..2129358 100644
--- a/doc/coverage/coverage/src/index.html
+++ b/doc/coverage/coverage/src/index.html
@@ -31,26 +31,26 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
+
+
 |
@@ -84,14 +84,26 @@
| RuleEngine.sol |
-
+
|
- 97.4 % |
- 38 / 39 |
- 88.9 % |
- 8 / 9 |
+ 83.3 % |
+ 10 / 12 |
+ 75.0 % |
+ 3 / 4 |
100.0 % |
- 8 / 8 |
+ 2 / 2 |
+
+
+ | RuleEngineBase.sol |
+
+
+ |
+ 100.0 % |
+ 40 / 40 |
+ 100.0 % |
+ 9 / 9 |
+ 100.0 % |
+ 5 / 5 |
diff --git a/doc/coverage/coverage/src/modules/RuleInternal.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/ERC3643ComplianceModule.sol.func-sort-c.html
similarity index 56%
rename from doc/coverage/coverage/src/modules/RuleInternal.sol.func-sort-c.html
rename to doc/coverage/coverage/src/modules/ERC3643ComplianceModule.sol.func-sort-c.html
index 7456c15..5bda21a 100644
--- a/doc/coverage/coverage/src/modules/RuleInternal.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/modules/ERC3643ComplianceModule.sol.func-sort-c.html
@@ -4,7 +4,7 @@
- LCOV - lcov.info - src/modules/RuleInternal.sol - functions
+ LCOV - lcov.info - src/modules/ERC3643ComplianceModule.sol - functions
@@ -19,7 +19,7 @@
-
+
|
|
@@ -31,17 +31,17 @@
|
-
-
+
+
-
+
|
-
-
+
+
@@ -49,9 +49,9 @@
|
|
-
-
-
+
+
+
 |
@@ -65,24 +65,40 @@
diff --git a/doc/coverage/coverage/src/modules/RuleInternal.sol.func.html b/doc/coverage/coverage/src/modules/ERC3643ComplianceModule.sol.func.html
similarity index 56%
rename from doc/coverage/coverage/src/modules/RuleInternal.sol.func.html
rename to doc/coverage/coverage/src/modules/ERC3643ComplianceModule.sol.func.html
index 239df15..cc97af1 100644
--- a/doc/coverage/coverage/src/modules/RuleInternal.sol.func.html
+++ b/doc/coverage/coverage/src/modules/ERC3643ComplianceModule.sol.func.html
@@ -4,7 +4,7 @@
- LCOV - lcov.info - src/modules/RuleInternal.sol - functions
+ LCOV - lcov.info - src/modules/ERC3643ComplianceModule.sol - functions
@@ -19,7 +19,7 @@
-
+
|
|
@@ -31,17 +31,17 @@
|
-
-
+
+
-
+
|
-
-
+
+
@@ -49,9 +49,9 @@
|
|
-
-
-
+
+
+
 |
@@ -66,23 +66,39 @@
|
Function Name  |
- Hit count  |
+ Hit count  |
- | RuleInternal._addRule |
- 203 |
+ ERC3643ComplianceModule._bindToken |
+ 26 |
+
+
+ | ERC3643ComplianceModule._unbindToken |
+ 4 |
+
+
+ | ERC3643ComplianceModule.bindToken |
+ 11 |
+
+
+ | ERC3643ComplianceModule.getTokenBound |
+ 2 |
+
+
+ | ERC3643ComplianceModule.getTokenBounds |
+ 2 |
- | RuleInternal._getRuleIndex |
+ ERC3643ComplianceModule.isTokenBound |
6 |
- | RuleInternal._removeRule |
- 55 |
+ ERC3643ComplianceModule.onlyBoundToken |
+ 3 |
- | RuleInternal._setRules |
- 32 |
+ ERC3643ComplianceModule.unbindToken |
+ 4 |
diff --git a/doc/coverage/coverage/src/modules/ERC3643ComplianceModule.sol.gcov.html b/doc/coverage/coverage/src/modules/ERC3643ComplianceModule.sol.gcov.html
new file mode 100644
index 0000000..9f5027e
--- /dev/null
+++ b/doc/coverage/coverage/src/modules/ERC3643ComplianceModule.sol.gcov.html
@@ -0,0 +1,175 @@
+
+
+
+
+
+
+ LCOV - lcov.info - src/modules/ERC3643ComplianceModule.sol
+
+
+
+
+
+
+ | LCOV - code coverage report |
+  |
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+  |
+
+ |
+
+
+  |
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.gcov.html b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.gcov.html
deleted file mode 100644
index 75768bd..0000000
--- a/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.gcov.html
+++ /dev/null
@@ -1,255 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/modules/RuleEngineOperation.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
|
-
-
-
- Branch data Line data Source code
-
- 1 : : // SPDX-License-Identifier: MPL-2.0
- 2 : :
- 3 : : pragma solidity ^0.8.20;
- 4 : :
- 5 : : import "./RuleInternal.sol";
- 6 : : import "../interfaces/IRuleEngineOperation.sol";
- 7 : : import "../interfaces/IRuleOperation.sol";
- 8 : : import "OZ/access/AccessControl.sol";
- 9 : :
- 10 : : /**
- 11 : : * @title Implementation of a ruleEngine defined by the CMTAT
- 12 : : */
- 13 : : abstract contract RuleEngineOperation is
- 14 : : AccessControl,
- 15 : : RuleInternal,
- 16 : : IRuleEngineOperation
- 17 : : {
- 18 : : /// @dev Array of rules
- 19 : : address[] internal _rulesOperation;
- 20 : :
- 21 : : /**
- 22 : : * @notice Set all the rules, will overwrite all the previous rules. \n
- 23 : : * Revert if one rule is a zero address or if the rule is already present
- 24 : : *
- 25 : : */
- 26 : : function setRulesOperation(
- 27 : : address[] calldata rules_
- 28 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
- 29 [ + ]: 11 : if (_rulesOperation.length > 0) {
- 30 : 10 : _clearRulesOperation();
- 31 : : }
- 32 : 11 : _setRules(rules_);
- 33 : 8 : _rulesOperation = rules_;
- 34 : : }
- 35 : :
- 36 : : /**
- 37 : : * @notice Clear all the rules of the array of rules
- 38 : : *
- 39 : : */
- 40 : : function clearRulesOperation() public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
- 41 : 4 : _clearRulesOperation();
- 42 : : }
- 43 : :
- 44 : : /**
- 45 : : * @notice Clear all the rules of the array of rules
- 46 : : *
- 47 : : */
- 48 : : function _clearRulesOperation() internal {
- 49 : 14 : uint256 index;
- 50 : : // we remove the last element first since it is more optimized.
- 51 : 14 : for (uint256 i = _rulesOperation.length; i > 0; --i) {
- 52 : : unchecked {
- 53 : : // don't underflow since i > 0
- 54 : 17 : index = i - 1;
- 55 : : }
- 56 : 17 : _removeRuleOperation(_rulesOperation[index], index);
- 57 : : }
- 58 : 14 : emit ClearRules(_rulesOperation);
- 59 : : }
- 60 : :
- 61 : : /**
- 62 : : * @notice Add a rule to the array of rules
- 63 : : * Revert if one rule is a zero address or if the rule is already present
- 64 : : *
- 65 : : */
- 66 : : function addRuleOperation(
- 67 : : IRuleOperation rule_
- 68 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
- 69 : 85 : RuleInternal._addRule(_rulesOperation, address(rule_));
- 70 : 83 : emit AddRule(address(rule_));
- 71 : : }
- 72 : :
- 73 : : /**
- 74 : : * @notice Remove a rule from the array of rules
- 75 : : * Revert if the rule found at the specified index does not match the rule in argument
- 76 : : * @param rule_ address of the target rule
- 77 : : * @param index the position inside the array of rule
- 78 : : * @dev To reduce the array size, the last rule is moved to the location occupied
- 79 : : * by the rule to remove
- 80 : : *
- 81 : : *
- 82 : : */
- 83 : : function removeRuleOperation(
- 84 : : IRuleOperation rule_,
- 85 : : uint256 index
- 86 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
- 87 : 5 : _removeRuleOperation(address(rule_), index);
- 88 : : }
- 89 : :
- 90 : : /**
- 91 : : * @notice Remove a rule from the array of rules
- 92 : : * Revert if the rule found at the specified index does not match the rule in argument
- 93 : : * @param rule_ address of the target rule
- 94 : : * @param index the position inside the array of rule
- 95 : : * @dev To reduce the array size, the last rule is moved to the location occupied
- 96 : : * by the rule to remove
- 97 : : *
- 98 : : *
- 99 : : */
- 100 : : function _removeRuleOperation(address rule_, uint256 index) internal {
- 101 : 22 : RuleInternal._removeRule(_rulesOperation, rule_, index);
- 102 : 21 : emit RemoveRule(address(rule_));
- 103 : : }
- 104 : :
- 105 : : /**
- 106 : : * @return The number of rules inside the array
- 107 : : */
- 108 : : function rulesCountOperation() external view override returns (uint256) {
- 109 : 41 : return _rulesOperation.length;
- 110 : : }
- 111 : :
- 112 : : /**
- 113 : : * @notice Get the index of a rule inside the list
- 114 : : * @return index if the rule is found, _rulesOperation.length otherwise
- 115 : : */
- 116 : : function getRuleIndexOperation(
- 117 : : IRuleOperation rule_
- 118 : : ) external view returns (uint256 index) {
- 119 : 3 : return RuleInternal._getRuleIndex(_rulesOperation, address(rule_));
- 120 : : }
- 121 : :
- 122 : : /**
- 123 : : * @notice Get the rule at the position specified by ruleId
- 124 : : * @param ruleId index of the rule
- 125 : : * @return a rule address
- 126 : : */
- 127 : : function ruleOperation(
- 128 : : uint256 ruleId
- 129 : : ) external view override returns (address) {
- 130 : 1 : return _rulesOperation[ruleId];
- 131 : : }
- 132 : :
- 133 : : /**
- 134 : : * @notice Get all the rules
- 135 : : * @return An array of rules
- 136 : : */
- 137 : : function rulesOperation()
- 138 : : external
- 139 : : view
- 140 : : override
- 141 : : returns (address[] memory)
- 142 : : {
- 143 : 5 : return _rulesOperation;
- 144 : : }
- 145 : :
- 146 : : /**
- 147 : : * @notice Go through all the rule to know if a restriction exists on the transfer
- 148 : : * @param _from the origin address
- 149 : : * @param _to the destination address
- 150 : : * @param _amount to transfer
- 151 : : **/
- 152 : : function _operateOnTransfer(
- 153 : : address _from,
- 154 : : address _to,
- 155 : : uint256 _amount
- 156 : : ) internal returns (bool isValid) {
- 157 : 58 : uint256 rulesLength = _rulesOperation.length;
- 158 : 58 : for (uint256 i = 0; i < rulesLength; ++i) {
- 159 : 50 : bool result = IRuleOperation(_rulesOperation[i]).operateOnTransfer(
- 160 : : _from,
- 161 : : _to,
- 162 : : _amount
- 163 : : );
- 164 [ + ]: 50 : if (!result) {
- 165 : 24 : return false;
- 166 : : }
- 167 : : }
- 168 : 34 : return true;
- 169 : : }
- 170 : : }
-
- |
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html
deleted file mode 100644
index 3f2eb78..0000000
--- a/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/modules/RuleEngineValidation.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func.html b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func.html
deleted file mode 100644
index 8e114c8..0000000
--- a/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/modules/RuleEngineValidation.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.gcov.html b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.gcov.html
deleted file mode 100644
index 92443af..0000000
--- a/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.gcov.html
+++ /dev/null
@@ -1,147 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/modules/RuleEngineValidation.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
|
-
-
-
- Branch data Line data Source code
-
- 1 : : // SPDX-License-Identifier: MPL-2.0
- 2 : :
- 3 : : pragma solidity ^0.8.20;
- 4 : :
- 5 : : import "OZ/access/AccessControl.sol";
- 6 : : import "./RuleInternal.sol";
- 7 : : import "./RuleEngineValidationCommon.sol";
- 8 : : import "../interfaces/IRuleEngineValidation.sol";
- 9 : : import "../interfaces/IRuleValidation.sol";
- 10 : : import "CMTAT/interfaces/draft-IERC1404/draft-IERC1404EnumCode.sol";
- 11 : :
- 12 : : /**
- 13 : : * @title Implementation of a ruleEngine defined by the CMTAT
- 14 : : */
- 15 : : abstract contract RuleEngineValidation is
- 16 : : AccessControl,
- 17 : : RuleInternal,
- 18 : : RuleEngineValidationCommon,
- 19 : : IRuleEngineValidation,
- 20 : : IERC1404EnumCode
- 21 : : {
- 22 : : /**
- 23 : : * @notice Go through all the rule to know if a restriction exists on the transfer
- 24 : : * @param _from the origin address
- 25 : : * @param _to the destination address
- 26 : : * @param _amount to transfer
- 27 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- 28 : : **/
- 29 : : function detectTransferRestrictionValidation(
- 30 : : address _from,
- 31 : : address _to,
- 32 : : uint256 _amount
- 33 : : ) public view override returns (uint8) {
- 34 : 105 : uint256 rulesLength = _rulesValidation.length;
- 35 : 105 : for (uint256 i = 0; i < rulesLength; ++i) {
- 36 : 43 : uint8 restriction = IRuleValidation(_rulesValidation[i])
- 37 : : .detectTransferRestriction(_from, _to, _amount);
- 38 [ + ]: 43 : if (restriction > 0) {
- 39 : 28 : return restriction;
- 40 : : }
- 41 : : }
- 42 : :
- 43 : 77 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 44 : : }
- 45 : :
- 46 : : /**
- 47 : : * @notice Validate a transfer
- 48 : : * @param _from the origin address
- 49 : : * @param _to the destination address
- 50 : : * @param _amount to transfer
- 51 : : * @return True if the transfer is valid, false otherwise
- 52 : : **/
- 53 : : function validateTransferValidation(
- 54 : : address _from,
- 55 : : address _to,
- 56 : : uint256 _amount
- 57 : : ) public view override returns (bool) {
- 58 : 70 : return
- 59 : 70 : detectTransferRestrictionValidation(_from, _to, _amount) ==
- 60 : : uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 61 : : }
- 62 : : }
-
- |
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html
deleted file mode 100644
index 31de5ea..0000000
--- a/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html
+++ /dev/null
@@ -1,121 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/modules/RuleEngineValidationCommon.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func.html b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func.html
deleted file mode 100644
index d05c663..0000000
--- a/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func.html
+++ /dev/null
@@ -1,121 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/modules/RuleEngineValidationCommon.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html
deleted file mode 100644
index 1c29fc2..0000000
--- a/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html
+++ /dev/null
@@ -1,237 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/modules/RuleEngineValidationCommon.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
|
-
-
-
- Branch data Line data Source code
-
- 1 : : // SPDX-License-Identifier: MPL-2.0
- 2 : :
- 3 : : pragma solidity ^0.8.20;
- 4 : :
- 5 : : import "OZ/access/AccessControl.sol";
- 6 : : import "./RuleInternal.sol";
- 7 : : import "../interfaces/IRuleEngineValidation.sol";
- 8 : : import "../interfaces/IRuleValidation.sol";
- 9 : :
- 10 : : /**
- 11 : : * @title Implementation of a ruleEngine defined by the CMTAT
- 12 : : */
- 13 : : abstract contract RuleEngineValidationCommon is
- 14 : : AccessControl,
- 15 : : RuleInternal,
- 16 : : IRuleEngineValidationCommon
- 17 : : {
- 18 : : /// @dev Array of rules
- 19 : : address[] internal _rulesValidation;
- 20 : :
- 21 : : /*//////////////////////////////////////////////////////////////
- 22 : : PUBLIC/EXTERNAL FUNCTIONS
- 23 : : //////////////////////////////////////////////////////////////*/
- 24 : : /**
- 25 : : * @notice Set all the rules, will overwrite all the previous rules. \n
- 26 : : * Revert if one rule is a zero address or if the rule is already present
- 27 : : * @dev take address[] instead of IRuleEngineValidation[] since it is not possible to cast IRuleEngineValidation[] -> address[]
- 28 : : *
- 29 : : */
- 30 : : function setRulesValidation(
- 31 : : address[] calldata rules_
- 32 : : ) public override onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
- 33 [ + ]: 21 : if (_rulesValidation.length > 0) {
- 34 : 20 : _clearRulesValidation();
- 35 : : }
- 36 : 21 : _setRules(rules_);
- 37 : 18 : _rulesValidation = rules_;
- 38 : : }
- 39 : :
- 40 : : /**
- 41 : : * @notice Clear all the rules of the array of rules
- 42 : : *
- 43 : : */
- 44 : : function clearRulesValidation() public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
- 45 : 5 : _clearRulesValidation();
- 46 : : }
- 47 : :
- 48 : : /**
- 49 : : * @notice Add a rule to the array of rules
- 50 : : * Revert if one rule is a zero address or if the rule is already present
- 51 : : *
- 52 : : */
- 53 : : function addRuleValidation(
- 54 : : IRuleValidation rule_
- 55 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
- 56 : 118 : RuleInternal._addRule(_rulesValidation, address(rule_));
- 57 : 116 : emit AddRule(address(rule_));
- 58 : : }
- 59 : :
- 60 : : /**
- 61 : : * @notice Remove a rule from the array of rules
- 62 : : * Revert if the rule found at the specified index does not match the rule in argument
- 63 : : * @param rule_ address of the target rule
- 64 : : * @param index the position inside the array of rule
- 65 : : * @dev To reduce the array size, the last rule is moved to the location occupied
- 66 : : * by the rule to remove
- 67 : : *
- 68 : : *
- 69 : : */
- 70 : : function removeRuleValidation(
- 71 : : IRuleValidation rule_,
- 72 : : uint256 index
- 73 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
- 74 : 5 : _removeRuleValidation(address(rule_), index);
- 75 : : }
- 76 : :
- 77 : : /**
- 78 : : * @return The number of rules inside the array
- 79 : : */
- 80 : : function rulesCountValidation() external view override returns (uint256) {
- 81 : 69 : return _rulesValidation.length;
- 82 : : }
- 83 : :
- 84 : : /**
- 85 : : * @notice Get the index of a rule inside the list
- 86 : : * @return index if the rule is found, _rulesValidation.length otherwise
- 87 : : */
- 88 : : function getRuleIndexValidation(
- 89 : : IRuleValidation rule_
- 90 : : ) external view returns (uint256 index) {
- 91 : 3 : return RuleInternal._getRuleIndex(_rulesValidation, address(rule_));
- 92 : : }
- 93 : :
- 94 : : /**
- 95 : : * @notice Get the rule at the position specified by ruleId
- 96 : : * @param ruleId index of the rule
- 97 : : * @return a rule address
- 98 : : */
- 99 : : function ruleValidation(
- 100 : : uint256 ruleId
- 101 : : ) external view override returns (address) {
- 102 : 1 : return _rulesValidation[ruleId];
- 103 : : }
- 104 : :
- 105 : : /**
- 106 : : * @notice Get all the rules
- 107 : : * @return An array of rules
- 108 : : */
- 109 : : function rulesValidation()
- 110 : : external
- 111 : : view
- 112 : : override
- 113 : : returns (address[] memory)
- 114 : : {
- 115 : 5 : return _rulesValidation;
- 116 : : }
- 117 : :
- 118 : : /*//////////////////////////////////////////////////////////////
- 119 : : INTERNAL FUNCTIONS
- 120 : : //////////////////////////////////////////////////////////////*/
- 121 : : /**
- 122 : : * @notice Clear all the rules of the array of rules
- 123 : : *
- 124 : : */
- 125 : : function _clearRulesValidation() internal {
- 126 : 25 : uint256 index;
- 127 : : // we remove the last element first since it is more optimized.
- 128 : 25 : for (uint256 i = _rulesValidation.length; i > 0; --i) {
- 129 : : unchecked {
- 130 : : // don't underflow since i > 0
- 131 : 28 : index = i - 1;
- 132 : : }
- 133 : 28 : _removeRuleValidation(_rulesValidation[index], index);
- 134 : : }
- 135 : 25 : emit ClearRules(_rulesValidation);
- 136 : : }
- 137 : :
- 138 : : /**
- 139 : : * @notice Remove a rule from the array of rules
- 140 : : * Revert if the rule found at the specified index does not match the rule in argument
- 141 : : * @param rule_ address of the target rule
- 142 : : * @param index the position inside the array of rule
- 143 : : * @dev To reduce the array size, the last rule is moved to the location occupied
- 144 : : * by the rule to remove
- 145 : : *
- 146 : : *
- 147 : : */
- 148 : : function _removeRuleValidation(address rule_, uint256 index) internal {
- 149 : 33 : RuleInternal._removeRule(_rulesValidation, rule_, index);
- 150 : 32 : emit RemoveRule(address(rule_));
- 151 : : }
- 152 : : }
-
- |
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/modules/RuleInternal.sol.gcov.html b/doc/coverage/coverage/src/modules/RuleInternal.sol.gcov.html
deleted file mode 100644
index cd50bce..0000000
--- a/doc/coverage/coverage/src/modules/RuleInternal.sol.gcov.html
+++ /dev/null
@@ -1,184 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/modules/RuleInternal.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/RulesManagementModule.sol.func-sort-c.html
similarity index 52%
rename from doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html
rename to doc/coverage/coverage/src/modules/RulesManagementModule.sol.func-sort-c.html
index 260f236..ddc2799 100644
--- a/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/modules/RulesManagementModule.sol.func-sort-c.html
@@ -4,7 +4,7 @@
- LCOV - lcov.info - src/modules/RuleEngineOperation.sol - functions
+ LCOV - lcov.info - src/modules/RulesManagementModule.sol - functions
@@ -19,7 +19,7 @@
-
+
|
|
@@ -31,17 +31,17 @@
|
-
-
+
+
-
+
|
-
-
+
+
@@ -49,9 +49,9 @@
|
|
-
-
-
+
+
+
 |
@@ -65,52 +65,56 @@
diff --git a/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func.html b/doc/coverage/coverage/src/modules/RulesManagementModule.sol.func.html
similarity index 52%
rename from doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func.html
rename to doc/coverage/coverage/src/modules/RulesManagementModule.sol.func.html
index 323d585..8aab7fe 100644
--- a/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func.html
+++ b/doc/coverage/coverage/src/modules/RulesManagementModule.sol.func.html
@@ -4,7 +4,7 @@
- LCOV - lcov.info - src/modules/RuleEngineOperation.sol - functions
+ LCOV - lcov.info - src/modules/RulesManagementModule.sol - functions
@@ -19,7 +19,7 @@
-
+
|
|
@@ -31,17 +31,17 @@
|
-
-
+
+
-
+
|
-
-
+
+
@@ -49,9 +49,9 @@
|
|
-
-
-
+
+
+
 |
@@ -66,51 +66,55 @@
|
Function Name  |
- Hit count  |
+ Hit count  |
- | RuleEngineOperation._clearRulesOperation |
- 14 |
+ RulesManagementModule._checkRule |
+ 141 |
- | RuleEngineOperation._operateOnTransfer |
- 58 |
+ RulesManagementModule._clearRules |
+ 36 |
- | RuleEngineOperation._removeRuleOperation |
- 22 |
+ RulesManagementModule._removeRule |
+ 8 |
- | RuleEngineOperation.addRuleOperation |
- 85 |
+ RulesManagementModule._transferred |
+ 12 |
- | RuleEngineOperation.clearRulesOperation |
- 4 |
+ RulesManagementModule.addRule |
+ 95 |
- | RuleEngineOperation.getRuleIndexOperation |
- 3 |
+ RulesManagementModule.clearRules |
+ 10 |
- | RuleEngineOperation.removeRuleOperation |
- 5 |
+ RulesManagementModule.containsRule |
+ 35 |
- | RuleEngineOperation.ruleOperation |
- 1 |
+ RulesManagementModule.removeRule |
+ 11 |
- | RuleEngineOperation.rulesCountOperation |
- 41 |
+ RulesManagementModule.rule |
+ 3 |
- | RuleEngineOperation.rulesOperation |
- 5 |
+ RulesManagementModule.rules |
+ 10 |
- | RuleEngineOperation.setRulesOperation |
- 11 |
+ RulesManagementModule.rulesCount |
+ 115 |
+
+
+ | RulesManagementModule.setRules |
+ 34 |
diff --git a/doc/coverage/coverage/src/modules/RulesManagementModule.sol.gcov.html b/doc/coverage/coverage/src/modules/RulesManagementModule.sol.gcov.html
new file mode 100644
index 0000000..6a77ef4
--- /dev/null
+++ b/doc/coverage/coverage/src/modules/RulesManagementModule.sol.gcov.html
@@ -0,0 +1,295 @@
+
+
+
+
+
+
+ LCOV - lcov.info - src/modules/RulesManagementModule.sol
+
+
+
+
+
+
+ | LCOV - code coverage report |
+  |
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+  |
+
+ |
+
+
+  |
+
+
+
+
+
|
+
+
+
+ Branch data Line data Source code
+
+ 1 : : // SPDX-License-Identifier: MPL-2.0
+ 2 : :
+ 3 : : pragma solidity ^0.8.20;
+ 4 : :
+ 5 : : /* ==== OpenZeppelin === */
+ 6 : : import {EnumerableSet} from "OZ/utils/structs/EnumerableSet.sol";
+ 7 : : import {AccessControl} from "OZ/access/AccessControl.sol";
+ 8 : : /* ==== Interface and other library === */
+ 9 : : import {IRulesManagementModule} from "../interfaces/IRulesManagementModule.sol";
+ 10 : : import {IRule} from "../interfaces/IRule.sol";
+ 11 : : import {RulesManagementModuleInvariantStorage} from "./library/RulesManagementModuleInvariantStorage.sol";
+ 12 : : /**
+ 13 : : * @title RuleEngine - part
+ 14 : : */
+ 15 : : abstract contract RulesManagementModule is
+ 16 : : AccessControl,
+ 17 : : RulesManagementModuleInvariantStorage,
+ 18 : : IRulesManagementModule
+ 19 : : {
+ 20 : : /* ==== Type declaration === */
+ 21 : : using EnumerableSet for EnumerableSet.AddressSet;
+ 22 : :
+ 23 : : /* ==== State Variables === */
+ 24 : : /// @dev Array of rules
+ 25 : : EnumerableSet.AddressSet internal _rules;
+ 26 : :
+ 27 : : /*//////////////////////////////////////////////////////////////
+ 28 : : PUBLIC/EXTERNAL FUNCTIONS
+ 29 : : //////////////////////////////////////////////////////////////*/
+ 30 : :
+ 31 : : /* ============ State functions ============ */
+ 32 : :
+ 33 : : /**
+ 34 : : * @inheritdoc IRulesManagementModule
+ 35 : : */
+ 36 : 34 : function setRules(
+ 37 : : IRule[] calldata rules_
+ 38 : : ) public virtual override(IRulesManagementModule) onlyRole(RULES_MANAGEMENT_ROLE) {
+ 39 [ + ]: 33 : if (rules_.length == 0) {
+ 40 : 4 : revert RuleEngine_RulesManagementModule_ArrayIsEmpty();
+ 41 : : }
+ 42 [ + ]: 29 : if (_rules.length() > 0) {
+ 43 : 27 : _clearRules();
+ 44 : : }
+ 45 : 29 : for(uint256 i = 0; i < rules_.length; ++i){
+ 46 : 47 : _checkRule(address(rules_[i]));
+ 47 : : // Should never revert because we check the presence of the rule before
+ 48 [ # + ]: 45 : require(_rules.add(address(rules_[i])), RuleEngine_RulesManagementModule_OperationNotSuccessful());
+ 49 : 45 : emit AddRule(rules_[i]);
+ 50 : : }
+ 51 : : }
+ 52 : :
+ 53 : : /**
+ 54 : : * @inheritdoc IRulesManagementModule
+ 55 : : */
+ 56 : 10 : function clearRules() public virtual override(IRulesManagementModule) onlyRole(RULES_MANAGEMENT_ROLE) {
+ 57 : 9 : _clearRules();
+ 58 : : }
+ 59 : :
+ 60 : : /**
+ 61 : : * @inheritdoc IRulesManagementModule
+ 62 : : */
+ 63 : 95 : function addRule(
+ 64 : : IRule rule_
+ 65 : : ) public virtual override(IRulesManagementModule) onlyRole(RULES_MANAGEMENT_ROLE) {
+ 66 : 94 : _checkRule(address(rule_));
+ 67 [ # + ]: 90 : require(_rules.add(address(rule_)), RuleEngine_RulesManagementModule_OperationNotSuccessful());
+ 68 : 90 : emit AddRule(rule_);
+ 69 : : }
+ 70 : :
+ 71 : : /**
+ 72 : : * @inheritdoc IRulesManagementModule
+ 73 : : */
+ 74 : 11 : function removeRule(
+ 75 : : IRule rule_
+ 76 : : ) public virtual override(IRulesManagementModule) onlyRole(RULES_MANAGEMENT_ROLE) {
+ 77 [ + + ]: 10 : require(_rules.contains(address(rule_)), RuleEngine_RulesManagementModule_RuleDoNotMatch());
+ 78 : 8 : _removeRule(rule_);
+ 79 : : }
+ 80 : :
+ 81 : : /* ============ View functions ============ */
+ 82 : :
+ 83 : : /**
+ 84 : : * @inheritdoc IRulesManagementModule
+ 85 : : */
+ 86 : 115 : function rulesCount() public view virtual override(IRulesManagementModule) returns (uint256) {
+ 87 : 192 : return _rules.length();
+ 88 : : }
+ 89 : :
+ 90 : : /**
+ 91 : : * @inheritdoc IRulesManagementModule
+ 92 : : */
+ 93 : 35 : function containsRule(IRule rule_) public view virtual override(IRulesManagementModule) returns (bool){
+ 94 : 35 : return _rules.contains(address(rule_));
+ 95 : : }
+ 96 : :
+ 97 : :
+ 98 : : /**
+ 99 : : * @inheritdoc IRulesManagementModule
+ 100 : : */
+ 101 : 3 : function rule(
+ 102 : : uint256 ruleId
+ 103 : : ) public view virtual override(IRulesManagementModule) returns (address) {
+ 104 [ + + ]: 85 : if(ruleId < _rules.length()){
+ 105 : : // Note that there are no guarantees on the ordering of values inside the array,
+ 106 : : // and it may change when more values are added or removed.
+ 107 : 84 : return _rules.at(ruleId);
+ 108 : : } else {
+ 109 : 1 : return address(0);
+ 110 : : }
+ 111 : : }
+ 112 : :
+ 113 : : /**
+ 114 : : * @inheritdoc IRulesManagementModule
+ 115 : : */
+ 116 : 10 : function rules()
+ 117 : : public
+ 118 : : view
+ 119 : : virtual
+ 120 : : override(IRulesManagementModule)
+ 121 : : returns (address[] memory)
+ 122 : : {
+ 123 : 10 : return _rules.values();
+ 124 : : }
+ 125 : :
+ 126 : : /*//////////////////////////////////////////////////////////////
+ 127 : : INTERNAL/PRIVATE FUNCTIONS
+ 128 : : //////////////////////////////////////////////////////////////*/
+ 129 : : /**
+ 130 : : * @notice Clear all the rules of the array of rules
+ 131 : : *
+ 132 : : */
+ 133 : 36 : function _clearRules() internal virtual {
+ 134 : 36 : emit ClearRules();
+ 135 : 36 : _rules.clear();
+ 136 : : }
+ 137 : :
+ 138 : : /**
+ 139 : : * @notice Remove a rule from the array of rules
+ 140 : : * Revert if the rule found at the specified index does not match the rule in argument
+ 141 : : * @param rule_ address of the target rule
+ 142 : : *
+ 143 : : *
+ 144 : : */
+ 145 : 8 : function _removeRule(IRule rule_) internal virtual {
+ 146 : : // Should never revert because we check the presence of the rule before
+ 147 [ # + ]: 8 : require(_rules.remove(address(rule_)), RuleEngine_RulesManagementModule_OperationNotSuccessful());
+ 148 : 8 : emit RemoveRule(rule_);
+ 149 : : }
+ 150 : :
+ 151 : : /**
+ 152 : : * @dev check if a rule is valid, revert otherwise
+ 153 : : */
+ 154 : 141 : function _checkRule(address rule_) internal view{
+ 155 [ + ]: 141 : if (rule_ == address(0x0)) {
+ 156 : 2 : revert RuleEngine_RulesManagementModule_RuleAddressZeroNotAllowed();
+ 157 : : }
+ 158 [ + ]: 139 : if (_rules.contains(rule_)) {
+ 159 : 4 : revert RuleEngine_RulesManagementModule_RuleAlreadyExists();
+ 160 : : }
+ 161 : : }
+ 162 : :
+ 163 : :
+ 164 : : /* ============ Transferred functions ============ */
+ 165 : :
+ 166 : : /**
+ 167 : : * @notice Go through all the rule to know if a restriction exists on the transfer
+ 168 : : * @param from the origin address
+ 169 : : * @param to the destination address
+ 170 : : * @param value to transfer
+ 171 : : **/
+ 172 : 10 : function _transferred(
+ 173 : : address from,
+ 174 : : address to,
+ 175 : : uint256 value
+ 176 : : ) internal virtual{
+ 177 : 10 : uint256 rulesLength = _rules.length();
+ 178 : 10 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 179 : 7 : IRule(_rules.at(i)).transferred(
+ 180 : : from,
+ 181 : : to,
+ 182 : : value
+ 183 : : );
+ 184 : : }
+ 185 : : }
+ 186 : :
+ 187 : : /**
+ 188 : : * @notice Go through all the rule to know if a restriction exists on the transfer
+ 189 : : * @param spender the spender address (transferFrom)
+ 190 : : * @param from the origin address
+ 191 : : * @param to the destination address
+ 192 : : * @param value to transfer
+ 193 : : **/
+ 194 : 2 : function _transferred(
+ 195 : : address spender,
+ 196 : : address from,
+ 197 : : address to,
+ 198 : : uint256 value
+ 199 : : ) internal virtual{
+ 200 : 2 : uint256 rulesLength = _rules.length();
+ 201 : 2 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 202 : 2 : IRule(_rules.at(i)).transferred(
+ 203 : : spender,
+ 204 : : from,
+ 205 : : to,
+ 206 : : value
+ 207 : : );
+ 208 : : }
+ 209 : : }
+ 210 : : }
+
+ |
+
+
+
+
+
+
+
+
+
diff --git a/doc/coverage/coverage/test/utils/CMTATDeployment.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/VersionModule.sol.func-sort-c.html
similarity index 78%
rename from doc/coverage/coverage/test/utils/CMTATDeployment.sol.func-sort-c.html
rename to doc/coverage/coverage/src/modules/VersionModule.sol.func-sort-c.html
index a8ae820..72f73b9 100644
--- a/doc/coverage/coverage/test/utils/CMTATDeployment.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/modules/VersionModule.sol.func-sort-c.html
@@ -4,7 +4,7 @@
- LCOV - lcov.info - test/utils/CMTATDeployment.sol - functions
+ LCOV - lcov.info - src/modules/VersionModule.sol - functions
@@ -19,7 +19,7 @@
-
+
|
|
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -65,12 +65,12 @@
diff --git a/doc/coverage/coverage/test/utils/CMTATDeployment.sol.func.html b/doc/coverage/coverage/src/modules/VersionModule.sol.func.html
similarity index 78%
rename from doc/coverage/coverage/test/utils/CMTATDeployment.sol.func.html
rename to doc/coverage/coverage/src/modules/VersionModule.sol.func.html
index a912669..5f5430e 100644
--- a/doc/coverage/coverage/test/utils/CMTATDeployment.sol.func.html
+++ b/doc/coverage/coverage/src/modules/VersionModule.sol.func.html
@@ -4,7 +4,7 @@
- LCOV - lcov.info - test/utils/CMTATDeployment.sol - functions
+ LCOV - lcov.info - src/modules/VersionModule.sol - functions
@@ -19,7 +19,7 @@
diff --git a/doc/coverage/coverage/test/utils/SanctionListOracle.sol.gcov.html b/doc/coverage/coverage/src/modules/VersionModule.sol.gcov.html
similarity index 69%
rename from doc/coverage/coverage/test/utils/SanctionListOracle.sol.gcov.html
rename to doc/coverage/coverage/src/modules/VersionModule.sol.gcov.html
index 6a45b5a..c87703d 100644
--- a/doc/coverage/coverage/test/utils/SanctionListOracle.sol.gcov.html
+++ b/doc/coverage/coverage/src/modules/VersionModule.sol.gcov.html
@@ -4,7 +4,7 @@
- LCOV - lcov.info - test/utils/SanctionListOracle.sol
+ LCOV - lcov.info - src/modules/VersionModule.sol
@@ -19,7 +19,7 @@
@@ -82,52 +82,40 @@
Branches  |
- | RuleEngineValidationCommon.sol |
+ RulesManagementModule.sol |
|
100.0 % |
- 19 / 19 |
- 100.0 % |
- 10 / 10 |
+ 47 / 47 |
100.0 % |
- 1 / 1 |
+ 12 / 12 |
+ 78.6 % |
+ 11 / 14 |
- | RuleEngineValidation.sol |
+ ERC3643ComplianceModule.sol |
|
100.0 % |
- 8 / 8 |
- 100.0 % |
- 2 / 2 |
+ 24 / 24 |
100.0 % |
- 1 / 1 |
+ 8 / 8 |
+ 84.6 % |
+ 11 / 13 |
- | RuleEngineOperation.sol |
+ VersionModule.sol |
|
100.0 % |
- 25 / 25 |
- 100.0 % |
- 11 / 11 |
- 100.0 % |
2 / 2 |
-
-
- | RuleInternal.sol |
-
-
- |
- 100.0 % |
- 29 / 29 |
- 100.0 % |
- 4 / 4 |
100.0 % |
- 8 / 8 |
+ 1 / 1 |
+ - |
+ 0 / 0 |
diff --git a/doc/coverage/coverage/src/modules/index-sort-f.html b/doc/coverage/coverage/src/modules/index-sort-f.html
index f0cc112..43cd97e 100644
--- a/doc/coverage/coverage/src/modules/index-sort-f.html
+++ b/doc/coverage/coverage/src/modules/index-sort-f.html
@@ -31,17 +31,17 @@
|
-
-
+
+
-
+
|
-
-
+
+
@@ -49,9 +49,9 @@
|
|
-
-
-
+
+
+
 |
@@ -82,52 +82,40 @@
Branches  |
- | RuleEngineValidation.sol |
+ VersionModule.sol |
|
100.0 % |
- 8 / 8 |
- 100.0 % |
2 / 2 |
100.0 % |
1 / 1 |
+ - |
+ 0 / 0 |
- | RuleInternal.sol |
+ ERC3643ComplianceModule.sol |
|
100.0 % |
- 29 / 29 |
- 100.0 % |
- 4 / 4 |
+ 24 / 24 |
100.0 % |
8 / 8 |
+ 84.6 % |
+ 11 / 13 |
- | RuleEngineValidationCommon.sol |
-
-
- |
- 100.0 % |
- 19 / 19 |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 1 / 1 |
-
-
- | RuleEngineOperation.sol |
+ RulesManagementModule.sol |
|
100.0 % |
- 25 / 25 |
+ 47 / 47 |
100.0 % |
- 11 / 11 |
- 100.0 % |
- 2 / 2 |
+ 12 / 12 |
+ 78.6 % |
+ 11 / 14 |
diff --git a/doc/coverage/coverage/src/modules/index-sort-l.html b/doc/coverage/coverage/src/modules/index-sort-l.html
index 7d113ca..fcde026 100644
--- a/doc/coverage/coverage/src/modules/index-sort-l.html
+++ b/doc/coverage/coverage/src/modules/index-sort-l.html
@@ -31,17 +31,17 @@
|
-
-
+
+
-
+
|
-
-
+
+
@@ -49,9 +49,9 @@
|
|
-
-
-
+
+
+
 |
@@ -82,52 +82,40 @@
Branches  |
- | RuleEngineValidation.sol |
+ VersionModule.sol |
|
100.0 % |
- 8 / 8 |
- 100.0 % |
2 / 2 |
100.0 % |
1 / 1 |
+ - |
+ 0 / 0 |
- | RuleEngineValidationCommon.sol |
-
-
- |
- 100.0 % |
- 19 / 19 |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 1 / 1 |
-
-
- | RuleEngineOperation.sol |
+ ERC3643ComplianceModule.sol |
|
100.0 % |
- 25 / 25 |
+ 24 / 24 |
100.0 % |
- 11 / 11 |
- 100.0 % |
- 2 / 2 |
+ 8 / 8 |
+ 84.6 % |
+ 11 / 13 |
- | RuleInternal.sol |
+ RulesManagementModule.sol |
|
100.0 % |
- 29 / 29 |
+ 47 / 47 |
100.0 % |
- 4 / 4 |
- 100.0 % |
- 8 / 8 |
+ 12 / 12 |
+ 78.6 % |
+ 11 / 14 |
diff --git a/doc/coverage/coverage/src/modules/index.html b/doc/coverage/coverage/src/modules/index.html
index 60ae93b..0beaa22 100644
--- a/doc/coverage/coverage/src/modules/index.html
+++ b/doc/coverage/coverage/src/modules/index.html
@@ -31,17 +31,17 @@
|
-
-
+
+
-
+
|
-
-
+
+
@@ -49,9 +49,9 @@
|
|
-
-
-
+
+
+
 |
@@ -82,52 +82,40 @@
Branches  |
- | RuleEngineOperation.sol |
+ ERC3643ComplianceModule.sol |
|
100.0 % |
- 25 / 25 |
- 100.0 % |
- 11 / 11 |
- 100.0 % |
- 2 / 2 |
-
-
- | RuleEngineValidation.sol |
-
-
- |
+ 24 / 24 |
100.0 % |
8 / 8 |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 1 / 1 |
+ 84.6 % |
+ 11 / 13 |
- | RuleEngineValidationCommon.sol |
+ RulesManagementModule.sol |
|
100.0 % |
- 19 / 19 |
- 100.0 % |
- 10 / 10 |
+ 47 / 47 |
100.0 % |
- 1 / 1 |
+ 12 / 12 |
+ 78.6 % |
+ 11 / 14 |
- | RuleInternal.sol |
+ VersionModule.sol |
|
100.0 % |
- 29 / 29 |
- 100.0 % |
- 4 / 4 |
+ 2 / 2 |
100.0 % |
- 8 / 8 |
+ 1 / 1 |
+ - |
+ 0 / 0 |
diff --git a/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html
deleted file mode 100644
index 7f4ab01..0000000
--- a/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html
+++ /dev/null
@@ -1,153 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation/RuleConditionalTransfer.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html
deleted file mode 100644
index fba2e82..0000000
--- a/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html
+++ /dev/null
@@ -1,153 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation/RuleConditionalTransfer.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html
deleted file mode 100644
index 476c0ca..0000000
--- a/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html
+++ /dev/null
@@ -1,486 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation/RuleConditionalTransfer.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
|
-
-
-
- Branch data Line data Source code
-
- 1 : : // SPDX-License-Identifier: MPL-2.0
- 2 : :
- 3 : : pragma solidity ^0.8.20;
- 4 : :
- 5 : : import "OZ/access/AccessControl.sol";
- 6 : : import "../../interfaces/IRuleOperation.sol";
- 7 : : import "./../../modules/MetaTxModuleStandalone.sol";
- 8 : : import "./abstract/RuleConditionalTransferInvariantStorage.sol";
- 9 : : import "./abstract/RuleConditionalTransferOperator.sol";
- 10 : : import "../validation/abstract/RuleValidateTransfer.sol";
- 11 : : import "CMTAT/interfaces/engine/IRuleEngine.sol";
- 12 : :
- 13 : : /**
- 14 : : * @title RuleConditionalTransfer
- 15 : : */
- 16 : :
- 17 : : contract RuleConditionalTransfer is
- 18 : : RuleValidateTransfer,
- 19 : : IRuleOperation,
- 20 : : RuleConditionalTransferOperator,
- 21 : : MetaTxModuleStandalone
- 22 : : {
- 23 : : /**
- 24 : : * @param admin Address of the contract (Access Control)
- 25 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- 26 : : */
- 27 : : constructor(
- 28 : : address admin,
- 29 : : address forwarderIrrevocable,
- 30 : : IRuleEngine ruleEngineContract,
- 31 : : OPTION memory options_
- 32 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
- 33 [ + ]: 158 : if (admin == address(0)) {
- 34 : 1 : revert RuleConditionalTransfer_AdminWithAddressZeroNotAllowed();
- 35 : : }
- 36 : 157 : _grantRole(DEFAULT_ADMIN_ROLE, admin);
- 37 [ + ]: 157 : if (address(ruleEngineContract) != address(0x0)) {
- 38 : 153 : _grantRole(RULE_ENGINE_CONTRACT_ROLE, address(ruleEngineContract));
- 39 : : }
- 40 : 157 : options = options_;
- 41 : : }
- 42 : :
- 43 : : /*//////////////////////////////////////////////////////////////
- 44 : : PUBLIC/EXTERNAL FUNCTIONS
- 45 : : //////////////////////////////////////////////////////////////*/
- 46 : : /**
- 47 : : * @notice function called by the RuleEngine
- 48 : : * @dev Returns true if the transfer is valid, and false otherwise.
- 49 : : * Add access control with the RuleEngine
- 50 : : */
- 51 : : function operateOnTransfer(
- 52 : : address _from,
- 53 : : address _to,
- 54 : : uint256 _amount
- 55 : : )
- 56 : : public
- 57 : : override
- 58 : : onlyRole(RULE_ENGINE_CONTRACT_ROLE)
- 59 : : returns (bool isValid)
- 60 : : {
- 61 [ + + ]: 50 : if (_validateTransfer(_from, _to)) {
- 62 : 8 : return true;
- 63 : : } else {
- 64 : 42 : bytes32 key = keccak256(abi.encode(_from, _to, _amount));
- 65 [ + + ]: 42 : if (_validateApproval(key)) {
- 66 : 18 : _updateProcessedTransfer(key);
- 67 : 18 : return true;
- 68 : : } else {
- 69 : 24 : return false;
- 70 : : }
- 71 : : }
- 72 : : }
- 73 : :
- 74 : : /**
- 75 : : * @notice Create a request of transfer for yourselves
- 76 : : * @param to recipient of tokens
- 77 : : * @param value amount of tokens to transfer
- 78 : : */
- 79 : : function createTransferRequest(address to, uint256 value) public {
- 80 : : // WAIT => Will set a new delay to approve
- 81 : : // APPROVED => will overwrite previous status
- 82 : : // DENIED => reject
- 83 : 117 : address from = _msgSender();
- 84 : 117 : bytes32 key = keccak256(abi.encode(from, to, value));
- 85 [ + ]: 117 : if (transferRequests[key].status == STATUS.DENIED) {
- 86 : 1 : revert RuleConditionalTransfer_TransferDenied();
- 87 : : }
- 88 [ + + ]: 116 : if (_checkRequestStatus(key)) {
- 89 : 113 : uint256 requestIdLocal = requestId;
- 90 : 113 : TransferRequest memory newTransferApproval = TransferRequest({
- 91 : : key: key,
- 92 : : id: requestIdLocal,
- 93 : : keyElement: TransferRequestKeyElement({
- 94 : : from: from,
- 95 : : to: to,
- 96 : : value: value
- 97 : : }),
- 98 : : askTime: block.timestamp,
- 99 : : maxTime: 0,
- 100 : : status: STATUS.WAIT
- 101 : : });
- 102 : 113 : transferRequests[key] = newTransferApproval;
- 103 : 113 : IdToKey[requestIdLocal] = key;
- 104 : 113 : emit transferWaiting(key, from, to, value, requestId);
- 105 : 113 : ++requestId;
- 106 : : } else {
- 107 : : // Overwrite previous approval
- 108 : 3 : transferRequests[key].askTime = block.timestamp;
- 109 : 3 : transferRequests[key].status = STATUS.WAIT;
- 110 : 3 : emit transferWaiting(
- 111 : : key,
- 112 : : from,
- 113 : : to,
- 114 : : value,
- 115 : : transferRequests[key].id
- 116 : : );
- 117 : : }
- 118 : : }
- 119 : :
- 120 : : /**
- 121 : : * @notice Batch version of {createTransferRequest}
- 122 : : */
- 123 : : function createTransferRequestBatch(
- 124 : : address[] memory tos,
- 125 : : uint256[] memory values
- 126 : : ) public {
- 127 [ + ]: 3 : if (tos.length == 0) {
- 128 : 1 : revert RuleConditionalTransfer_EmptyArray();
- 129 : : }
- 130 [ + ]: 2 : if (tos.length != values.length) {
- 131 : 1 : revert RuleConditionalTransfer_InvalidLengthArray();
- 132 : : }
- 133 : 1 : for (uint256 i = 0; i < tos.length; ++i) {
- 134 : 3 : createTransferRequest(tos[i], values[i]);
- 135 : : }
- 136 : : }
- 137 : :
- 138 : : /**
- 139 : : * @notice allow a token holder to cancel/reset his own request
- 140 : : */
- 141 : : function cancelTransferRequest(uint256 requestId_) public {
- 142 : 6 : _cancelTransferRequest(requestId_);
- 143 : : }
- 144 : :
- 145 : : /**
- 146 : : * @notice allow a token holder to cancel/reset his own request
- 147 : : */
- 148 : : function cancelTransferRequestBatch(uint256[] memory requestIds) public {
- 149 [ + ]: 3 : if (requestIds.length == 0) {
- 150 : 1 : revert RuleConditionalTransfer_EmptyArray();
- 151 : : }
- 152 : : // Check id validity before performing actions
- 153 : 2 : for (uint256 i = 0; i < requestIds.length; ++i) {
- 154 [ + ]: 5 : if (requestIds[i] + 1 > requestId) {
- 155 : 1 : revert RuleConditionalTransfer_InvalidId();
- 156 : : }
- 157 : : }
- 158 : 1 : for (uint256 i = 0; i < requestIds.length; ++i) {
- 159 : 3 : _cancelTransferRequest(requestIds[i]);
- 160 : : }
- 161 : : }
- 162 : :
- 163 : : function getRequestTrade(
- 164 : : address from,
- 165 : : address to,
- 166 : : uint256 value
- 167 : : ) public view returns (TransferRequest memory) {
- 168 : 57 : bytes32 key = keccak256(abi.encode(from, to, value));
- 169 : 57 : return transferRequests[key];
- 170 : : }
- 171 : :
- 172 : : /**
- 173 : : * @notice get Trade by status
- 174 : : * @param _targetStatus The status of the transactions you want to retrieve
- 175 : : * @return array with corresponding transactions
- 176 : : */
- 177 : : function getRequestByStatus(
- 178 : : STATUS _targetStatus
- 179 : : ) public view returns (TransferRequest[] memory) {
- 180 : 35 : uint totalRequestCount = requestId;
- 181 : 35 : uint requestCount = 0;
- 182 : 35 : uint currentIndex = 0;
- 183 : :
- 184 : : // We count the number of requests matching the criteria
- 185 : 35 : for (uint i = 0; i < totalRequestCount; ++i) {
- 186 [ + ]: 38 : if (transferRequests[IdToKey[i]].status == _targetStatus) {
- 187 : 36 : requestCount += 1;
- 188 : : }
- 189 : : }
- 190 : :
- 191 : : // We reserve the memory to store the trade
- 192 : 35 : TransferRequest[] memory requests = new TransferRequest[](requestCount);
- 193 : :
- 194 : : // We create an array with the list of trade
- 195 : 35 : for (uint i = 0; i < totalRequestCount; ++i) {
- 196 [ + ]: 38 : if (transferRequests[IdToKey[i]].status == _targetStatus) {
- 197 : : //uint currentId = i + 1;
- 198 : 36 : TransferRequest memory currentRequest = transferRequests[
- 199 : : IdToKey[i]
- 200 : : ];
- 201 : 36 : requests[currentIndex] = currentRequest;
- 202 : 36 : currentIndex += 1;
- 203 : : }
- 204 : : }
- 205 : 35 : return requests;
- 206 : : }
- 207 : :
- 208 : : /**
- 209 : : * @notice Check if the transfer is valid
- 210 : : * @param _from the origin address
- 211 : : * @param _to the destination address
- 212 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- 213 : : **/
- 214 : : function detectTransferRestriction(
- 215 : : address _from,
- 216 : : address _to,
- 217 : : uint256 _amount
- 218 : : ) public view override returns (uint8) {
- 219 : : // No need of approval if from and to are in the whitelist
- 220 [ + ]: 56 : if (_validateTransfer(_from, _to)) {
- 221 : 1 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 222 : : }
- 223 : 55 : bytes32 key = keccak256(abi.encode(_from, _to, _amount));
- 224 [ + + ]: 55 : if (_validateApproval(key)) {
- 225 : 8 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 226 : : } else {
- 227 : 47 : return CODE_TRANSFER_REQUEST_NOT_APPROVED;
- 228 : : }
- 229 : : }
- 230 : :
- 231 : : /**
- 232 : : * @notice To know if the restriction code is valid for this rule or not.
- 233 : : * @param _restrictionCode The target restriction code
- 234 : : * @return true if the restriction code is known, false otherwise
- 235 : : **/
- 236 : : function canReturnTransferRestrictionCode(
- 237 : : uint8 _restrictionCode
- 238 : : ) external pure override returns (bool) {
- 239 : 2 : return _restrictionCode == CODE_TRANSFER_REQUEST_NOT_APPROVED;
- 240 : : }
- 241 : :
- 242 : : /**
- 243 : : * @notice Return the corresponding message
- 244 : : * @param _restrictionCode The target restriction code
- 245 : : * @return true if the transfer is valid, false otherwise
- 246 : : **/
- 247 : : function messageForTransferRestriction(
- 248 : : uint8 _restrictionCode
- 249 : : ) external pure override returns (string memory) {
- 250 [ + + ]: 3 : if (_restrictionCode == CODE_TRANSFER_REQUEST_NOT_APPROVED) {
- 251 : 2 : return TEXT_TRANSFER_REQUEST_NOT_APPROVED;
- 252 : : } else {
- 253 : 1 : return TEXT_CODE_NOT_FOUND;
- 254 : : }
- 255 : : }
- 256 : :
- 257 : : /*//////////////////////////////////////////////////////////////
- 258 : : INTERNAL FUNCTIONS
- 259 : : //////////////////////////////////////////////////////////////*/
- 260 : : function _validateTransfer(
- 261 : : address _from,
- 262 : : address _to
- 263 : : ) internal view returns (bool) {
- 264 : : // No need of approval if from and to are in the whitelist
- 265 [ + ]: 106 : if (address(whitelistConditionalTransfer) != address(0)) {
- 266 : : if (
- 267 : 36 : whitelistConditionalTransfer.addressIsListed(_from) &&
- 268 : 5 : whitelistConditionalTransfer.addressIsListed(_to)
- 269 [ + ]: 3 : ) {
- 270 : 3 : return true;
- 271 : : }
- 272 : : }
- 273 : :
- 274 : : // Mint & Burn
- 275 [ + ]: 103 : if (_validateBurnMint(_from, _to)) {
- 276 : 6 : return true;
- 277 : : }
- 278 : 97 : return false;
- 279 : : }
- 280 : :
- 281 : : function _cancelTransferRequest(uint256 requestId_) internal {
- 282 [ + ]: 9 : if (requestId_ + 1 > requestId) {
- 283 : 1 : revert RuleConditionalTransfer_InvalidId();
- 284 : : }
- 285 : 8 : bytes32 key = IdToKey[requestId_];
- 286 : : // Check Sender
- 287 [ + ]: 8 : if (transferRequests[key].keyElement.from != _msgSender()) {
- 288 : 1 : revert RuleConditionalTransfer_InvalidSender();
- 289 : : }
- 290 : : // Check status
- 291 : : if (
- 292 : 7 : transferRequests[key].status != STATUS.WAIT &&
- 293 : 2 : transferRequests[key].status != STATUS.APPROVED
- 294 [ + ]: 1 : ) {
- 295 : 1 : revert RuleConditionalTransfer_Wrong_Status();
- 296 : : }
- 297 : 6 : _resetRequestStatus(key);
- 298 : : }
- 299 : :
- 300 : : /**
- 301 : : *
- 302 : : * @dev
- 303 : : * Test burn and mint condition
- 304 : : * Returns true if the transfer is valid, and false otherwise.
- 305 : : *
- 306 : : */
- 307 : : function _validateBurnMint(
- 308 : : address _from,
- 309 : : address _to
- 310 : : ) internal view returns (bool isValid) {
- 311 : : // Mint & Burn
- 312 : : if (
- 313 : 103 : (_from == address(0) &&
- 314 : : options.issuance.authorizedMintWithoutApproval) ||
- 315 : : (_to == address(0) &&
- 316 : : options.issuance.authorizedBurnWithoutApproval)
- 317 [ + ]: 6 : ) {
- 318 : 6 : return true;
- 319 : : }
- 320 : 97 : return false;
- 321 : : }
- 322 : :
- 323 : : /**
- 324 : : *
- 325 : : * @dev
- 326 : : * Test transfer approval condition
- 327 : : * Returns true if the transfer is valid, and false otherwise.
- 328 : : */
- 329 : : function _validateApproval(
- 330 : : bytes32 key
- 331 : : ) internal view returns (bool isValid) {
- 332 : : // If automatic approval is activate and time to approve the request has passed
- 333 : 97 : if(transferRequests[key].status == STATUS.NONE
- 334 : : ||
- 335 : 50 : transferRequests[key].status == STATUS.DENIED
- 336 : : ||
- 337 : 47 : transferRequests[key].status == STATUS.EXECUTED)
- 338 [ + ]: 50 : {
- 339 : 50 : return false;
- 340 : : }
- 341 : 47 : bool isTransferApproved;
- 342 : 47 : bool automaticApprovalCondition;
- 343 [ + ]: 47 : if(transferRequests[key].status ==
- 344 [ + ]: 20 : STATUS.APPROVED){
- 345 : 20 : isTransferApproved = (transferRequests[key].maxTime >= block.timestamp);
- 346 : : } else if(options
- 347 : : .automaticApproval
- 348 [ + ]: 27 : .isActivate){
- 349 : : // Warning: overflow possible if timeLimitBeforeAutomaticApproval == max(uint256)
- 350 : 27 : automaticApprovalCondition= block.timestamp >=
- 351 : : (transferRequests[key].askTime +
- 352 : : options.automaticApproval.timeLimitBeforeAutomaticApproval);
- 353 : : }
- 354 : : // If the transfer is approved and delay to perform the transfer is respected
- 355 [ + + ]: 47 : if (automaticApprovalCondition || isTransferApproved) {
- 356 : 26 : return true;
- 357 : : } else {
- 358 : 21 : return false;
- 359 : : }
- 360 : : }
- 361 : :
- 362 : : /*//////////////////////////////////////////////////////////////
- 363 : : ERC-2771
- 364 : : //////////////////////////////////////////////////////////////*/
- 365 : :
- 366 : : /**
- 367 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 368 : : */
- 369 : : function _msgSender()
- 370 : : internal
- 371 : : view
- 372 : : override(ERC2771Context, Context)
- 373 : : returns (address sender)
- 374 : : {
- 375 : 829 : return ERC2771Context._msgSender();
- 376 : : }
- 377 : :
- 378 : : /**
- 379 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 380 : : */
- 381 : : function _msgData()
- 382 : : internal
- 383 : : view
- 384 : : override(ERC2771Context, Context)
- 385 : : returns (bytes calldata)
- 386 : : {
- 387 : 0 : return ERC2771Context._msgData();
- 388 : : }
- 389 : :
- 390 : : /**
- 391 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 392 : : */
- 393 : : function _contextSuffixLength()
- 394 : : internal
- 395 : : view
- 396 : : override(ERC2771Context, Context)
- 397 : : returns (uint256)
- 398 : : {
- 399 : 829 : return ERC2771Context._contextSuffixLength();
- 400 : : }
- 401 : : }
-
- |
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html
deleted file mode 100644
index acebdd7..0000000
--- a/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html
+++ /dev/null
@@ -1,161 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation/abstract/RuleConditionalTransferOperator.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html
deleted file mode 100644
index bbcca68..0000000
--- a/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html
+++ /dev/null
@@ -1,161 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation/abstract/RuleConditionalTransferOperator.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html
deleted file mode 100644
index 8a6d8ca..0000000
--- a/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html
+++ /dev/null
@@ -1,558 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation/abstract/RuleConditionalTransferOperator.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
|
-
-
-
- Branch data Line data Source code
-
- 1 : : // SPDX-License-Identifier: MPL-2.0
- 2 : :
- 3 : : pragma solidity ^0.8.20;
- 4 : :
- 5 : : import "OZ/access/AccessControl.sol";
- 6 : : import "./RuleConditionalTransferInvariantStorage.sol";
- 7 : : import "OZ/token/ERC20/utils/SafeERC20.sol";
- 8 : :
- 9 : : /**
- 10 : : * @title Restricted functions
- 11 : : */
- 12 : : abstract contract RuleConditionalTransferOperator is
- 13 : : AccessControl,
- 14 : : RuleConditionalTransferInvariantStorage
- 15 : : {
- 16 : : // Security
- 17 : : using SafeERC20 for IERC20;
- 18 : : /* ============ State Variables ============ */
- 19 : : OPTION public options;
- 20 : : uint256 public requestId;
- 21 : : mapping(uint256 => bytes32) public IdToKey;
- 22 : : mapping(bytes32 => TransferRequest) public transferRequests;
- 23 : : RuleWhitelist public whitelistConditionalTransfer;
- 24 : :
- 25 : : /*//////////////////////////////////////////////////////////////
- 26 : : PUBLIC/EXTERNAL FUNCTIONS
- 27 : : //////////////////////////////////////////////////////////////*/
- 28 : :
- 29 : : /**
- 30 : : * @notice set a whitelist. A transfer does not need of an approved request if from and to are in the whitelist
- 31 : : */
- 32 : : function setConditionalWhitelist(
- 33 : : RuleWhitelist newWhitelistConditionalTransfer
- 34 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 35 : 26 : whitelistConditionalTransfer = newWhitelistConditionalTransfer;
- 36 : 26 : emit WhitelistConditionalTransfer(newWhitelistConditionalTransfer);
- 37 : : }
- 38 : :
- 39 : : /**
- 40 : : * @notice set/unset the issuance options (mint & burn)
- 41 : : */
- 42 : : function setIssuanceOptions(
- 43 : : ISSUANCE calldata issuance_
- 44 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 45 : : if (
- 46 : 6 : options.issuance.authorizedMintWithoutApproval !=
- 47 : : issuance_.authorizedMintWithoutApproval
- 48 [ + ]: 3 : ) {
- 49 : 3 : options.issuance.authorizedMintWithoutApproval = issuance_
- 50 : : .authorizedMintWithoutApproval;
- 51 : : }
- 52 : : if (
- 53 : 6 : options.issuance.authorizedBurnWithoutApproval !=
- 54 : : issuance_.authorizedBurnWithoutApproval
- 55 [ + ]: 3 : ) {
- 56 : 3 : options.issuance.authorizedBurnWithoutApproval = issuance_
- 57 : : .authorizedBurnWithoutApproval;
- 58 : : }
- 59 : : }
- 60 : :
- 61 : : /**
- 62 : : * @notice set/unset the option to perform the transfer if the request is approved by the rule operator.
- 63 : : * To perform the transfer, the token holder has to approve the rule to spend tokens on his behalf (standard ERC-20 approval).
- 64 : : * If the allowance is not sufficient, the request will be approved, but without performing the transfer.
- 65 : : */
- 66 : : function setAutomaticTransfer(
- 67 : : AUTOMATIC_TRANSFER calldata automaticTransfer_
- 68 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 69 : : if (
- 70 : 3 : automaticTransfer_.isActivate !=
- 71 : : options.automaticTransfer.isActivate
- 72 [ + ]: 2 : ) {
- 73 : 2 : options.automaticTransfer.isActivate = automaticTransfer_
- 74 : : .isActivate;
- 75 : : }
- 76 : : // No need to put the cmtat to zero to deactivate automaticTransfer
- 77 : : if (
- 78 : 3 : address(automaticTransfer_.cmtat) !=
- 79 : : address(options.automaticTransfer.cmtat)
- 80 [ + ]: 2 : ) {
- 81 : 2 : options.automaticTransfer.cmtat = automaticTransfer_.cmtat;
- 82 : : }
- 83 : : }
- 84 : :
- 85 : : /**
- 86 : : * @notice set time limit for new requests (Approval and transfer)
- 87 : : * timeLimitToApprove: time limit for an operator to approve a request
- 88 : : * timeLimitToTransfer: once a request is approved, time limit for the token holder to perform the transfer
- 89 : : */
- 90 : : function setTimeLimit(
- 91 : : TIME_LIMIT memory timeLimit_
- 92 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 93 : : if (
- 94 : 4 : options.timeLimit.timeLimitToApprove !=
- 95 : : timeLimit_.timeLimitToApprove
- 96 [ + ]: 4 : ) {
- 97 : 4 : options.timeLimit.timeLimitToApprove = timeLimit_
- 98 : : .timeLimitToApprove;
- 99 : : }
- 100 : : if (
- 101 : 4 : options.timeLimit.timeLimitToTransfer !=
- 102 : : timeLimit_.timeLimitToTransfer
- 103 [ + ]: 4 : ) {
- 104 : 4 : options.timeLimit.timeLimitToTransfer = timeLimit_
- 105 : : .timeLimitToTransfer;
- 106 : : }
- 107 : : }
- 108 : :
- 109 : : /**
- 110 : : * @notice If the transfer is not approved or denied within {timeLimitBeforeAutomaticApproval},
- 111 : : * the request is considered as approved during a transfer.
- 112 : : *
- 113 : : */
- 114 : : function setAutomaticApproval(
- 115 : : AUTOMATIC_APPROVAL memory automaticApproval_
- 116 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 117 : : if (
- 118 : 9 : options.automaticApproval.isActivate !=
- 119 : : automaticApproval_.isActivate
- 120 [ + ]: 6 : ) {
- 121 : 6 : options.automaticApproval.isActivate = automaticApproval_
- 122 : : .isActivate;
- 123 : : }
- 124 : : if (
- 125 : 9 : options.automaticApproval.timeLimitBeforeAutomaticApproval !=
- 126 : : automaticApproval_.timeLimitBeforeAutomaticApproval
- 127 [ + ]: 9 : ) {
- 128 : 9 : options
- 129 : : .automaticApproval
- 130 : : .timeLimitBeforeAutomaticApproval = automaticApproval_
- 131 : : .timeLimitBeforeAutomaticApproval;
- 132 : : }
- 133 : : }
- 134 : :
- 135 : : /**
- 136 : : * @notice create a transfer request directly approved
- 137 : : */
- 138 : : function createTransferRequestWithApproval(
- 139 : : TransferRequestKeyElement calldata keyElement
- 140 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 141 : 5 : _createTransferRequestWithApproval(keyElement);
- 142 : : }
- 143 : :
- 144 : : /**
- 145 : : * @notice approve a transferRequest
- 146 : : * @param keyElement contains from, to, value
- 147 : : * @param partialValue amount approved. Put 0 if all the amount specified by value is approved.
- 148 : : * @param isApproved approved (true) or refused (false). Put true if you use partialApproval
- 149 : : */
- 150 : : function approveTransferRequest(
- 151 : : TransferRequestKeyElement calldata keyElement,
- 152 : : uint256 partialValue,
- 153 : : bool isApproved
- 154 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 155 : 39 : _approveTransferRequestKeyElement(keyElement, partialValue, isApproved);
- 156 : : }
- 157 : :
- 158 : : /**
- 159 : : * @notice approve a transferRequestby using its id
- 160 : : */
- 161 : : function approveTransferRequestWithId(
- 162 : : uint256 requestId_,
- 163 : : bool isApproved
- 164 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 165 [ + ]: 4 : if (requestId_ + 1 > requestId) {
- 166 : 2 : revert RuleConditionalTransfer_InvalidId();
- 167 : : }
- 168 : 2 : TransferRequest memory transferRequest = transferRequests[
- 169 : : IdToKey[requestId_]
- 170 : : ];
- 171 : 2 : _approveRequest(transferRequest, isApproved);
- 172 : : }
- 173 : :
- 174 : : /**
- 175 : : * @notice reset to None the status of a request
- 176 : : */
- 177 : : function resetRequestStatus(
- 178 : : uint256 requestId_
- 179 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 180 [ + ]: 2 : if (requestId_ + 1 > requestId) {
- 181 : 1 : revert RuleConditionalTransfer_InvalidId();
- 182 : : }
- 183 : 1 : bytes32 key = IdToKey[requestId_];
- 184 : 1 : _resetRequestStatus(key);
- 185 : : }
- 186 : :
- 187 : : /* ============ Batch function ============ */
- 188 : : /**
- 189 : : * @notice Batch version of {approveTransferRequestWithId}
- 190 : : */
- 191 : : function approveTransferRequestBatchWithId(
- 192 : : uint256[] calldata requestId_,
- 193 : : bool[] calldata isApproved
- 194 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 195 [ + ]: 5 : if (requestId_.length == 0) {
- 196 : 1 : revert RuleConditionalTransfer_EmptyArray();
- 197 : : }
- 198 [ + ]: 4 : if (requestId_.length != isApproved.length) {
- 199 : 1 : revert RuleConditionalTransfer_InvalidLengthArray();
- 200 : : }
- 201 : : // Check id validity before performing actions
- 202 : 3 : for (uint256 i = 0; i < requestId_.length; ++i) {
- 203 [ + ]: 11 : if (requestId_[i] + 1 > requestId) {
- 204 : 1 : revert RuleConditionalTransfer_InvalidId();
- 205 : : }
- 206 : : }
- 207 : 2 : for (uint256 i = 0; i < requestId_.length; ++i) {
- 208 : 5 : TransferRequest memory transferRequest = transferRequests[
- 209 : : IdToKey[requestId_[i]]
- 210 : : ];
- 211 : 5 : _approveRequest(transferRequest, isApproved[i]);
- 212 : : }
- 213 : : }
- 214 : :
- 215 : : /**
- 216 : : * @notice Batch version of {approveTransferRequest}
- 217 : : */
- 218 : : function approveTransferRequestBatch(
- 219 : : TransferRequestKeyElement[] calldata keyElements,
- 220 : : uint256[] calldata partialValues,
- 221 : : bool[] calldata isApproved
- 222 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 223 [ + ]: 6 : if (keyElements.length == 0) {
- 224 : 1 : revert RuleConditionalTransfer_EmptyArray();
- 225 : : }
- 226 : : if (
- 227 : 5 : (keyElements.length != partialValues.length) ||
- 228 : : (partialValues.length != isApproved.length)
- 229 [ + ]: 3 : ) {
- 230 : 3 : revert RuleConditionalTransfer_InvalidLengthArray();
- 231 : : }
- 232 : 2 : for (uint256 i = 0; i < keyElements.length; ++i) {
- 233 : 9 : _approveTransferRequestKeyElement(
- 234 : : keyElements[i],
- 235 : : partialValues[i],
- 236 : : isApproved[i]
- 237 : : );
- 238 : : }
- 239 : : }
- 240 : :
- 241 : : /**
- 242 : : * @notice Batch version of {createTransferRequestWithApproval}
- 243 : : */
- 244 : : function createTransferRequestWithApprovalBatch(
- 245 : : TransferRequestKeyElement[] calldata keyElements
- 246 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 247 [ + ]: 2 : if (keyElements.length == 0) {
- 248 : 1 : revert RuleConditionalTransfer_EmptyArray();
- 249 : : }
- 250 : 1 : for (uint256 i = 0; i < keyElements.length; ++i) {
- 251 : 4 : _createTransferRequestWithApproval(keyElements[i]);
- 252 : : }
- 253 : : }
- 254 : :
- 255 : : /**
- 256 : : * @notice Batch version of {resetRequestStatus}
- 257 : : */
- 258 : : function resetRequestStatusBatch(
- 259 : : uint256[] memory requestIds
- 260 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 261 [ + ]: 3 : if (requestIds.length == 0) {
- 262 : 1 : revert RuleConditionalTransfer_EmptyArray();
- 263 : : }
- 264 : : // Check id validity before performing actions
- 265 : 2 : for (uint256 i = 0; i < requestIds.length; ++i) {
- 266 [ + ]: 4 : if (requestIds[i] + 1 > requestId) {
- 267 : 1 : revert RuleConditionalTransfer_InvalidId();
- 268 : : }
- 269 : : }
- 270 : 1 : for (uint256 i = 0; i < requestIds.length; ++i) {
- 271 : 3 : bytes32 key = IdToKey[requestIds[i]];
- 272 : 3 : _resetRequestStatus(key);
- 273 : : }
- 274 : : }
- 275 : :
- 276 : : /* ============ ACCESS CONTROL ============ */
- 277 : : /**
- 278 : : * @dev Returns `true` if `account` has been granted `role`.
- 279 : : */
- 280 : : function hasRole(
- 281 : : bytes32 role,
- 282 : : address account
- 283 : : ) public view virtual override(AccessControl) returns (bool) {
- 284 : : // The Default Admin has all roles
- 285 [ + ]: 704 : if (AccessControl.hasRole(DEFAULT_ADMIN_ROLE, account)) {
- 286 : 137 : return true;
- 287 : : }
- 288 : 567 : return AccessControl.hasRole(role, account);
- 289 : : }
- 290 : :
- 291 : : /*//////////////////////////////////////////////////////////////
- 292 : : INTERNAL FUNCTIONS
- 293 : : //////////////////////////////////////////////////////////////*/
- 294 : : function _approveTransferRequestKeyElement(
- 295 : : TransferRequestKeyElement calldata keyElement,
- 296 : : uint256 partialValue,
- 297 : : bool isApproved
- 298 : : ) internal {
- 299 [ + ]: 48 : if (partialValue > keyElement.value) {
- 300 : 1 : revert RuleConditionalTransfer_InvalidValueApproved();
- 301 : : }
- 302 : 47 : bytes32 key = keccak256(
- 303 : : abi.encode(keyElement.from, keyElement.to, keyElement.value)
- 304 : : );
- 305 : 47 : TransferRequest memory transferRequest = transferRequests[key];
- 306 [ + + ]: 47 : if (partialValue > 0) {
- 307 [ + ]: 9 : if (!isApproved) {
- 308 : 1 : revert RuleConditionalTransfer_CannotDeniedPartially();
- 309 : : }
- 310 : : // Denied the first request
- 311 : 8 : _approveRequest(transferRequest, false);
- 312 : : // Create new request
- 313 : 8 : _createTransferRequestWithApproval(
- 314 : : TransferRequestKeyElement({
- 315 : : from: keyElement.from,
- 316 : : to: keyElement.to,
- 317 : : value: partialValue
- 318 : : })
- 319 : : );
- 320 : : } else {
- 321 : 38 : _approveRequest(transferRequest, isApproved);
- 322 : : }
- 323 : : }
- 324 : :
- 325 : : function _createTransferRequestWithApproval(
- 326 : : TransferRequestKeyElement memory keyElement_
- 327 : : ) internal {
- 328 : : // WAIT => Will overwrite
- 329 : : // APPROVED => will overwrite previous status with a new delay
- 330 : : // DENIED => will overwrite
- 331 : 17 : bytes32 key = keccak256(
- 332 : : abi.encode(keyElement_.from, keyElement_.to, keyElement_.value)
- 333 : : );
- 334 [ + + ]: 17 : if (_checkRequestStatus(key)) {
- 335 : : // Only if it is a new request
- 336 : 16 : TransferRequest memory newTransferApproval = TransferRequest({
- 337 : : key: key,
- 338 : : id: requestId,
- 339 : : keyElement: keyElement_,
- 340 : : askTime: 0,
- 341 : : // Warning: overflow possible if timeLimitToTransfer == max(uint256)
- 342 : : maxTime: block.timestamp +
- 343 : : options.timeLimit.timeLimitToTransfer,
- 344 : : status: STATUS.APPROVED
- 345 : : });
- 346 : 16 : transferRequests[key] = newTransferApproval;
- 347 : 16 : IdToKey[requestId] = key;
- 348 : 16 : emit transferApproved(
- 349 : : key,
- 350 : : keyElement_.from,
- 351 : : keyElement_.to,
- 352 : : keyElement_.value,
- 353 : : requestId
- 354 : : );
- 355 : 16 : ++requestId;
- 356 : : } else {
- 357 : : // Overwrite previous approval
- 358 : : // Warning: overflow possible if timeLimitToTransfer == max(uint256)
- 359 : 1 : transferRequests[key].maxTime =
- 360 : : block.timestamp +
- 361 : : options.timeLimit.timeLimitToTransfer;
- 362 : 1 : transferRequests[key].status = STATUS.APPROVED;
- 363 : 1 : emit transferApproved(
- 364 : : key,
- 365 : : keyElement_.from,
- 366 : : keyElement_.to,
- 367 : : keyElement_.value,
- 368 : : transferRequests[key].id
- 369 : : );
- 370 : : }
- 371 : : }
- 372 : :
- 373 : : function _resetRequestStatus(bytes32 key) internal {
- 374 : 10 : transferRequests[key].status = STATUS.NONE;
- 375 : 10 : emit transferReset(
- 376 : : key,
- 377 : : transferRequests[key].keyElement.from,
- 378 : : transferRequests[key].keyElement.to,
- 379 : : transferRequests[key].keyElement.value,
- 380 : : transferRequests[key].id
- 381 : : );
- 382 : : }
- 383 : :
- 384 : : /**
- 385 : : * @dev check if it is a new request or not
- 386 : : */
- 387 : : function _checkRequestStatus(bytes32 key) internal view returns (bool) {
- 388 : : // Status NONE not enough because reset is possible
- 389 : 133 : return
- 390 : 133 : (transferRequests[key].status == STATUS.NONE) &&
- 391 : : (transferRequests[key].key == 0x0);
- 392 : : }
- 393 : :
- 394 : : function _approveRequest(
- 395 : : TransferRequest memory transferRequest,
- 396 : : bool isApproved
- 397 : : ) internal {
- 398 : : // status
- 399 [ + ]: 53 : if (transferRequest.status != STATUS.WAIT) {
- 400 : 1 : revert RuleConditionalTransfer_Wrong_Status();
- 401 : : }
- 402 [ + + ]: 32 : if (isApproved) {
- 403 : : // Time
- 404 : : if (
- 405 : 32 : block.timestamp >
- 406 : : (transferRequest.askTime + options.timeLimit.timeLimitToApprove)
- 407 [ + ]: 3 : ) {
- 408 : 3 : revert RuleConditionalTransfer_timeExceeded();
- 409 : : }
- 410 : : // Set status
- 411 : 29 : transferRequests[transferRequest.key].status = STATUS.APPROVED;
- 412 : : // Set max time
- 413 : 29 : transferRequests[transferRequest.key].maxTime =
- 414 : : block.timestamp +
- 415 : : options.timeLimit.timeLimitToTransfer;
- 416 : 29 : emit transferApproved(
- 417 : : transferRequest.key,
- 418 : : transferRequest.keyElement.from,
- 419 : : transferRequest.keyElement.to,
- 420 : : transferRequest.keyElement.value,
- 421 : : transferRequests[transferRequest.key].id
- 422 : : );
- 423 : : if (
- 424 : 29 : options.automaticTransfer.isActivate &&
- 425 : 7 : address(options.automaticTransfer.cmtat) != address(0)
- 426 [ + ]: 7 : ) {
- 427 : : // Transfer with approval
- 428 : : // External call
- 429 : : if (
- 430 : 7 : options.automaticTransfer.cmtat.allowance(
- 431 : : transferRequest.keyElement.from,
- 432 : : address(this)
- 433 : : ) >= transferRequest.keyElement.value
- 434 [ + ]: 3 : ) {
- 435 : : // Will call the ruleEngine and the rule again...
- 436 : 3 : options.automaticTransfer.cmtat.safeTransferFrom(
- 437 : : transferRequest.keyElement.from,
- 438 : : transferRequest.keyElement.to,
- 439 : : transferRequest.keyElement.value
- 440 : : );
- 441 : : }
- 442 : : }
- 443 : : } else {
- 444 : 20 : transferRequests[transferRequest.key].status = STATUS.DENIED;
- 445 : 20 : emit transferDenied(
- 446 : : transferRequest.key,
- 447 : : transferRequest.keyElement.from,
- 448 : : transferRequest.keyElement.to,
- 449 : : transferRequest.keyElement.value,
- 450 : : transferRequests[transferRequest.key].id
- 451 : : );
- 452 : : }
- 453 : : }
- 454 : :
- 455 : : /**
- 456 : : * @notice update the request during a transfer
- 457 : : */
- 458 : : function _updateProcessedTransfer(bytes32 key) internal {
- 459 : : // Reset to zero
- 460 : 18 : transferRequests[key].maxTime = 0;
- 461 : 18 : transferRequests[key].askTime = 0;
- 462 : : // Change status
- 463 : 18 : transferRequests[key].status = STATUS.EXECUTED;
- 464 : : // Emit event
- 465 : 18 : emit transferProcessed(
- 466 : : key,
- 467 : : transferRequests[key].keyElement.from,
- 468 : : transferRequests[key].keyElement.to,
- 469 : : transferRequests[key].keyElement.value,
- 470 : : transferRequests[key].id
- 471 : : );
- 472 : : }
- 473 : : }
-
- |
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/index-sort-b.html b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-b.html
deleted file mode 100644
index e47a898..0000000
--- a/doc/coverage/coverage/src/rules/operation/abstract/index-sort-b.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation/abstract
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleConditionalTransferOperator.sol |
-
-
- |
- 100.0 % |
- 113 / 113 |
- 100.0 % |
- 20 / 20 |
- 100.0 % |
- 31 / 31 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/index-sort-f.html b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-f.html
deleted file mode 100644
index aaae3fc..0000000
--- a/doc/coverage/coverage/src/rules/operation/abstract/index-sort-f.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation/abstract
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleConditionalTransferOperator.sol |
-
-
- |
- 100.0 % |
- 113 / 113 |
- 100.0 % |
- 20 / 20 |
- 100.0 % |
- 31 / 31 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/index-sort-l.html b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-l.html
deleted file mode 100644
index 2ec5b2c..0000000
--- a/doc/coverage/coverage/src/rules/operation/abstract/index-sort-l.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation/abstract
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleConditionalTransferOperator.sol |
-
-
- |
- 100.0 % |
- 113 / 113 |
- 100.0 % |
- 20 / 20 |
- 100.0 % |
- 31 / 31 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/index.html b/doc/coverage/coverage/src/rules/operation/abstract/index.html
deleted file mode 100644
index 1428f56..0000000
--- a/doc/coverage/coverage/src/rules/operation/abstract/index.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation/abstract
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleConditionalTransferOperator.sol |
-
-
- |
- 100.0 % |
- 113 / 113 |
- 100.0 % |
- 20 / 20 |
- 100.0 % |
- 31 / 31 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/index-sort-b.html b/doc/coverage/coverage/src/rules/operation/index-sort-b.html
deleted file mode 100644
index d14d712..0000000
--- a/doc/coverage/coverage/src/rules/operation/index-sort-b.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleConditionalTransfer.sol |
-
-
- |
- 99.1 % |
- 105 / 106 |
- 94.4 % |
- 17 / 18 |
- 100.0 % |
- 33 / 33 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/index-sort-f.html b/doc/coverage/coverage/src/rules/operation/index-sort-f.html
deleted file mode 100644
index d28f603..0000000
--- a/doc/coverage/coverage/src/rules/operation/index-sort-f.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleConditionalTransfer.sol |
-
-
- |
- 99.1 % |
- 105 / 106 |
- 94.4 % |
- 17 / 18 |
- 100.0 % |
- 33 / 33 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/index-sort-l.html b/doc/coverage/coverage/src/rules/operation/index-sort-l.html
deleted file mode 100644
index ece5b0b..0000000
--- a/doc/coverage/coverage/src/rules/operation/index-sort-l.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleConditionalTransfer.sol |
-
-
- |
- 99.1 % |
- 105 / 106 |
- 94.4 % |
- 17 / 18 |
- 100.0 % |
- 33 / 33 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/operation/index.html b/doc/coverage/coverage/src/rules/operation/index.html
deleted file mode 100644
index 260d74e..0000000
--- a/doc/coverage/coverage/src/rules/operation/index.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/operation
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleConditionalTransfer.sol |
-
-
- |
- 99.1 % |
- 105 / 106 |
- 94.4 % |
- 17 / 18 |
- 100.0 % |
- 33 / 33 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html
deleted file mode 100644
index a23344e..0000000
--- a/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/RuleBlacklist.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func.html b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func.html
deleted file mode 100644
index 0168a37..0000000
--- a/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func.html
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/RuleBlacklist.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html
deleted file mode 100644
index bea5e34..0000000
--- a/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html
+++ /dev/null
@@ -1,161 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/RuleBlacklist.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html
deleted file mode 100644
index 76ad884..0000000
--- a/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html
+++ /dev/null
@@ -1,121 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/RuleSanctionList.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func.html b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func.html
deleted file mode 100644
index f3eefa0..0000000
--- a/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func.html
+++ /dev/null
@@ -1,121 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/RuleSanctionList.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html
deleted file mode 100644
index 299cb3a..0000000
--- a/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html
+++ /dev/null
@@ -1,250 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/RuleSanctionList.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
|
-
-
-
- Branch data Line data Source code
-
- 1 : : // SPDX-License-Identifier: MPL-2.0
- 2 : :
- 3 : : pragma solidity ^0.8.20;
- 4 : :
- 5 : : import "OZ/access/AccessControl.sol";
- 6 : : import "../../modules/MetaTxModuleStandalone.sol";
- 7 : : import "./abstract/RuleSanctionListInvariantStorage.sol";
- 8 : : import "./abstract/RuleValidateTransfer.sol";
- 9 : :
- 10 : : interface SanctionsList {
- 11 : : function isSanctioned(address addr) external view returns (bool);
- 12 : : }
- 13 : :
- 14 : : contract RuleSanctionList is
- 15 : : AccessControl,
- 16 : : MetaTxModuleStandalone,
- 17 : : RuleValidateTransfer,
- 18 : : RuleSanctionlistInvariantStorage
- 19 : : {
- 20 : : SanctionsList public sanctionsList;
- 21 : :
- 22 : : /**
- 23 : : * @param admin Address of the contract (Access Control)
- 24 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- 25 : : */
- 26 : : constructor(
- 27 : : address admin,
- 28 : : address forwarderIrrevocable,
- 29 : : address sanctionContractOracle_
- 30 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
- 31 [ + ]: 13 : if (admin == address(0)) {
- 32 : 1 : revert RuleSanctionList_AdminWithAddressZeroNotAllowed();
- 33 : : }
- 34 [ + ]: 12 : if (sanctionContractOracle_ != address(0)) {
- 35 : 1 : _setSanctionListOracle(sanctionContractOracle_);
- 36 : : }
- 37 : 12 : _grantRole(DEFAULT_ADMIN_ROLE, admin);
- 38 : : }
- 39 : :
- 40 : : /**
- 41 : : * @notice Set the oracle contract
- 42 : : * @param sanctionContractOracle_ address of your oracle contract
- 43 : : * @dev zero address is authorized to authorize all transfers
- 44 : : */
- 45 : : function setSanctionListOracle(
- 46 : : address sanctionContractOracle_
- 47 : : ) public onlyRole(SANCTIONLIST_ROLE) {
- 48 : 10 : _setSanctionListOracle(sanctionContractOracle_);
- 49 : : }
- 50 : :
- 51 : : /**
- 52 : : * @notice Check if an addres is in the whitelist or not
- 53 : : * @param _from the origin address
- 54 : : * @param _to the destination address
- 55 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- 56 : : **/
- 57 : : function detectTransferRestriction(
- 58 : : address _from,
- 59 : : address _to,
- 60 : : uint256 /*_amount */
- 61 : : ) public view override returns (uint8) {
- 62 [ + ]: 7 : if (address(sanctionsList) != address(0)) {
- 63 [ + + ]: 7 : if (sanctionsList.isSanctioned(_from)) {
- 64 : 2 : return CODE_ADDRESS_FROM_IS_SANCTIONED;
- 65 [ + ]: 5 : } else if (sanctionsList.isSanctioned(_to)) {
- 66 : 2 : return CODE_ADDRESS_TO_IS_SANCTIONED;
- 67 : : }
- 68 : : }
- 69 : 3 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 70 : : }
- 71 : :
- 72 : : /**
- 73 : : * @notice To know if the restriction code is valid for this rule or not.
- 74 : : * @param _restrictionCode The target restriction code
- 75 : : * @return true if the restriction code is known, false otherwise
- 76 : : **/
- 77 : : function canReturnTransferRestrictionCode(
- 78 : : uint8 _restrictionCode
- 79 : : ) external pure override returns (bool) {
- 80 : 3 : return
- 81 : 3 : _restrictionCode == CODE_ADDRESS_FROM_IS_SANCTIONED ||
- 82 : 2 : _restrictionCode == CODE_ADDRESS_TO_IS_SANCTIONED;
- 83 : : }
- 84 : :
- 85 : : /**
- 86 : : * @notice Return the corresponding message
- 87 : : * @param _restrictionCode The target restriction code
- 88 : : * @return true if the transfer is valid, false otherwise
- 89 : : **/
- 90 : : function messageForTransferRestriction(
- 91 : : uint8 _restrictionCode
- 92 : : ) external pure override returns (string memory) {
- 93 [ + + ]: 3 : if (_restrictionCode == CODE_ADDRESS_FROM_IS_SANCTIONED) {
- 94 : 1 : return TEXT_ADDRESS_FROM_IS_SANCTIONED;
- 95 [ + + ]: 2 : } else if (_restrictionCode == CODE_ADDRESS_TO_IS_SANCTIONED) {
- 96 : 1 : return TEXT_ADDRESS_TO_IS_SANCTIONED;
- 97 : : } else {
- 98 : 1 : return TEXT_CODE_NOT_FOUND;
- 99 : : }
- 100 : : }
- 101 : :
- 102 : : /* ============ ACCESS CONTROL ============ */
- 103 : : /**
- 104 : : * @dev Returns `true` if `account` has been granted `role`.
- 105 : : */
- 106 : : function hasRole(
- 107 : : bytes32 role,
- 108 : : address account
- 109 : : ) public view virtual override(AccessControl) returns (bool) {
- 110 : : // The Default Admin has all roles
- 111 [ + ]: 24 : if (AccessControl.hasRole(DEFAULT_ADMIN_ROLE, account)) {
- 112 : 11 : return true;
- 113 : : }
- 114 : 13 : return AccessControl.hasRole(role, account);
- 115 : : }
- 116 : :
- 117 : : /*//////////////////////////////////////////////////////////////
- 118 : : INTERNAL FUNCTIONS
- 119 : : //////////////////////////////////////////////////////////////*/
- 120 : :
- 121 : : function _setSanctionListOracle(address sanctionContractOracle_) internal {
- 122 : 11 : sanctionsList = SanctionsList(sanctionContractOracle_);
- 123 : 11 : emit SetSanctionListOracle(address(sanctionContractOracle_));
- 124 : : }
- 125 : :
- 126 : : /*//////////////////////////////////////////////////////////////
- 127 : : ERC-2771
- 128 : : //////////////////////////////////////////////////////////////*/
- 129 : :
- 130 : : /**
- 131 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 132 : : */
- 133 : : function _msgSender()
- 134 : : internal
- 135 : : view
- 136 : : override(ERC2771Context, Context)
- 137 : : returns (address sender)
- 138 : : {
- 139 : 23 : return ERC2771Context._msgSender();
- 140 : : }
- 141 : :
- 142 : : /**
- 143 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 144 : : */
- 145 : : function _msgData()
- 146 : : internal
- 147 : : view
- 148 : : override(ERC2771Context, Context)
- 149 : : returns (bytes calldata)
- 150 : : {
- 151 : 0 : return ERC2771Context._msgData();
- 152 : : }
- 153 : :
- 154 : : /**
- 155 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 156 : : */
- 157 : : function _contextSuffixLength()
- 158 : : internal
- 159 : : view
- 160 : : override(ERC2771Context, Context)
- 161 : : returns (uint256)
- 162 : : {
- 163 : 23 : return ERC2771Context._contextSuffixLength();
- 164 : : }
- 165 : : }
-
- |
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html
deleted file mode 100644
index 3983775..0000000
--- a/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/RuleWhitelist.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func.html
deleted file mode 100644
index 855b26a..0000000
--- a/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/RuleWhitelist.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html
deleted file mode 100644
index 729cd39..0000000
--- a/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html
+++ /dev/null
@@ -1,125 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/RuleWhitelist.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html
deleted file mode 100644
index 50d42d4..0000000
--- a/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html
+++ /dev/null
@@ -1,105 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/RuleWhitelistWrapper.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html
deleted file mode 100644
index 87ddb39..0000000
--- a/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html
+++ /dev/null
@@ -1,105 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/RuleWhitelistWrapper.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html
deleted file mode 100644
index 497bf06..0000000
--- a/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html
+++ /dev/null
@@ -1,215 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/RuleWhitelistWrapper.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
|
-
-
-
- Branch data Line data Source code
-
- 1 : : // SPDX-License-Identifier: MPL-2.0
- 2 : :
- 3 : : pragma solidity ^0.8.20;
- 4 : :
- 5 : : import "OZ/access/AccessControl.sol";
- 6 : : import "../../modules/RuleEngineValidationCommon.sol";
- 7 : : import "../../modules/MetaTxModuleStandalone.sol";
- 8 : : import "./abstract/RuleAddressList/RuleAddressList.sol";
- 9 : : import "./abstract/RuleWhitelistCommon.sol";
- 10 : :
- 11 : : /**
- 12 : : * @title Wrapper to call several different whitelist rules
- 13 : : */
- 14 : : contract RuleWhitelistWrapper is
- 15 : : RuleEngineValidationCommon,
- 16 : : MetaTxModuleStandalone,
- 17 : : RuleWhitelistCommon
- 18 : : {
- 19 : : /**
- 20 : : * @param admin Address of the contract (Access Control)
- 21 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- 22 : : */
- 23 : : constructor(
- 24 : : address admin,
- 25 : : address forwarderIrrevocable
- 26 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
- 27 [ + ]: 14 : if (admin == address(0)) {
- 28 : 1 : revert RuleEngine_AdminWithAddressZeroNotAllowed();
- 29 : : }
- 30 : 13 : _grantRole(DEFAULT_ADMIN_ROLE, admin);
- 31 : : }
- 32 : :
- 33 : : /**
- 34 : : * @notice Go through all the whitelist rules to know if a restriction exists on the transfer
- 35 : : * @param _from the origin address
- 36 : : * @param _to the destination address
- 37 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- 38 : : **/
- 39 : : function detectTransferRestriction(
- 40 : : address _from,
- 41 : : address _to,
- 42 : : uint256 /*_amount*/
- 43 : : ) public view override returns (uint8) {
- 44 : 11 : address[] memory targetAddress = new address[](2);
- 45 : 11 : bool[] memory isListed = new bool[](2);
- 46 : 11 : bool[] memory result = new bool[](2);
- 47 : 11 : targetAddress[0] = _from;
- 48 : 11 : targetAddress[1] = _to;
- 49 : 11 : uint256 rulesLength = _rulesValidation.length;
- 50 : : // For each whitelist rule, we ask if from or to are in the whitelist
- 51 : 11 : for (uint256 i = 0; i < rulesLength; ++i) {
- 52 : : // External call
- 53 : 25 : isListed = RuleAddressList(_rulesValidation[i])
- 54 : : .addressIsListedBatch(targetAddress);
- 55 [ + ]: 25 : if (isListed[0] && !result[0]) {
- 56 : : // Update if from is in the list
- 57 : 7 : result[0] = true;
- 58 : : }
- 59 [ + ]: 25 : if (isListed[1] && !result[1]) {
- 60 : : // Update if to is in the list
- 61 : 7 : result[1] = true;
- 62 : : }
- 63 [ + ]: 25 : if (result[0] && result[1]) {
- 64 : 25 : break;
- 65 : : }
- 66 : : }
- 67 [ + + ]: 11 : if (!result[0]) {
- 68 : 4 : return CODE_ADDRESS_FROM_NOT_WHITELISTED;
- 69 [ + + ]: 7 : } else if (!result[1]) {
- 70 : 2 : return CODE_ADDRESS_TO_NOT_WHITELISTED;
- 71 : : } else {
- 72 : 5 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 73 : : }
- 74 : : }
- 75 : :
- 76 : : /* ============ ACCESS CONTROL ============ */
- 77 : : /**
- 78 : : * @dev Returns `true` if `account` has been granted `role`.
- 79 : : */
- 80 : : function hasRole(
- 81 : : bytes32 role,
- 82 : : address account
- 83 : : ) public view virtual override(AccessControl) returns (bool) {
- 84 : : // The Default Admin has all roles
- 85 [ + ]: 52 : if (AccessControl.hasRole(DEFAULT_ADMIN_ROLE, account)) {
- 86 : 39 : return true;
- 87 : : }
- 88 : 13 : return AccessControl.hasRole(role, account);
- 89 : : }
- 90 : :
- 91 : : /*//////////////////////////////////////////////////////////////
- 92 : : ERC-2771
- 93 : : //////////////////////////////////////////////////////////////*/
- 94 : :
- 95 : : /**
- 96 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 97 : : */
- 98 : : function _msgSender()
- 99 : : internal
- 100 : : view
- 101 : : override(ERC2771Context, Context)
- 102 : : returns (address sender)
- 103 : : {
- 104 : 52 : return ERC2771Context._msgSender();
- 105 : : }
- 106 : :
- 107 : : /**
- 108 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 109 : : */
- 110 : : function _msgData()
- 111 : : internal
- 112 : : view
- 113 : : override(ERC2771Context, Context)
- 114 : : returns (bytes calldata)
- 115 : : {
- 116 : 0 : return ERC2771Context._msgData();
- 117 : : }
- 118 : :
- 119 : : /**
- 120 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 121 : : */
- 122 : : function _contextSuffixLength()
- 123 : : internal
- 124 : : view
- 125 : : override(ERC2771Context, Context)
- 126 : : returns (uint256)
- 127 : : {
- 128 : 52 : return ERC2771Context._contextSuffixLength();
- 129 : : }
- 130 : : }
-
- |
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html
deleted file mode 100644
index 98ee305..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html
+++ /dev/null
@@ -1,129 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html
deleted file mode 100644
index ed5ebcb..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html
+++ /dev/null
@@ -1,129 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html
deleted file mode 100644
index 5b3956f..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html
+++ /dev/null
@@ -1,105 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html
deleted file mode 100644
index d5e1465..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html
+++ /dev/null
@@ -1,105 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html
deleted file mode 100644
index f91cf24..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html
+++ /dev/null
@@ -1,186 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html
deleted file mode 100644
index 5f6b1ad..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleAddressList
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleAddressList.sol |
-
-
- |
- 95.7 % |
- 22 / 23 |
- 91.7 % |
- 11 / 12 |
- 100.0 % |
- 2 / 2 |
-
-
- | RuleAddressListInternal.sol |
-
-
- |
- 100.0 % |
- 22 / 22 |
- 100.0 % |
- 6 / 6 |
- 100.0 % |
- 4 / 4 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html
deleted file mode 100644
index d55918c..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleAddressList
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleAddressList.sol |
-
-
- |
- 95.7 % |
- 22 / 23 |
- 91.7 % |
- 11 / 12 |
- 100.0 % |
- 2 / 2 |
-
-
- | RuleAddressListInternal.sol |
-
-
- |
- 100.0 % |
- 22 / 22 |
- 100.0 % |
- 6 / 6 |
- 100.0 % |
- 4 / 4 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html
deleted file mode 100644
index 94dea7d..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleAddressList
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleAddressList.sol |
-
-
- |
- 95.7 % |
- 22 / 23 |
- 91.7 % |
- 11 / 12 |
- 100.0 % |
- 2 / 2 |
-
-
- | RuleAddressListInternal.sol |
-
-
- |
- 100.0 % |
- 22 / 22 |
- 100.0 % |
- 6 / 6 |
- 100.0 % |
- 4 / 4 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index.html
deleted file mode 100644
index b24b451..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleAddressList
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleAddressList.sol |
-
-
- |
- 95.7 % |
- 22 / 23 |
- 91.7 % |
- 11 / 12 |
- 100.0 % |
- 2 / 2 |
-
-
- | RuleAddressListInternal.sol |
-
-
- |
- 100.0 % |
- 22 / 22 |
- 100.0 % |
- 6 / 6 |
- 100.0 % |
- 4 / 4 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html
deleted file mode 100644
index 9025b1d..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleValidateTransfer.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html
deleted file mode 100644
index cef3f12..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleValidateTransfer.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html
deleted file mode 100644
index c350c3b..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html
+++ /dev/null
@@ -1,110 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleValidateTransfer.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func-sort-c.html
deleted file mode 100644
index d40fb06..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func-sort-c.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleWhitelistCommon.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func.html
deleted file mode 100644
index b899bc1..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleWhitelistCommon.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.gcov.html
deleted file mode 100644
index 20b596c..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.gcov.html
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract/RuleWhitelistCommon.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/index-sort-b.html b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-b.html
deleted file mode 100644
index 32f7fc4..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/index-sort-b.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleValidateTransfer.sol |
-
-
- |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
- | RuleWhitelistCommon.sol |
-
-
- |
- 100.0 % |
- 8 / 8 |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 4 / 4 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/index-sort-f.html b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-f.html
deleted file mode 100644
index 37e913e..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/index-sort-f.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleValidateTransfer.sol |
-
-
- |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
- | RuleWhitelistCommon.sol |
-
-
- |
- 100.0 % |
- 8 / 8 |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 4 / 4 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/index-sort-l.html b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-l.html
deleted file mode 100644
index 51f2975..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/index-sort-l.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleValidateTransfer.sol |
-
-
- |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
- | RuleWhitelistCommon.sol |
-
-
- |
- 100.0 % |
- 8 / 8 |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 4 / 4 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/index.html b/doc/coverage/coverage/src/rules/validation/abstract/index.html
deleted file mode 100644
index 74cd455..0000000
--- a/doc/coverage/coverage/src/rules/validation/abstract/index.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation/abstract
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleValidateTransfer.sol |
-
-
- |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
- | RuleWhitelistCommon.sol |
-
-
- |
- 100.0 % |
- 8 / 8 |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 4 / 4 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/index-sort-b.html b/doc/coverage/coverage/src/rules/validation/index-sort-b.html
deleted file mode 100644
index d627eb6..0000000
--- a/doc/coverage/coverage/src/rules/validation/index-sort-b.html
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleWhitelist.sol |
-
-
- |
- 100.0 % |
- 5 / 5 |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 4 / 4 |
-
-
- | RuleBlacklist.sol |
-
-
- |
- 100.0 % |
- 13 / 13 |
- 100.0 % |
- 4 / 4 |
- 100.0 % |
- 8 / 8 |
-
-
- | RuleWhitelistWrapper.sol |
-
-
- |
- 96.4 % |
- 27 / 28 |
- 83.3 % |
- 5 / 6 |
- 100.0 % |
- 9 / 9 |
-
-
- | RuleSanctionList.sol |
-
-
- |
- 96.4 % |
- 27 / 28 |
- 90.0 % |
- 9 / 10 |
- 100.0 % |
- 11 / 11 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/index-sort-f.html b/doc/coverage/coverage/src/rules/validation/index-sort-f.html
deleted file mode 100644
index 7939279..0000000
--- a/doc/coverage/coverage/src/rules/validation/index-sort-f.html
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleWhitelistWrapper.sol |
-
-
- |
- 96.4 % |
- 27 / 28 |
- 83.3 % |
- 5 / 6 |
- 100.0 % |
- 9 / 9 |
-
-
- | RuleSanctionList.sol |
-
-
- |
- 96.4 % |
- 27 / 28 |
- 90.0 % |
- 9 / 10 |
- 100.0 % |
- 11 / 11 |
-
-
- | RuleWhitelist.sol |
-
-
- |
- 100.0 % |
- 5 / 5 |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 4 / 4 |
-
-
- | RuleBlacklist.sol |
-
-
- |
- 100.0 % |
- 13 / 13 |
- 100.0 % |
- 4 / 4 |
- 100.0 % |
- 8 / 8 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/index-sort-l.html b/doc/coverage/coverage/src/rules/validation/index-sort-l.html
deleted file mode 100644
index e147ebd..0000000
--- a/doc/coverage/coverage/src/rules/validation/index-sort-l.html
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleSanctionList.sol |
-
-
- |
- 96.4 % |
- 27 / 28 |
- 90.0 % |
- 9 / 10 |
- 100.0 % |
- 11 / 11 |
-
-
- | RuleWhitelistWrapper.sol |
-
-
- |
- 96.4 % |
- 27 / 28 |
- 83.3 % |
- 5 / 6 |
- 100.0 % |
- 9 / 9 |
-
-
- | RuleWhitelist.sol |
-
-
- |
- 100.0 % |
- 5 / 5 |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 4 / 4 |
-
-
- | RuleBlacklist.sol |
-
-
- |
- 100.0 % |
- 13 / 13 |
- 100.0 % |
- 4 / 4 |
- 100.0 % |
- 8 / 8 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/src/rules/validation/index.html b/doc/coverage/coverage/src/rules/validation/index.html
deleted file mode 100644
index 3d1ec09..0000000
--- a/doc/coverage/coverage/src/rules/validation/index.html
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - src/rules/validation
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleBlacklist.sol |
-
-
- |
- 100.0 % |
- 13 / 13 |
- 100.0 % |
- 4 / 4 |
- 100.0 % |
- 8 / 8 |
-
-
- | RuleSanctionList.sol |
-
-
- |
- 96.4 % |
- 27 / 28 |
- 90.0 % |
- 9 / 10 |
- 100.0 % |
- 11 / 11 |
-
-
- | RuleWhitelist.sol |
-
-
- |
- 100.0 % |
- 5 / 5 |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 4 / 4 |
-
-
- | RuleWhitelistWrapper.sol |
-
-
- |
- 96.4 % |
- 27 / 28 |
- 83.3 % |
- 5 / 6 |
- 100.0 % |
- 9 / 9 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.func-sort-c.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.func-sort-c.html
deleted file mode 100644
index 88c2a09..0000000
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.func-sort-c.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/RuleConditionalTransfer/utils/RuleCTDeployment.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.func.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.func.html
deleted file mode 100644
index ead2a6c..0000000
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.func.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/RuleConditionalTransfer/utils/RuleCTDeployment.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.gcov.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.gcov.html
deleted file mode 100644
index 471014d..0000000
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.gcov.html
+++ /dev/null
@@ -1,142 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/RuleConditionalTransfer/utils/RuleCTDeployment.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
|
-
-
-
- Branch data Line data Source code
-
- 1 : : // SPDX-License-Identifier: MPL-2.0
- 2 : : pragma solidity ^0.8.20;
- 3 : :
- 4 : : import "forge-std/Test.sol";
- 5 : : import "../../HelperContract.sol";
- 6 : : import "src/RuleEngine.sol";
- 7 : :
- 8 : : /**
- 9 : : * @title Tests on the Access Control
- 10 : : */
- 11 : : contract RuleCTDeployment is Test, HelperContract {
- 12 : : // Arrange
- 13 : : constructor() {
- 14 : 13 : TIME_LIMIT memory timeLimit_ = TIME_LIMIT({
- 15 : : timeLimitToApprove: 7 days,
- 16 : : timeLimitToTransfer: 30 days
- 17 : : });
- 18 : :
- 19 : 13 : AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
- 20 : : isActivate: false,
- 21 : : timeLimitBeforeAutomaticApproval: 0
- 22 : : });
- 23 : :
- 24 : 13 : ISSUANCE memory issuanceOption_ = ISSUANCE({
- 25 : : authorizedMintWithoutApproval: false,
- 26 : : authorizedBurnWithoutApproval: false
- 27 : : });
- 28 : 13 : AUTOMATIC_TRANSFER memory automaticTransfer_ = AUTOMATIC_TRANSFER({
- 29 : : isActivate: false,
- 30 : : cmtat: IERC20(address(0))
- 31 : : });
- 32 : :
- 33 : 13 : OPTION memory options = OPTION({
- 34 : : issuance: issuanceOption_,
- 35 : : timeLimit: timeLimit_,
- 36 : : automaticApproval: automaticApproval_,
- 37 : : automaticTransfer: automaticTransfer_
- 38 : : });
- 39 : 13 : ruleEngineMock = new RuleEngine(
- 40 : : RULE_ENGINE_OPERATOR_ADDRESS,
- 41 : : ZERO_ADDRESS,
- 42 : : ZERO_ADDRESS
- 43 : : );
- 44 : 13 : vm.prank(DEFAULT_ADMIN_ADDRESS);
- 45 : 13 : ruleConditionalTransfer = new RuleConditionalTransfer(
- 46 : : DEFAULT_ADMIN_ADDRESS,
- 47 : : ZERO_ADDRESS,
- 48 : : ruleEngineMock,
- 49 : : options
- 50 : : );
- 51 : 13 : vm.prank(DEFAULT_ADMIN_ADDRESS);
- 52 : 13 : ruleConditionalTransfer.grantRole(
- 53 : : RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE,
- 54 : : CONDITIONAL_TRANSFER_OPERATOR_ADDRESS
- 55 : : );
- 56 : : }
- 57 : : }
-
- |
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-b.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-b.html
deleted file mode 100644
index 273564b..0000000
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-b.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/RuleConditionalTransfer/utils
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleCTDeployment.sol |
-
-
- |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-f.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-f.html
deleted file mode 100644
index cfa53fa..0000000
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-f.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/RuleConditionalTransfer/utils
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleCTDeployment.sol |
-
-
- |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-l.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-l.html
deleted file mode 100644
index 8cfb2ca..0000000
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-l.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/RuleConditionalTransfer/utils
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleCTDeployment.sol |
-
-
- |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index.html
deleted file mode 100644
index 0fb4392..0000000
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/RuleConditionalTransfer/utils
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | RuleCTDeployment.sol |
-
-
- |
- 100.0 % |
- 10 / 10 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/utils/CMTATDeployment.sol.gcov.html b/doc/coverage/coverage/test/utils/CMTATDeployment.sol.gcov.html
deleted file mode 100644
index a0b1546..0000000
--- a/doc/coverage/coverage/test/utils/CMTATDeployment.sol.gcov.html
+++ /dev/null
@@ -1,129 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/utils/CMTATDeployment.sol
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
|
-
-
-
- Branch data Line data Source code
-
- 1 : : //SPDX-License-Identifier: MPL-2.0
- 2 : : pragma solidity ^0.8.20;
- 3 : :
- 4 : : import "forge-std/Test.sol";
- 5 : : import "OZ/access/AccessControl.sol";
- 6 : : import "CMTAT/CMTAT_STANDALONE.sol";
- 7 : :
- 8 : : contract CMTATDeployment {
- 9 : : // Share with helper contract
- 10 : : address constant ZERO_ADDRESS = address(0);
- 11 : : address constant DEFAULT_ADMIN_ADDRESS = address(1);
- 12 : :
- 13 : : CMTAT_STANDALONE public cmtat;
- 14 : :
- 15 : : constructor() {
- 16 : : // CMTAT
- 17 : 86 : ICMTATConstructor.ERC20Attributes
- 18 : : memory erc20Attributes = ICMTATConstructor.ERC20Attributes(
- 19 : : "CMTA Token",
- 20 : : "CMTAT",
- 21 : : 0
- 22 : : );
- 23 : 86 : ICMTATConstructor.BaseModuleAttributes
- 24 : : memory baseModuleAttributes = ICMTATConstructor
- 25 : : .BaseModuleAttributes(
- 26 : : "CMTAT_ISIN",
- 27 : : "https://cmta.ch",
- 28 : : "CMTAT_info"
- 29 : : );
- 30 : 86 : ICMTATConstructor.Engine memory engines = ICMTATConstructor.Engine(
- 31 : : IRuleEngine(ZERO_ADDRESS),
- 32 : : IDebtEngine(ZERO_ADDRESS),
- 33 : : IAuthorizationEngine(ZERO_ADDRESS),
- 34 : : IERC1643(ZERO_ADDRESS)
- 35 : : );
- 36 : 86 : cmtat = new CMTAT_STANDALONE(
- 37 : : ZERO_ADDRESS,
- 38 : : DEFAULT_ADMIN_ADDRESS,
- 39 : : erc20Attributes,
- 40 : : baseModuleAttributes,
- 41 : : engines
- 42 : : );
- 43 : : }
- 44 : : }
-
- |
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html
deleted file mode 100644
index 32ca64b..0000000
--- a/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/utils/SanctionListOracle.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func.html b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func.html
deleted file mode 100644
index 12d4508..0000000
--- a/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func.html
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/utils/SanctionListOracle.sol - functions
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/utils/index-sort-b.html b/doc/coverage/coverage/test/utils/index-sort-b.html
deleted file mode 100644
index 500c424..0000000
--- a/doc/coverage/coverage/test/utils/index-sort-b.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/utils
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | CMTATDeployment.sol |
-
-
- |
- 100.0 % |
- 4 / 4 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
- | SanctionListOracle.sol |
-
-
- |
- 66.7 % |
- 2 / 3 |
- 75.0 % |
- 3 / 4 |
- - |
- 0 / 0 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/utils/index-sort-f.html b/doc/coverage/coverage/test/utils/index-sort-f.html
deleted file mode 100644
index ff0b711..0000000
--- a/doc/coverage/coverage/test/utils/index-sort-f.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/utils
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | SanctionListOracle.sol |
-
-
- |
- 66.7 % |
- 2 / 3 |
- 75.0 % |
- 3 / 4 |
- - |
- 0 / 0 |
-
-
- | CMTATDeployment.sol |
-
-
- |
- 100.0 % |
- 4 / 4 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/utils/index-sort-l.html b/doc/coverage/coverage/test/utils/index-sort-l.html
deleted file mode 100644
index b1f3e52..0000000
--- a/doc/coverage/coverage/test/utils/index-sort-l.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/utils
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | SanctionListOracle.sol |
-
-
- |
- 66.7 % |
- 2 / 3 |
- 75.0 % |
- 3 / 4 |
- - |
- 0 / 0 |
-
-
- | CMTATDeployment.sol |
-
-
- |
- 100.0 % |
- 4 / 4 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/coverage/test/utils/index.html b/doc/coverage/coverage/test/utils/index.html
deleted file mode 100644
index 0cb6aec..0000000
--- a/doc/coverage/coverage/test/utils/index.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
- LCOV - lcov.info - test/utils
-
-
-
-
-
-
- | LCOV - code coverage report |
-  |
-
-
-
-
-
-
-
- |
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
- |
- |
-
-
-
-
-
-  |
-
- |
-
-
-  |
-
-
-
-
-
-
-
|
- |
- |
- |
- |
- |
- |
- |
-
-
-
- Filename  |
- Line Coverage  |
- Functions  |
- Branches  |
-
-
- | CMTATDeployment.sol |
-
-
- |
- 100.0 % |
- 4 / 4 |
- 100.0 % |
- 1 / 1 |
- - |
- 0 / 0 |
-
-
- | SanctionListOracle.sol |
-
-
- |
- 66.7 % |
- 2 / 3 |
- 75.0 % |
- 3 / 4 |
- - |
- 0 / 0 |
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/coverage/lcov.info b/doc/coverage/lcov.info
index a4e6aaf..9a34f35 100644
--- a/doc/coverage/lcov.info
+++ b/doc/coverage/lcov.info
@@ -1,995 +1,272 @@
TN:
-SF:script/CMTATWithRuleEngineScript.s.sol
-FN:15,CMTATWithRuleEngineScript.run
-FNDA:0,CMTATWithRuleEngineScript.run
-DA:17,0
-DA:18,0
-DA:19,0
-DA:20,0
-DA:22,0
-DA:23,0
-DA:24,0
-DA:26,0
-DA:30,0
-DA:32,0
-DA:37,0
-DA:38,0
-DA:39,0
-DA:41,0
-FNF:1
-FNH:0
-LF:14
-LH:0
-BRF:0
-BRH:0
-end_of_record
-TN:
-SF:script/RuleEngineScript.s.sol
-FN:16,RuleEngineScript.run
-FNDA:0,RuleEngineScript.run
-DA:18,0
-DA:19,0
-DA:20,0
-DA:21,0
-DA:23,0
-DA:24,0
-DA:26,0
-DA:27,0
-DA:28,0
-DA:30,0
-DA:33,0
-BRDA:33,0,0,-
-BRDA:33,0,1,-
-DA:34,0
-FNF:1
-FNH:0
-LF:12
-LH:0
-BRF:2
-BRH:0
-end_of_record
-TN:
SF:src/RuleEngine.sol
-FN:29,RuleEngine.
-FNDA:205,RuleEngine.
-DA:34,205
-BRDA:34,0,0,1
-DA:35,1
-DA:37,204
-BRDA:37,1,0,86
-DA:38,86
-DA:40,204
-FN:50,RuleEngine.detectTransferRestriction
-FNDA:20,RuleEngine.detectTransferRestriction
-DA:56,32
-DA:61,32
-BRDA:61,2,0,15
-DA:62,15
-DA:66,17
-DA:67,17
-DA:68,12
-DA:70,12
-BRDA:70,3,0,11
-DA:71,11
-DA:75,6
-FN:85,RuleEngine.validateTransfer
-FNDA:12,RuleEngine.validateTransfer
-DA:90,12
-DA:91,12
-FN:100,RuleEngine.messageForTransferRestriction
-FNDA:18,RuleEngine.messageForTransferRestriction
-DA:104,18
-DA:105,18
-DA:107,13
-DA:109,10
-BRDA:109,4,0,10
-DA:110,10
-DA:111,10
-DA:116,8
-DA:117,8
-DA:119,2
-DA:121,1
-BRDA:121,5,0,1
-DA:122,1
-DA:123,1
-DA:127,7
-FN:133,RuleEngine.operateOnTransfer
-FNDA:69,RuleEngine.operateOnTransfer
-DA:140,68
-DA:141,10
-BRDA:141,6,0,10
-DA:142,10
-DA:145,58
-FN:152,RuleEngine.hasRole
-FNDA:299,RuleEngine.hasRole
-DA:157,597
-BRDA:157,7,0,220
-DA:158,220
-DA:160,377
-FN:170,RuleEngine._msgSender
-FNDA:588,RuleEngine._msgSender
-DA:176,588
-FN:182,RuleEngine._msgData
+DA:22,90
+FN:22,RuleEngine.constructor
+FNDA:90,RuleEngine.constructor
+DA:27,90
+BRDA:27,0,0,1
+DA:28,1
+DA:30,89
+BRDA:30,1,0,15
+DA:31,15
+DA:33,89
+DA:43,300
+FN:43,RuleEngine._msgSender
+FNDA:300,RuleEngine._msgSender
+DA:50,300
+DA:56,0
+FN:56,RuleEngine._msgData
FNDA:0,RuleEngine._msgData
-DA:188,0
-FN:194,RuleEngine._contextSuffixLength
-FNDA:588,RuleEngine._contextSuffixLength
-DA:200,588
-FNF:9
-FNH:8
-LF:39
-LH:38
-BRF:8
-BRH:8
-end_of_record
-TN:
-SF:src/modules/MetaTxModuleStandalone.sol
-FN:11,MetaTxModuleStandalone.
-FNDA:575,MetaTxModuleStandalone.
-FNF:1
-FNH:1
-LF:0
-LH:0
-BRF:0
-BRH:0
-end_of_record
-TN:
-SF:src/modules/RuleEngineOperation.sol
-FN:26,RuleEngineOperation.setRulesOperation
-FNDA:11,RuleEngineOperation.setRulesOperation
-DA:29,11
-BRDA:29,0,0,10
-DA:30,10
-DA:32,11
-DA:33,8
-FN:40,RuleEngineOperation.clearRulesOperation
-FNDA:4,RuleEngineOperation.clearRulesOperation
-DA:41,4
-FN:48,RuleEngineOperation._clearRulesOperation
-FNDA:14,RuleEngineOperation._clearRulesOperation
-DA:49,14
-DA:51,14
-DA:54,17
-DA:56,17
-DA:58,14
-FN:66,RuleEngineOperation.addRuleOperation
-FNDA:85,RuleEngineOperation.addRuleOperation
-DA:69,85
-DA:70,83
-FN:83,RuleEngineOperation.removeRuleOperation
-FNDA:5,RuleEngineOperation.removeRuleOperation
-DA:87,5
-FN:100,RuleEngineOperation._removeRuleOperation
-FNDA:22,RuleEngineOperation._removeRuleOperation
-DA:101,22
-DA:102,21
-FN:108,RuleEngineOperation.rulesCountOperation
-FNDA:41,RuleEngineOperation.rulesCountOperation
-DA:109,41
-FN:116,RuleEngineOperation.getRuleIndexOperation
-FNDA:3,RuleEngineOperation.getRuleIndexOperation
-DA:119,3
-FN:127,RuleEngineOperation.ruleOperation
-FNDA:1,RuleEngineOperation.ruleOperation
-DA:130,1
-FN:137,RuleEngineOperation.rulesOperation
-FNDA:5,RuleEngineOperation.rulesOperation
-DA:143,5
-FN:152,RuleEngineOperation._operateOnTransfer
-FNDA:58,RuleEngineOperation._operateOnTransfer
-DA:157,58
-DA:158,58
-DA:159,50
-DA:164,50
-BRDA:164,1,0,24
-DA:165,24
-DA:168,34
-FNF:11
-FNH:11
-LF:25
-LH:25
+DA:63,0
+DA:69,300
+FN:69,RuleEngine._contextSuffixLength
+FNDA:300,RuleEngine._contextSuffixLength
+DA:76,300
+FNF:4
+FNH:3
+LF:12
+LH:10
BRF:2
BRH:2
end_of_record
TN:
-SF:src/modules/RuleEngineValidation.sol
-FN:29,RuleEngineValidation.detectTransferRestrictionValidation
-FNDA:3,RuleEngineValidation.detectTransferRestrictionValidation
-DA:34,105
-DA:35,105
-DA:36,43
-DA:38,43
-BRDA:38,0,0,28
-DA:39,28
-DA:43,77
-FN:53,RuleEngineValidation.validateTransferValidation
-FNDA:2,RuleEngineValidation.validateTransferValidation
-DA:58,70
-DA:59,70
-FNF:2
-FNH:2
-LF:8
-LH:8
-BRF:1
-BRH:1
-end_of_record
-TN:
-SF:src/modules/RuleEngineValidationCommon.sol
-FN:30,RuleEngineValidationCommon.setRulesValidation
-FNDA:22,RuleEngineValidationCommon.setRulesValidation
-DA:33,21
-BRDA:33,0,0,20
-DA:34,20
-DA:36,21
-DA:37,18
-FN:44,RuleEngineValidationCommon.clearRulesValidation
-FNDA:6,RuleEngineValidationCommon.clearRulesValidation
-DA:45,5
-FN:53,RuleEngineValidationCommon.addRuleValidation
-FNDA:119,RuleEngineValidationCommon.addRuleValidation
-DA:56,118
-DA:57,116
-FN:70,RuleEngineValidationCommon.removeRuleValidation
-FNDA:6,RuleEngineValidationCommon.removeRuleValidation
-DA:74,5
-FN:80,RuleEngineValidationCommon.rulesCountValidation
-FNDA:69,RuleEngineValidationCommon.rulesCountValidation
-DA:81,69
-FN:88,RuleEngineValidationCommon.getRuleIndexValidation
-FNDA:3,RuleEngineValidationCommon.getRuleIndexValidation
-DA:91,3
-FN:99,RuleEngineValidationCommon.ruleValidation
-FNDA:1,RuleEngineValidationCommon.ruleValidation
-DA:102,1
-FN:109,RuleEngineValidationCommon.rulesValidation
-FNDA:5,RuleEngineValidationCommon.rulesValidation
-DA:115,5
-FN:125,RuleEngineValidationCommon._clearRulesValidation
-FNDA:25,RuleEngineValidationCommon._clearRulesValidation
-DA:126,25
-DA:128,25
-DA:131,28
-DA:133,28
-DA:135,25
-FN:148,RuleEngineValidationCommon._removeRuleValidation
-FNDA:33,RuleEngineValidationCommon._removeRuleValidation
-DA:149,33
-DA:150,32
+SF:src/RuleEngineBase.sol
+DA:35,3
+FN:35,RuleEngineBase.transferred
+FNDA:3,RuleEngineBase.transferred
+DA:42,2
+DA:48,9
+FN:48,RuleEngineBase.transferred
+FNDA:9,RuleEngineBase.transferred
+DA:53,8
+DA:57,2
+FN:57,RuleEngineBase.created
+FNDA:2,RuleEngineBase.created
+DA:58,1
+DA:62,2
+FN:62,RuleEngineBase.destroyed
+FNDA:2,RuleEngineBase.destroyed
+DA:63,1
+DA:76,21
+FN:76,RuleEngineBase.detectTransferRestriction
+FNDA:21,RuleEngineBase.detectTransferRestriction
+DA:81,39
+DA:82,39
+DA:83,39
+DA:85,39
+BRDA:85,0,0,28
+DA:86,28
+DA:89,11
+DA:95,11
+FN:95,RuleEngineBase.detectTransferRestrictionFrom
+FNDA:11,RuleEngineBase.detectTransferRestrictionFrom
+DA:101,25
+DA:102,25
+DA:103,25
+DA:105,25
+BRDA:105,1,0,19
+DA:106,19
+DA:110,6
+DA:116,13
+FN:116,RuleEngineBase.messageForTransferRestriction
+FNDA:13,RuleEngineBase.messageForTransferRestriction
+DA:120,13
+DA:121,13
+DA:123,10
+DA:125,8
+BRDA:125,2,0,8
+DA:126,8
+DA:127,8
+DA:131,5
+DA:137,18
+FN:137,RuleEngineBase.canTransfer
+FNDA:18,RuleEngineBase.canTransfer
+DA:142,18
+DA:143,18
+DA:150,14
+FN:150,RuleEngineBase.canTransferFrom
+FNDA:14,RuleEngineBase.canTransferFrom
+DA:156,14
+DA:157,14
+DA:166,98
+FN:166,RuleEngineBase.hasRole
+FNDA:98,RuleEngineBase.hasRole
+DA:170,293
+BRDA:170,3,0,165
+BRDA:170,3,1,128
+DA:171,165
+DA:173,128
FNF:10
FNH:10
-LF:19
-LH:19
-BRF:1
-BRH:1
-end_of_record
-TN:
-SF:src/modules/RuleInternal.sol
-FN:19,RuleInternal._setRules
-FNDA:32,RuleInternal._setRules
-DA:20,32
-BRDA:20,0,0,2
-DA:21,2
-DA:23,30
-DA:24,48
-BRDA:24,1,0,2
-DA:25,2
-DA:27,2
-BRDA:27,2,0,2
-DA:28,2
-DA:30,44
-DA:31,44
-DA:33,44
-FN:43,RuleInternal._addRule
-FNDA:203,RuleInternal._addRule
-DA:44,203
-BRDA:44,3,0,2
-DA:45,2
-DA:47,2
-BRDA:47,4,0,2
-DA:48,2
-DA:50,199
-DA:51,199
-FN:64,RuleInternal._removeRule
-FNDA:55,RuleInternal._removeRule
-DA:69,55
-BRDA:69,5,0,2
-DA:70,2
-DA:72,53
-BRDA:72,6,0,4
-DA:73,4
-DA:75,53
-DA:76,53
-DA:77,53
-FN:84,RuleInternal._getRuleIndex
-FNDA:6,RuleInternal._getRuleIndex
-DA:88,6
-DA:89,6
-DA:90,10
-BRDA:90,7,0,4
-DA:91,4
-DA:94,6
-DA:97,2
-FNF:4
-FNH:4
-LF:29
-LH:29
-BRF:8
-BRH:8
+LF:40
+LH:40
+BRF:5
+BRH:5
end_of_record
TN:
-SF:src/rules/operation/RuleConditionalTransfer.sol
-FN:27,RuleConditionalTransfer.
-FNDA:158,RuleConditionalTransfer.
-DA:33,158
-BRDA:33,0,0,1
-DA:34,1
-DA:36,157
-DA:37,157
-BRDA:37,1,0,153
-DA:38,153
-DA:40,157
-FN:51,RuleConditionalTransfer.operateOnTransfer
-FNDA:50,RuleConditionalTransfer.operateOnTransfer
-DA:61,50
-BRDA:61,2,0,8
-BRDA:61,2,1,24
-DA:62,8
-DA:64,42
-DA:65,42
-BRDA:65,3,0,18
-BRDA:65,3,1,24
-DA:66,18
-DA:67,18
-DA:69,24
-FN:79,RuleConditionalTransfer.createTransferRequest
-FNDA:114,RuleConditionalTransfer.createTransferRequest
-DA:83,117
-DA:84,117
-DA:85,117
-BRDA:85,4,0,1
-DA:86,1
-DA:88,116
-BRDA:88,5,0,113
-BRDA:88,5,1,3
-DA:89,113
-DA:90,113
-DA:102,113
-DA:103,113
-DA:104,113
-DA:105,113
-DA:108,3
-DA:109,3
-DA:110,3
-FN:123,RuleConditionalTransfer.createTransferRequestBatch
-FNDA:3,RuleConditionalTransfer.createTransferRequestBatch
-DA:127,3
-BRDA:127,6,0,1
-DA:128,1
-DA:130,2
-BRDA:130,7,0,1
-DA:131,1
-DA:133,1
-DA:134,3
-FN:141,RuleConditionalTransfer.cancelTransferRequest
-FNDA:6,RuleConditionalTransfer.cancelTransferRequest
-DA:142,6
-FN:148,RuleConditionalTransfer.cancelTransferRequestBatch
-FNDA:3,RuleConditionalTransfer.cancelTransferRequestBatch
-DA:149,3
-BRDA:149,8,0,1
-DA:150,1
-DA:153,2
-DA:154,5
-BRDA:154,9,0,1
-DA:155,1
-DA:158,1
-DA:159,3
-FN:163,RuleConditionalTransfer.getRequestTrade
-FNDA:57,RuleConditionalTransfer.getRequestTrade
-DA:168,57
-DA:169,57
-FN:177,RuleConditionalTransfer.getRequestByStatus
-FNDA:35,RuleConditionalTransfer.getRequestByStatus
-DA:180,35
-DA:181,35
-DA:182,35
-DA:185,35
-DA:186,38
-BRDA:186,10,0,36
-DA:187,36
-DA:192,35
-DA:195,35
-DA:196,38
-BRDA:196,11,0,36
-DA:198,36
-DA:201,36
-DA:202,36
-DA:205,35
-FN:214,RuleConditionalTransfer.detectTransferRestriction
-FNDA:56,RuleConditionalTransfer.detectTransferRestriction
-DA:220,56
-BRDA:220,12,0,1
-DA:221,1
-DA:223,55
-DA:224,55
-BRDA:224,13,0,8
-BRDA:224,13,1,8
-DA:225,8
-DA:227,47
-FN:236,RuleConditionalTransfer.canReturnTransferRestrictionCode
-FNDA:2,RuleConditionalTransfer.canReturnTransferRestrictionCode
-DA:239,2
-FN:247,RuleConditionalTransfer.messageForTransferRestriction
-FNDA:3,RuleConditionalTransfer.messageForTransferRestriction
-DA:250,3
-BRDA:250,14,0,2
-BRDA:250,14,1,1
-DA:251,2
-DA:253,1
-FN:260,RuleConditionalTransfer._validateTransfer
-FNDA:106,RuleConditionalTransfer._validateTransfer
-DA:265,106
-BRDA:265,15,0,36
-DA:267,36
-DA:268,5
-DA:269,3
-BRDA:269,16,0,3
-DA:270,3
-DA:275,103
-BRDA:275,17,0,6
-DA:276,6
-DA:278,97
-FN:281,RuleConditionalTransfer._cancelTransferRequest
-FNDA:9,RuleConditionalTransfer._cancelTransferRequest
-DA:282,9
-BRDA:282,18,0,1
-DA:283,1
-DA:285,8
-DA:287,8
-BRDA:287,19,0,1
-DA:288,1
-DA:292,7
-DA:293,2
-DA:294,1
-BRDA:294,20,0,1
-DA:295,1
-DA:297,6
-FN:307,RuleConditionalTransfer._validateBurnMint
-FNDA:103,RuleConditionalTransfer._validateBurnMint
-DA:313,103
-DA:317,6
-BRDA:317,21,0,6
-DA:318,6
-DA:320,97
-FN:329,RuleConditionalTransfer._validateApproval
-FNDA:97,RuleConditionalTransfer._validateApproval
-DA:333,97
-DA:335,50
-DA:337,47
-DA:338,50
-BRDA:338,22,0,50
-DA:339,50
-DA:341,47
-DA:342,47
-DA:343,47
-DA:344,20
-BRDA:344,23,0,20
-BRDA:343,23,1,27
-DA:345,20
-DA:348,27
-BRDA:348,24,0,27
-DA:350,27
-DA:355,47
-BRDA:355,25,0,26
-BRDA:355,25,1,21
-DA:356,26
-DA:358,21
-FN:369,RuleConditionalTransfer._msgSender
-FNDA:829,RuleConditionalTransfer._msgSender
-DA:375,829
-FN:381,RuleConditionalTransfer._msgData
-FNDA:0,RuleConditionalTransfer._msgData
-DA:387,0
-FN:393,RuleConditionalTransfer._contextSuffixLength
-FNDA:829,RuleConditionalTransfer._contextSuffixLength
-DA:399,829
-FNF:18
-FNH:17
-LF:106
-LH:105
-BRF:33
-BRH:33
-end_of_record
-TN:
-SF:src/rules/operation/abstract/RuleConditionalTransferOperator.sol
-FN:32,RuleConditionalTransferOperator.setConditionalWhitelist
-FNDA:26,RuleConditionalTransferOperator.setConditionalWhitelist
-DA:35,26
-DA:36,26
-FN:42,RuleConditionalTransferOperator.setIssuanceOptions
-FNDA:7,RuleConditionalTransferOperator.setIssuanceOptions
-DA:46,6
-DA:48,3
-BRDA:48,0,0,3
-DA:49,3
-DA:53,6
-DA:55,3
-BRDA:55,1,0,3
-DA:56,3
-FN:66,RuleConditionalTransferOperator.setAutomaticTransfer
-FNDA:4,RuleConditionalTransferOperator.setAutomaticTransfer
-DA:70,3
-DA:72,2
-BRDA:72,2,0,2
-DA:73,2
-DA:78,3
-DA:80,2
-BRDA:80,3,0,2
-DA:81,2
-FN:90,RuleConditionalTransferOperator.setTimeLimit
-FNDA:5,RuleConditionalTransferOperator.setTimeLimit
-DA:94,4
-DA:96,4
-BRDA:96,4,0,4
-DA:97,4
-DA:101,4
-DA:103,4
-BRDA:103,5,0,4
-DA:104,4
-FN:114,RuleConditionalTransferOperator.setAutomaticApproval
-FNDA:10,RuleConditionalTransferOperator.setAutomaticApproval
-DA:118,9
-DA:120,6
-BRDA:120,6,0,6
-DA:121,6
-DA:125,9
-DA:127,9
-BRDA:127,7,0,9
-DA:128,9
-FN:138,RuleConditionalTransferOperator.createTransferRequestWithApproval
-FNDA:6,RuleConditionalTransferOperator.createTransferRequestWithApproval
-DA:141,5
-FN:150,RuleConditionalTransferOperator.approveTransferRequest
-FNDA:40,RuleConditionalTransferOperator.approveTransferRequest
-DA:155,39
-FN:161,RuleConditionalTransferOperator.approveTransferRequestWithId
-FNDA:5,RuleConditionalTransferOperator.approveTransferRequestWithId
-DA:165,4
-BRDA:165,8,0,2
-DA:166,2
-DA:168,2
-DA:171,2
-FN:177,RuleConditionalTransferOperator.resetRequestStatus
-FNDA:3,RuleConditionalTransferOperator.resetRequestStatus
-DA:180,2
-BRDA:180,9,0,1
-DA:181,1
-DA:183,1
-DA:184,1
-FN:191,RuleConditionalTransferOperator.approveTransferRequestBatchWithId
-FNDA:7,RuleConditionalTransferOperator.approveTransferRequestBatchWithId
-DA:195,5
-BRDA:195,10,0,1
-DA:196,1
-DA:198,4
-BRDA:198,11,0,1
-DA:199,1
-DA:202,3
-DA:203,11
-BRDA:203,12,0,1
-DA:204,1
-DA:207,2
-DA:208,5
-DA:211,5
-FN:218,RuleConditionalTransferOperator.approveTransferRequestBatch
-FNDA:7,RuleConditionalTransferOperator.approveTransferRequestBatch
-DA:223,6
-BRDA:223,13,0,1
-DA:224,1
-DA:227,5
-DA:229,3
-BRDA:229,14,0,3
-DA:230,3
-DA:232,2
-DA:233,9
-FN:244,RuleConditionalTransferOperator.createTransferRequestWithApprovalBatch
-FNDA:3,RuleConditionalTransferOperator.createTransferRequestWithApprovalBatch
-DA:247,2
-BRDA:247,15,0,1
-DA:248,1
-DA:250,1
-DA:251,4
-FN:258,RuleConditionalTransferOperator.resetRequestStatusBatch
-FNDA:3,RuleConditionalTransferOperator.resetRequestStatusBatch
-DA:261,3
-BRDA:261,16,0,1
-DA:262,1
-DA:265,2
-DA:266,4
-BRDA:266,17,0,1
-DA:267,1
-DA:270,1
-DA:271,3
-DA:272,3
-FN:280,RuleConditionalTransferOperator.hasRole
-FNDA:310,RuleConditionalTransferOperator.hasRole
-DA:285,704
-BRDA:285,18,0,137
-DA:286,137
-DA:288,567
-FN:294,RuleConditionalTransferOperator._approveTransferRequestKeyElement
-FNDA:48,RuleConditionalTransferOperator._approveTransferRequestKeyElement
-DA:299,48
-BRDA:299,19,0,1
-DA:300,1
-DA:302,47
-DA:305,47
-DA:306,47
-BRDA:306,20,0,9
-BRDA:306,20,1,8
-DA:307,9
-BRDA:307,21,0,1
-DA:308,1
-DA:311,8
-DA:313,8
-DA:321,38
-FN:325,RuleConditionalTransferOperator._createTransferRequestWithApproval
-FNDA:17,RuleConditionalTransferOperator._createTransferRequestWithApproval
-DA:331,17
-DA:334,17
-BRDA:334,22,0,16
-BRDA:334,22,1,1
-DA:336,16
-DA:346,16
-DA:347,16
-DA:348,16
-DA:355,16
-DA:359,1
-DA:362,1
-DA:363,1
-FN:373,RuleConditionalTransferOperator._resetRequestStatus
-FNDA:10,RuleConditionalTransferOperator._resetRequestStatus
-DA:374,10
-DA:375,10
-FN:387,RuleConditionalTransferOperator._checkRequestStatus
-FNDA:133,RuleConditionalTransferOperator._checkRequestStatus
-DA:389,133
-DA:390,133
-FN:394,RuleConditionalTransferOperator._approveRequest
-FNDA:53,RuleConditionalTransferOperator._approveRequest
-DA:399,53
-BRDA:399,23,0,1
-DA:400,1
-DA:402,32
-BRDA:402,24,0,32
-BRDA:402,24,1,20
-DA:405,32
-DA:407,3
-BRDA:407,25,0,3
-DA:408,3
-DA:411,29
-DA:413,29
-DA:416,29
-DA:424,29
-DA:425,7
-DA:426,7
-BRDA:426,26,0,7
-DA:430,7
-DA:434,3
-BRDA:434,27,0,3
-DA:436,3
-DA:444,20
-DA:445,20
-FN:458,RuleConditionalTransferOperator._updateProcessedTransfer
-FNDA:18,RuleConditionalTransferOperator._updateProcessedTransfer
-DA:460,18
-DA:461,18
-DA:463,18
-DA:465,18
-FNF:20
-FNH:20
-LF:113
-LH:113
-BRF:31
-BRH:31
-end_of_record
-TN:
-SF:src/rules/validation/RuleBlacklist.sol
-FN:22,RuleBlacklist.
-FNDA:12,RuleBlacklist.
-FN:33,RuleBlacklist.detectTransferRestriction
-FNDA:10,RuleBlacklist.detectTransferRestriction
-DA:38,10
-BRDA:38,0,0,5
-BRDA:38,0,1,3
-DA:39,5
-DA:40,5
-BRDA:40,1,0,2
-BRDA:40,1,1,3
-DA:41,2
-DA:43,3
-FN:52,RuleBlacklist.canReturnTransferRestrictionCode
-FNDA:4,RuleBlacklist.canReturnTransferRestrictionCode
-DA:55,4
-DA:56,4
-DA:57,2
-FN:65,RuleBlacklist.messageForTransferRestriction
-FNDA:4,RuleBlacklist.messageForTransferRestriction
-DA:68,4
-BRDA:68,2,0,2
-BRDA:68,2,1,1
-DA:69,2
-DA:70,2
-BRDA:70,3,0,1
-BRDA:70,3,1,1
-DA:71,1
-DA:73,1
-FNF:4
-FNH:4
-LF:13
-LH:13
-BRF:8
-BRH:8
-end_of_record
-TN:
-SF:src/rules/validation/RuleSanctionList.sol
-FN:26,RuleSanctionList.
-FNDA:13,RuleSanctionList.
-DA:31,13
-BRDA:31,0,0,1
-DA:32,1
-DA:34,12
-BRDA:34,1,0,1
-DA:35,1
-DA:37,12
-FN:45,RuleSanctionList.setSanctionListOracle
-FNDA:11,RuleSanctionList.setSanctionListOracle
-DA:48,10
-FN:57,RuleSanctionList.detectTransferRestriction
-FNDA:7,RuleSanctionList.detectTransferRestriction
-DA:62,7
-BRDA:62,2,0,7
-DA:63,7
-BRDA:63,3,0,2
-BRDA:63,3,1,3
-DA:64,2
-DA:65,5
-BRDA:65,4,0,2
+SF:src/modules/ERC3643ComplianceModule.sol
+DA:27,3
+FN:27,ERC3643ComplianceModule.onlyBoundToken
+FNDA:3,ERC3643ComplianceModule.onlyBoundToken
+DA:28,3
+BRDA:28,0,0,1
+DA:29,1
+DA:40,11
+FN:40,ERC3643ComplianceModule.bindToken
+FNDA:11,ERC3643ComplianceModule.bindToken
+DA:41,11
+DA:45,4
+FN:45,ERC3643ComplianceModule.unbindToken
+FNDA:4,ERC3643ComplianceModule.unbindToken
+DA:46,4
+DA:50,6
+FN:50,ERC3643ComplianceModule.isTokenBound
+FNDA:6,ERC3643ComplianceModule.isTokenBound
+DA:51,6
+DA:55,2
+FN:55,ERC3643ComplianceModule.getTokenBound
+FNDA:2,ERC3643ComplianceModule.getTokenBound
+DA:56,2
+BRDA:56,1,0,1
+BRDA:56,1,1,1
+DA:59,1
+DA:61,1
DA:66,2
-DA:69,3
-FN:77,RuleSanctionList.canReturnTransferRestrictionCode
-FNDA:3,RuleSanctionList.canReturnTransferRestrictionCode
-DA:80,3
+FN:66,ERC3643ComplianceModule.getTokenBounds
+FNDA:2,ERC3643ComplianceModule.getTokenBounds
+DA:67,2
+DA:76,4
+FN:76,ERC3643ComplianceModule._unbindToken
+FNDA:4,ERC3643ComplianceModule._unbindToken
+DA:77,4
+BRDA:77,2,0,1
+BRDA:77,2,1,3
+DA:79,3
+BRDA:79,3,0,-
+BRDA:79,3,1,3
DA:81,3
-DA:82,2
-FN:90,RuleSanctionList.messageForTransferRestriction
-FNDA:3,RuleSanctionList.messageForTransferRestriction
-DA:93,3
-BRDA:93,5,0,1
-BRDA:93,5,1,1
-DA:94,1
-DA:95,2
-BRDA:95,6,0,1
-BRDA:95,6,1,1
-DA:96,1
-DA:98,1
-FN:106,RuleSanctionList.hasRole
-FNDA:13,RuleSanctionList.hasRole
-DA:111,24
-BRDA:111,7,0,11
-DA:112,11
-DA:114,13
-FN:121,RuleSanctionList._setSanctionListOracle
-FNDA:11,RuleSanctionList._setSanctionListOracle
-DA:122,11
-DA:123,11
-FN:133,RuleSanctionList._msgSender
-FNDA:23,RuleSanctionList._msgSender
-DA:139,23
-FN:145,RuleSanctionList._msgData
-FNDA:0,RuleSanctionList._msgData
-DA:151,0
-FN:157,RuleSanctionList._contextSuffixLength
-FNDA:23,RuleSanctionList._contextSuffixLength
-DA:163,23
-FNF:10
-FNH:9
-LF:28
-LH:27
-BRF:11
+DA:83,26
+FN:83,ERC3643ComplianceModule._bindToken
+FNDA:26,ERC3643ComplianceModule._bindToken
+DA:84,26
+BRDA:84,4,0,1
+BRDA:84,4,1,25
+DA:85,25
+BRDA:85,5,0,1
+BRDA:85,5,1,24
+DA:87,24
+BRDA:87,6,0,-
+BRDA:87,6,1,24
+DA:88,24
+FNF:8
+FNH:8
+LF:24
+LH:24
+BRF:13
BRH:11
end_of_record
TN:
-SF:src/rules/validation/RuleWhitelist.sol
-FN:16,RuleWhitelist.
-FNDA:173,RuleWhitelist.
-FN:27,RuleWhitelist.detectTransferRestriction
-FNDA:28,RuleWhitelist.detectTransferRestriction
-DA:32,28
-BRDA:32,0,0,13
-BRDA:32,0,1,10
-DA:33,13
-DA:34,15
-BRDA:34,1,0,5
-BRDA:34,1,1,10
-DA:35,5
-DA:37,10
-FNF:2
-FNH:2
-LF:5
-LH:5
-BRF:4
-BRH:4
-end_of_record
-TN:
-SF:src/rules/validation/RuleWhitelistWrapper.sol
-FN:23,RuleWhitelistWrapper.
-FNDA:14,RuleWhitelistWrapper.
-DA:27,14
-BRDA:27,0,0,1
-DA:28,1
-DA:30,13
-FN:39,RuleWhitelistWrapper.detectTransferRestriction
-FNDA:11,RuleWhitelistWrapper.detectTransferRestriction
-DA:44,11
-DA:45,11
-DA:46,11
-DA:47,11
-DA:48,11
-DA:49,11
-DA:51,11
-DA:53,25
-DA:55,25
-BRDA:55,1,0,7
-DA:57,7
-DA:59,25
-BRDA:59,2,0,7
-DA:61,7
-DA:63,25
-BRDA:63,3,0,25
-DA:64,25
-DA:67,11
-BRDA:67,4,0,4
-BRDA:67,4,1,5
-DA:68,4
-DA:69,7
-BRDA:69,5,0,2
-BRDA:69,5,1,5
-DA:70,2
-DA:72,5
-FN:80,RuleWhitelistWrapper.hasRole
-FNDA:13,RuleWhitelistWrapper.hasRole
-DA:85,52
-BRDA:85,6,0,39
-DA:86,39
-DA:88,13
-FN:98,RuleWhitelistWrapper._msgSender
-FNDA:52,RuleWhitelistWrapper._msgSender
-DA:104,52
-FN:110,RuleWhitelistWrapper._msgData
-FNDA:0,RuleWhitelistWrapper._msgData
-DA:116,0
-FN:122,RuleWhitelistWrapper._contextSuffixLength
-FNDA:52,RuleWhitelistWrapper._contextSuffixLength
-DA:128,52
-FNF:6
-FNH:5
-LF:28
-LH:27
-BRF:9
-BRH:9
-end_of_record
-TN:
-SF:src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol
-FN:27,RuleAddressList.
-FNDA:185,RuleAddressList.
-DA:31,185
-BRDA:31,0,0,1
-DA:32,1
-DA:34,184
-FN:42,RuleAddressList.addAddressesToTheList
-FNDA:17,RuleAddressList.addAddressesToTheList
-DA:45,16
-DA:46,16
-FN:55,RuleAddressList.removeAddressesFromTheList
-FNDA:4,RuleAddressList.removeAddressesFromTheList
-DA:58,3
-DA:59,3
-FN:67,RuleAddressList.addAddressToTheList
-FNDA:52,RuleAddressList.addAddressToTheList
-DA:70,51
-DA:71,50
-FN:80,RuleAddressList.removeAddressFromTheList
-FNDA:3,RuleAddressList.removeAddressFromTheList
-DA:83,2
-DA:84,1
-FN:92,RuleAddressList.numberListedAddress
-FNDA:24,RuleAddressList.numberListedAddress
-DA:93,24
-FN:102,RuleAddressList.addressIsListed
-FNDA:101,RuleAddressList.addressIsListed
-DA:105,159
-FN:112,RuleAddressList.addressIsListedBatch
-FNDA:28,RuleAddressList.addressIsListedBatch
-DA:115,28
-DA:116,28
-DA:117,55
-DA:119,28
-FN:126,RuleAddressList.hasRole
-FNDA:194,RuleAddressList.hasRole
-DA:131,280
-BRDA:131,1,0,78
-DA:132,78
-DA:134,202
-FN:144,RuleAddressList._msgSender
-FNDA:270,RuleAddressList._msgSender
-DA:150,270
-FN:156,RuleAddressList._msgData
-FNDA:0,RuleAddressList._msgData
-DA:162,0
-FN:168,RuleAddressList._contextSuffixLength
-FNDA:270,RuleAddressList._contextSuffixLength
-DA:174,270
-FNF:12
-FNH:11
-LF:23
-LH:22
-BRF:2
-BRH:2
-end_of_record
-TN:
-SF:src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol
-FN:22,RuleAddressListInternal._addAddressesToThelist
-FNDA:16,RuleAddressListInternal._addAddressesToThelist
-DA:25,16
-DA:26,16
-DA:27,34
-BRDA:27,0,0,32
-DA:28,32
-DA:29,32
-DA:32,16
-FN:41,RuleAddressListInternal._removeAddressesFromThelist
-FNDA:3,RuleAddressListInternal._removeAddressesFromThelist
-DA:44,3
-DA:45,3
-DA:46,6
-BRDA:46,1,0,6
-DA:47,6
-DA:48,6
-DA:51,3
-FN:59,RuleAddressListInternal._addAddressToThelist
-FNDA:51,RuleAddressListInternal._addAddressToThelist
-DA:60,1
-BRDA:60,2,0,1
-DA:61,1
-DA:63,50
-DA:64,50
-FN:73,RuleAddressListInternal._removeAddressFromThelist
-FNDA:2,RuleAddressListInternal._removeAddressFromThelist
-DA:74,2
-BRDA:74,3,0,1
-DA:75,1
-DA:77,1
-DA:78,1
-FN:86,RuleAddressListInternal._numberListedAddress
-FNDA:24,RuleAddressListInternal._numberListedAddress
-DA:87,24
-FN:96,RuleAddressListInternal._addressIsListed
-FNDA:214,RuleAddressListInternal._addressIsListed
-DA:99,214
-FNF:6
-FNH:6
-LF:22
-LH:22
-BRF:4
-BRH:4
+SF:src/modules/RulesManagementModule.sol
+DA:36,34
+FN:36,RulesManagementModule.setRules
+FNDA:34,RulesManagementModule.setRules
+DA:39,33
+BRDA:39,0,0,4
+DA:40,4
+DA:42,29
+BRDA:42,1,0,27
+DA:43,27
+DA:45,29
+DA:46,47
+DA:48,45
+BRDA:48,2,0,-
+BRDA:48,2,1,45
+DA:49,45
+DA:56,10
+FN:56,RulesManagementModule.clearRules
+FNDA:10,RulesManagementModule.clearRules
+DA:57,9
+DA:63,95
+FN:63,RulesManagementModule.addRule
+FNDA:95,RulesManagementModule.addRule
+DA:66,94
+DA:67,90
+BRDA:67,3,0,-
+BRDA:67,3,1,90
+DA:68,90
+DA:74,11
+FN:74,RulesManagementModule.removeRule
+FNDA:11,RulesManagementModule.removeRule
+DA:77,10
+BRDA:77,4,0,2
+BRDA:77,4,1,8
+DA:78,8
+DA:86,115
+FN:86,RulesManagementModule.rulesCount
+FNDA:115,RulesManagementModule.rulesCount
+DA:87,192
+DA:93,35
+FN:93,RulesManagementModule.containsRule
+FNDA:35,RulesManagementModule.containsRule
+DA:94,35
+DA:101,3
+FN:101,RulesManagementModule.rule
+FNDA:3,RulesManagementModule.rule
+DA:104,85
+BRDA:104,5,0,84
+BRDA:104,5,1,1
+DA:107,84
+DA:109,1
+DA:116,10
+FN:116,RulesManagementModule.rules
+FNDA:10,RulesManagementModule.rules
+DA:123,10
+DA:133,36
+FN:133,RulesManagementModule._clearRules
+FNDA:36,RulesManagementModule._clearRules
+DA:134,36
+DA:135,36
+DA:145,8
+FN:145,RulesManagementModule._removeRule
+FNDA:8,RulesManagementModule._removeRule
+DA:147,8
+BRDA:147,6,0,-
+BRDA:147,6,1,8
+DA:148,8
+DA:154,141
+FN:154,RulesManagementModule._checkRule
+FNDA:141,RulesManagementModule._checkRule
+DA:155,141
+BRDA:155,7,0,2
+DA:156,2
+DA:158,139
+BRDA:158,8,0,4
+DA:159,4
+DA:172,10
+FN:172,RulesManagementModule._transferred
+FNDA:10,RulesManagementModule._transferred
+DA:177,10
+DA:178,10
+DA:179,7
+DA:194,2
+FN:194,RulesManagementModule._transferred
+FNDA:2,RulesManagementModule._transferred
+DA:200,2
+DA:201,2
+DA:202,2
+FNF:13
+FNH:13
+LF:47
+LH:47
+BRF:14
+BRH:11
end_of_record
TN:
-SF:src/rules/validation/abstract/RuleValidateTransfer.sol
-FN:15,RuleValidateTransfer.validateTransfer
-FNDA:40,RuleValidateTransfer.validateTransfer
-DA:21,40
-DA:22,40
+SF:src/modules/VersionModule.sol
+DA:21,1
+FN:21,VersionModule.version
+FNDA:1,VersionModule.version
+DA:22,1
FNF:1
FNH:1
LF:2
@@ -997,95 +274,3 @@ LH:2
BRF:0
BRH:0
end_of_record
-TN:
-SF:src/rules/validation/abstract/RuleWhitelistCommon.sol
-FN:17,RuleWhitelistCommon.canReturnTransferRestrictionCode
-FNDA:12,RuleWhitelistCommon.canReturnTransferRestrictionCode
-DA:20,12
-DA:21,12
-DA:22,6
-FN:30,RuleWhitelistCommon.messageForTransferRestriction
-FNDA:10,RuleWhitelistCommon.messageForTransferRestriction
-DA:33,10
-BRDA:33,0,0,6
-BRDA:33,0,1,1
-DA:34,6
-DA:35,4
-BRDA:35,1,0,3
-BRDA:35,1,1,1
-DA:36,3
-DA:38,1
-FNF:2
-FNH:2
-LF:8
-LH:8
-BRF:4
-BRH:4
-end_of_record
-TN:
-SF:test/HelperContract.sol
-FN:95,HelperContract.
-FNDA:0,HelperContract.
-FNF:1
-FNH:0
-LF:0
-LH:0
-BRF:0
-BRH:0
-end_of_record
-TN:
-SF:test/RuleConditionalTransfer/utils/RuleCTDeployment.sol
-FN:13,RuleCTDeployment.
-FNDA:13,RuleCTDeployment.
-DA:14,13
-DA:19,13
-DA:24,13
-DA:28,13
-DA:33,13
-DA:39,13
-DA:44,13
-DA:45,13
-DA:51,13
-DA:52,13
-FNF:1
-FNH:1
-LF:10
-LH:10
-BRF:0
-BRH:0
-end_of_record
-TN:
-SF:test/utils/CMTATDeployment.sol
-FN:15,CMTATDeployment.
-FNDA:86,CMTATDeployment.
-DA:17,86
-DA:23,86
-DA:30,86
-DA:36,86
-FNF:1
-FNH:1
-LF:4
-LH:4
-BRF:0
-BRH:0
-end_of_record
-TN:
-SF:test/utils/SanctionListOracle.sol
-FN:9,SanctionListOracle.
-FNDA:11,SanctionListOracle.
-FN:13,SanctionListOracle.addToSanctionsList
-FNDA:10,SanctionListOracle.addToSanctionsList
-DA:14,10
-FN:17,SanctionListOracle.removeFromSanctionsList
-FNDA:0,SanctionListOracle.removeFromSanctionsList
-DA:18,0
-FN:21,SanctionListOracle.isSanctioned
-FNDA:12,SanctionListOracle.isSanctioned
-DA:22,12
-FNF:4
-FNH:3
-LF:3
-LH:2
-BRF:0
-BRH:0
-end_of_record
diff --git a/doc/functionalities.odt b/doc/functionalities.odt
deleted file mode 100644
index 3ff1fd4..0000000
Binary files a/doc/functionalities.odt and /dev/null differ
diff --git a/doc/functionalities.pdf b/doc/functionalities.pdf
deleted file mode 100644
index 7c5cf1c..0000000
Binary files a/doc/functionalities.pdf and /dev/null differ
diff --git a/doc/other/CMTAT/checkTransferred.png b/doc/other/CMTAT/checkTransferred.png
new file mode 100644
index 0000000..317ff56
Binary files /dev/null and b/doc/other/CMTAT/checkTransferred.png differ
diff --git a/doc/other/CMTAT/transferred.png b/doc/other/CMTAT/transferred.png
new file mode 100644
index 0000000..f378b43
Binary files /dev/null and b/doc/other/CMTAT/transferred.png differ
diff --git a/doc/schema/Engine-RuleEngine.drawio.png b/doc/schema/Engine-RuleEngine.drawio.png
deleted file mode 100644
index ceccf1e..0000000
Binary files a/doc/schema/Engine-RuleEngine.drawio.png and /dev/null differ
diff --git a/doc/schema/RuleEngine b/doc/schema/RuleEngine
deleted file mode 100644
index e908186..0000000
--- a/doc/schema/RuleEngine
+++ /dev/null
@@ -1 +0,0 @@
-1VpLc+I4EP41VO0e4rIkP/AxkMzMYac2NWEnm70JW4AqxqJkMcD8+pWxbCzJBEIwIblEar3s7q+/7hbuoeF8/ZXjxew7S0jag26y7qG7HoQA+VD+KySbUuL3+6VgymmiJu0Ej/Q3UUJXSZc0Ibk2UTCWCrrQhTHLMhILTYY5Zyt92oSl+qkLPCWW4DHGqS19oomYlVKIULAb+EbodFYdHfheOTLH1Wz1KvkMJ2zVEKH7HhpyxkTZmq+HJC20VymmXPdlz2j9ZJxk4pgF3og/hzzA5Gnz9/PLqj/65+d/N2qXXzhdqjcefh/djtQTi02lh9WMCvK4wHHRX0lb99BgJuap7AHZxPmi1P6Erok8b2A/XHUS4YKsGyL1sF8JmxPBN3KKGoWhUpyCDvD9sr/aGQJUc2ZNG1RCrIw/rffeqUc2lIbeoC1oaQs4guMsnxD+h2A9OKxG/7Q0SLLktgCk7MUpznMa6yrkbJklhe7uXNmTauObf2XnxnVcACvJczHseCisBHfr5oK7TbP3QDiV7024Eu61icB8SsRhlJBEcxbbcg3L+C2GqWScpFjQX7qLtRlLnfDAqHziGhgA6sCAyLB3zpY8JmpV0yOMjWBgICwyNioVY220xU792qfDCVlwGrEXkhVakzwl7WZiSFLIomgu5+ltLJg07KDwJyr56i88JukDy6mgLJNTxkwINm9MuE3ptBgQzPBdthQpzciwZtBXsXK8//qGlSpKb4AEtYAk6Mp5PUvb5/JRV3dP/4Bz7tVtidvDfnjQX/2r8tcA6UhA7on+GkQGpEysdOyvgYUg6MgOTbAgIxUGbExJI2yd04iYyh1jCQLCW/x0TpOk2GPASU5/4/F2vwI+i+L1ti/sD3r+XSugXnUA04Pr7EkdouUnbZ7tOqgfIt0UZ0HKDQy1XW/6+g5sMslJJ6b1LdP+WKbkPptKZrRM+gHJkN+/umQo7IxPgc6n4cmE+skSG9PIsI9OJErP3OiyRNm3oCG4bEFXpiyyCMNpbjvV9fBkBewz8KQXeUBnNPA+pHTPhJFlO4SdRJYRsahi3A+SC07jbab5MSkUWVNRM4VsPzfkuyVF5/1Jl38sl7hXRSaBb0UMx238GRseSy1916AWeFlqqbRsRGopqa5ZdljUsXYgap8hSEeGbiK74qlr14uUPMC+sFDKAlenLOi2ZDSX1ZZdj3sXp77uUh14VfQUmtcD3olFYWgWhf6FCelt9woZy4pkJcH5bAsFoGOkkD9gIVOdbCuBLpJSiTn2Ul9AQxtLKhyqwNlxQARHR8TrglzkehpSUFVDvRVykZleB8ZGXUOuvVqVEpuUPprWkffhtN5WqAapPHYwlo1p0SDO1JFTngr1pDQvbM23Gi3nyXPrqZaGpWKErsbSXYcsLW5oK4+f0DQ1RMfXNm120y17BtMBFxzOX7wW03X3e4sdkf3LFyPwlGoEdES+R3Pvdd0Bh4EVpc9RjUTmT0Heq0VOx7wM7VTAGzt8B9AhS1ouPi5zSVbnCM0MQS3rIkmARwL1unEKgrNUzZHBrMD8yXIPMiUw8KYxTd1p7X18qzoPtW8CZKPc8bywtwOs3xnsm0h/brrBG2DfFTcfnRhfF+YtEg3Ows0W5UfQOS5P3o/6szO2fVONxl0RtuMCXydt4KEuWPttX38chrX7OWENPg2s95A5NGPRu8hcdncfm5XTd9/sofv/AQ==
\ No newline at end of file
diff --git a/doc/schema/RuleEngine.drawio b/doc/schema/RuleEngine.drawio
new file mode 100644
index 0000000..dfe33f6
--- /dev/null
+++ b/doc/schema/RuleEngine.drawio
@@ -0,0 +1 @@
+5VpNk+I2EP01VG0OULbkD3zkY7I5ZGtmdyaZmdwMFqBaYxFZLLC/PpItY8sS4CEYSIULVlu07NdPr9USHThabj/TcLX4QiIUd4AVbTtw3AHA9nzIv4Rll1u8AOSGOcWR7FQanvFPJI2WtK5xhFKlIyMkZnilGqckSdCUKbaQUrJRu81IrI66CudIMzxPw1i3vuKILXIrgNArb/yG8HxRDO25Tn5nGRa95aukizAim4oJPnTgiBLC8qvldoRigV4BTP67Xw/c3T8ZRQlr8gPnhb771AvR6+7x/fum//LHn391pZcfYbyWbzz68jJ4kU/MdgUOmwVm6HkVTkV7w2PdgcMFW8a8ZfPLMF3l6M/wFvHxhjOSMBlN2+Vt/WGLkRFlaFsxyYf/jMgSMbrjXeRd4AS9oPrxcw+SWbYvcd6UcbKhtC2qISqMoeTGfD9UiR6/kAB+AEyogflCvqNEjM95h6iGKqfESlyul/FgygjlQAk8MOff7+EExU8kxQyThHeZEMbIstJhEOO5uMFILRZkzWKcoNF+RljtxMOzFPyB5Wr4m+D32kLf0dDX8EZJNBCiwFvTOExTPFWho2SdRIK/GWZoi9mbuNOzrL5sv4t7PRcW7fG20nm8qzSeEMX8xXjUzRHgwNPdW/ED0ZC+i2bpOmsVvg9GLiVrOkWn5zoL6RyxI/1kHFGkSKPOg0qgXUOgCxtFccjwD1VQTdGXIzwRzN+spBnk+AOVar6reslfXf6wKoE1X65f46xTI2OOjeYo4+P+zc+nqKdRFPQYDZN0hijlvAPWpxnlsxyMsjyXf2e9f9G5zMOTiURNiaUsTDk9EDXoxRJHkfAxpCjFP8NJ5k8QayXeOsPBHXbccSPRODoR60qyz9JyUCUPmhTG6sF+sYAoInYRTnWh6rVr91UXZDZLUSsUcDUKfFvH6CGZc8m+x6zrWeqUsV1d5vepV0mzfltCH2gQwlCdRv9O9s8U5n26qKaKo2micbhOSrvbUNqLZfW9aLuvkYvn2vJTc9hU5vugJvPgujJfoFyb5NxSlAIlN1XunZjwLczvoIZVYFhFg2su42xwCDz77sEzrYGvjJ5eg8BJT0jDzfWxMf6nVQzclYr5p1aVjXXLrjlyr6xbHyuhEpKIdWQUpouMHLbKGmF/ChlfhSaZBViQW1NGeU1c7KWAg0WX5NOV86jdOJHeFwUD4CjMge6ZFVJQr+q9mqO2KWheH3NLcvfqD52bq79vmMBezIcdThTsvL/XYtsxQ6WbZrAMRIZ1V9sMm+I+v5qLb9SbiyTyKjCOcSoIQ7Ow5M75w06KrlqYOJpMjUWuASMSix2vQkZmOI5rpua1rCn4Kj1aiL9tOf2TayfHEP/WKiNgyP7T62R/cE55ZF9J1hur+n1tffl9bT1wifIocOrrlaNV1+UUfzbZvD0uif01XbtfHzeDYDFeGE4gWmLoeevTGhXO4x9syr9bss0G+kYrPHMZYfuaL7vf2krCyCu9jLSrSsgvP93rDmvjnVOVjYen18EU1rV6ju0FatAvwibgKk73helFd1iNb6znwIdvoy70HCjCLw7kUi3Ul9loNcRNU4tzjzehZ1hctHa8aQT28gdsV1fqqgIfJs/NqrhaXj5XfUGgK7lzXfXVyzjwf1Rf59rqK704bZxnGd/QVHHeRBSMxy/7TaSPVBgfXfIdy0LNDttvJTgOn5WWW8k5atLOUhKs3HbO0yPXD3oQlAVGXZrsntc/PErLStU3KNV/7kz+kprlH9Ws9s7kgbrg6V5Awniz/H9d3r38myJ8+Ac=
\ No newline at end of file
diff --git a/doc/schema/RuleEngine.drawio.png b/doc/schema/RuleEngine.drawio.png
new file mode 100644
index 0000000..0004966
Binary files /dev/null and b/doc/schema/RuleEngine.drawio.png differ
diff --git a/doc/schema/RuleEngine.png b/doc/schema/RuleEngine.png
deleted file mode 100644
index 3e891c6..0000000
Binary files a/doc/schema/RuleEngine.png and /dev/null differ
diff --git a/doc/schema/RuleEngine.svg b/doc/schema/RuleEngine.svg
deleted file mode 100644
index f597ee9..0000000
--- a/doc/schema/RuleEngine.svg
+++ /dev/null
@@ -1,596 +0,0 @@
-
-
-
-
-
diff --git a/doc/schema/classDiagram.svg b/doc/schema/classDiagram.svg
index f407eb7..d3a0e65 100644
--- a/doc/schema/classDiagram.svg
+++ b/doc/schema/classDiagram.svg
@@ -4,1005 +4,1539 @@
-