Stable Credits are decentralized complementary currencies within on-chain mutual credit networks.
The main problem most mutual credit networks face is achieving sustainable stability at scale. To address this problem, Stable Credit networks enable external risk management infrastructure to analyze and mitigate credit risks.
This diagram depicts the key stabilizing mechanisms that make up the StableCredit protocol. |
Each StableCredit is outfitted with an AssurancePool that is responsible for providing credit networks with the means to autonomously manage credit risk. The AssurancePool is responsible for storing reserve deposits that are used to incentive the reduction of bad debt introduced by the decoupling of StableCredits and the original minter's debt balance. More information on StableCredit risk management can be found here.
StableCredit.sol
: An extension of the baseMutualCredit.sol
andERC20.sol
contracts responsible for managing positive and negative balances of network members.AccessManager.sol
: Responsible for role based access control of Stable Credit networks.CreditIssuer.sol
: Responsible for issuing credit lines to network members and storing/managing credit periodsAssurancePool.sol
: Responsible for assuring the value of each stable credit by maintaining network reserve funds according to the analyzed risk of the network.AssuranceOracle.sol
: Responsible for serving the necessary data to network contracts to assist in managing network credit risk.
- Admin - Capable of granting/revoking all other role access as well as reassigning contract connections within the protocol.
Note The
ADMIN_OWNER_ADDRESS
provided in the.env
file is granted the admin role at network deployment. Addresses granted this role should be as limited as possible, ideally a Gnosis Safe, as addresses with this role have the ability to cause irreversible damage to the network.
-
Operator - Capable of granting/revoking member access as well as the following:
- initialize new credit lines
- update existing credit terms
- pause/unpause credit periods
- pause/unpause fee collection
- update base fee rate
- update reserve token
- update deposit token
- withdraw/reallocate excess reserve balance
-
Member - Capable of the following:
- transfer stable credits
- utilize an issued credit line to mint stable credits
- repay credit balances of credits with reserve tokens
- burn lost debt using stable credits
This project uses Foundry for the development framework and Hardhat for the deployment framework.
- Install foundry dependencies
forge install
- Install node dependencies
yarn install
- Next, duplicate the
.env.example
file and rename it to.env
. Register for an Infura account and add your api key to the.env
file along with the other example values:
INFURA_API_KEY=<YOUR_API_KEY>
To compile the contracts, run:
yarn compile
Note After compilation, the hardhat TypeChain extension automatically generates TypeScript bindings for each contract. These bindings can be found in the
/types
directory.
yarn test
forge coverage
Note This project enables upgradeability via the OpenZeppelin Hardhat Upgrades method. More info on upgradable contracts can be found here. For details on ownership and upgrading, follow this tutorial.
Generate your local deployer account that will be used to deploy your contracts.
yarn generate
This will create a .txt
file containing the seed phrase of your deploy account. The file's name is the account's address. Be sure to fund this account before proceeding.
To deploy to a specific network, be sure to update the networks
field in the hardhat.config.ts file.
yarn deploy-network --<NETWORK_NAME>
This will run the Openzeppelin Hardhat upgrades plugin script that deploys the proxies and implementation contracts that make up the new network.
Note During deployment, an admin contract is also deployed. Only the owner of the admin contract has the ability to upgrade the deployed contracts. Ownership is transferred to the address supplied to the
ADMIN_OWNER_ADDRESS
field in your configured.env
file. For increased security, you should transfer control of upgrades to a Gnosis Safe.
Note Example automation infrastructure OpenZeppelin Defender or Gelato
In order to reduce the cost of gas for network participants, some state synchronization is delayed. To ensure that state stays synchronized in a predictable and timely manner, the following functions should be called on configured time intervals:
Function | Contract | Details | Suggested Interval |
---|---|---|---|
syncCreditPeriod(address member) |
CreditIssuer.sol | Should be called at the end of the provided member's credit period in order to prompt renewal or credit default. | EO Credit period |
allocate() |
AssurancePool.sol | Enables caller to allocate unallocated reserve tokens into the needed reserve balance. | daily |
convertDeposits() |
AssurancePool.sol | Enables caller to swap collected deposit tokens for reserve tokens and allocate into the necessary RTD dependant reserve. (only necessary if deposit token differs from reserve token) | daily |