This section explains how the smart contracts of the decentralized application work. Their hierarchy, intercommunications (relationships) and main responsibilities.
The main characteristic the dApp’s smart contracts structure is that it is built with the idea to provide immutable data storage and immutability of the data-handling logic for the covered projects and investment insurances, while at the same time preserve the dApp’s upgradability and the ability a certain problem to be fixed if necessary
Immutability & Upgradability¶
When an investor makes new insurance of his investment, it is always handled by the same contracts that were in use by the dApp at the moment the insurance request was made. That means there is no possibility of anyone to change the logic of how your insurance is stored and managed on the blockchain.
If the network (dApp) is upgraded in any way, it will not affect the existing projects, investment protections and the funds associated with them. The changes will affect only the projects added after the change and the insurances made for the investments in them.
There are publicly published articles and documentation for every update of the dApp’s smart contracts, including code changes, fixes, new features and other changes.
The smart contracts used by the dApp are divided into 2 main types:
- Permanent: (irreplaceable) core contracts containing the data storage;
- Upgradable: contracts containing logic and data fetching functions;
Furthermore, the upgradable contracts are separated into 2 sub-types depending on their level of interaction with the permanent storage contracts of the dApp:
- Controllers: contain the data-handling logic for the individual covered projects and investment protections. Controllers are the only contracts that can directly change user and project data in the storage. Each one is responsible for a different set of functionality related to the different stages of the lifecycle of a covered project and the investment insurances requested for it.
- Network contracts: can read from the storage and set global settings, but can not manipulate user and project related data. May also be used by a controller as an extension providing additional logic;
To better understand the dApps’s structure let’s see what the
visual representation of a call to the
requestRefundWithdraw() function looks like. This function
sets the amount of funds that must be refunded to an investor
to his withdrawable balance, in case of a project failure.
- Bob requests his refund for the project ‘X’ by calling
requestRefundWithdraw()from the main (entry point) contract, which has a routing (proxy) role.
- It fetches from
the storage the exact controller contract that was in use when
Bob requested his investment insurance and makes a call to
- It contains the logic needed for the call to be executed. The controller communicates with the storage to make the modifications of the user data affected by the execution of the call.
In case Alice requests investment insurance for Project ‘Y’ that was covered (listed) further in time, the same function call can be executed by a different controller, depending on whether the dApp was updated or not during that time. In both cases, once the insurance is made the contracts managing it can never be changed.
- Primary Storage
- Secondary Storage
- Refund Pool
- Affiliates Escrow
- RefundEther Token
- Project Controller
- Refund Controller
- Dispute Controller
- Utility Controller
- Main (Entry) Contract
- View Contract
- Event Logger
- Open Zeppelin’s Reentrancy Guard
- Open Zeppelin’s Roles
- Open Zeppelin’s SafeMath
See contracts’ addresses and source code in the Contracts section.