Overview
Application Handler
Purpose
The Application Handler supports the Application Manager by storing the application level rules data and functions. Procotol supported asset handler contracts call the check-application-level-rules function
via the Application Manager. The Application Manager then checks the associated Application Handler where application level rule data is stored. The Application Handler contract also serves as the Application Manager’s connection to the protocol rule processor diamond for the application level rules.
Application Level Rules
Application level rules apply to all assets associated to the Application Manager and handler when set to active. The Application Handler facilitates the rule checks for each application level rule. The first function called by the Application Manager is:
This function allows the Application Manager to know if any application level rules are active and if the call should continue to the handler to check the active rules.
Rule Functions
The Application Handler is responsible for setting each application level rule to active or inactive accordingly. Only Rule Administrators may set the status of a rule.
Application Manager
Purpose
The Application Manager acts as a central hub for managing the application it is associated with.
It provides the ability to manage metadata for accounts associated with the application including:
- Roles
- Tags
- Risk Scores
- Access Levels
The Application Manager also provides the ability to check application level rules via its associated Application Handler.
Admin Roles
The Application Manager can be utilized for both updating and checking an account’s role in relation to the application. These capabilites are provided for the following roles:
Super Admin Special Case
The functions are slightly different for a Super Admin. Because there can only be one super admin at a time we use a two-step process to set a new one. The following functions are used in place of the add function the other admin types employ:
The first part of the two-step process, to propose the new Super Admin address. This can only be called by the existing Super admin.
The second part of the two-step process, confirming renounces the role for the existing Super Admin and promotes the Proposed Super Admin to the role. This can only be called by the Proposed Super Admin.
Access Levels, Risk Scores and Tags
The AppManager contains the functionality used to manage the Access Levels, Risk Scores and Tags associated with accounts, with respect to the application it manages.
Associated Contracts
The Application Manager also contains the functionality to register, deregister and check various related contracts, including:
- The Application Handler
- Protocol Compliant Tokens
- Treasury
Protocol Asset Handler Diamond Structure
Purpose
The Protocol Asset Handler Diamond serves as the access point to the protocol for a protocol supported asset. The protocol supported asset stores the Handler Diamond proxy address and uses it to call the check all rules function
. The Handler Diamond stores all asset level rule data, rule activation status, and connects the token to the App Manager for role based access control.
Asset level rules are set by Rule administrators. When setting a rule status in the Handler the protocol supplied rule id for each rule and the action type are required for the set-rule function
. The Handler Diamond stores each action type and rule together within the Rule Storage Facet.
Each Protocol supported asset type (ERC20, ERC721, etc) will need one handler diamond deployed and connected to the asset. The Handler diamond architecture will remain the same for each asset type. The asset handler diamond will consist of a proxy contract, libraries, storage facets and unique facets for that type. The unique facets for the asset type are found here:
Common Contracts
Each asset handler diamond will inherit from the following contracts:
- HandlerBase.sol
- HandlerUtils.sol
- HandlerDiamondLib.sol
- RuleStorage.sol
- StorageLib.sol
- TradingRulesFacet.sol
Protocol ERC 20
Purpose
The Protocol ERC 20 defines the base that contracts must conform to in order to be compatible with the protocol. Using the protocol ERC 20 does not restrict you from inheriting from other internal or external contracts, such as other OpenZeppelin contracts or custom logic contracts specific to your application.
Structure
The Protocol ERC 20 inherits from multiple contracts (internal and external), overrides functions from some of the inherited contracts, and defines a few functions of its own. The following contracts are inherited:
- ERC20 (external to the protocol)
- ERC165 (external to the protocol)
- EC20Burnable (external to the protocol)
- ERC20FlashMint (external to the protocol)
- ProtocolTokenCommon (internal to the protocol)
- IProtocolERX20Errors (internal to the protocol)
Protocol ERC 721
Purpose
The Protocol ERC 721 defines the base that contracts must conform to in order to be compatible with the protocol. Using the protocol ERC 721 does not restrict you from inheriting from other internal or external contracts, such as other OpenZeppelin contracts or custom logic contracts specific to your application.
Structure
The Protocol ERC 721 inherits from multiple contracts (internal and external), overrides functions from some of the inherited contracts, and defines a few functions of its own. The following contracts are inherited:
- ERC721Burnable (external to the protocol)
- ERC721URIStorage (external to the protocol)
- ERC721Enumerable (external to the protocol)
- ProtocolTokenCommon (internal to the protocol)
- AppAdministratorOrOwnerOnly (internal to the protocol)
Protocol Rule Processor Diamond
Purpose
The Rule Processor Diamond is a proxy contract that is used by application contracts to assess economic actions against rules that are active within that handler. The Rule Processor will delegate those calls to the appropriate facet contract, allowing for efficient on chain rule assessments per transaction. The Rule Processor Diamond proxy also acts as a single source address for the creation of rules for application contracts. Rule administrators of an application are allowed to add rules to the Rule Processor storage. These rules are immutable once created and can be shared across different applications with the rule id number generated by the protocol.
The Rule Processor diamond architecture consists of the Rule Processor Diamond, Rule Processor Diamond Libraries and supporting Rule Processor Facets. The library contracts store supporting functions for upgrading the diamond, connecting new facets, validating rule existence and supporting rule checks. The facet contracts fall into two categories: Storage Contracts and Processor Contracts. Storage contracts contain the data associated with a specific rule and the corresponding Processor contract contains the functions used to validate transactions relevant to the rule on chain.
see diamond diagram
Protocol Rule Processor Diamond Facets
Purpose
The Rule Processor Diamond Facets are where rule adding and rule check functions are stored in the protocol. Storage facets store the add rule functions for each rule type. Processor facets store the rule check functions and are called by an application’s handler contracts. Facets can be added or removed by the diamond to allow for upgrades to functionality of the diamond. Application contracts never call the facets directly and will only ever interact with the Rule Processor Proxy.
see facet list
Protocol Rule Processor Diamond Libraries
Purpose
The Rule Processor Diamond Libraries store functions used by the diamond structure. The Rule Processor Diamond Lib contract holds the function to store rules when added to the protocol, the diamond cut function for upgrading the diamond and adding or removing functions from facets. The Rule Processor Common Lib holds functions used throughout the facets to validate rules and parameters passed to the rule check functions.
Using these singular library contracts prevents data storage collision as functionality is added or removed from the protocol. Facets should always be removed through the diamond cut function in Rule Processor Diamond Lib.This prevents a situation where a facet may have been self destructed but the function selectors are still stored in the diamond. This could result in a “false posistive” successful transaction when attempting to add a rule and the rule is never added to the diamond. Protocol Rule Processor facets are never written with self destruct functionality.