diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index fc50d58..0000000
--- a/.eslintignore
+++ /dev/null
@@ -1,5 +0,0 @@
-node_modules
-artifacts
-cache
-coverage
-money-streaming-intro-foundry/lib
\ No newline at end of file
diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index 9d42f5a..0000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "env": {
- "commonjs": true,
- "es2021": true,
- "node": true
- },
- "extends": "eslint:recommended",
- "parserOptions": {
- "ecmaVersion": "latest"
- },
- "rules": {}
-}
diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index a882f24..0000000
--- a/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-*.sh linguist-detectable=false
diff --git a/.github/workflows/build-examples.yml b/.github/workflows/build-examples.yml
index 5d4708d..29adbe1 100644
--- a/.github/workflows/build-examples.yml
+++ b/.github/workflows/build-examples.yml
@@ -10,31 +10,6 @@ on:
workflow_dispatch:
jobs:
- build-example:
- name: Build Example
- runs-on: ubuntu-latest
- env:
- CI: false # might not need this. this refers to react ui related things.
- strategy:
- # build all examples independently
- fail-fast: false
- matrix:
- project: ["tradeable-cashflow", "borrow-against-salary", "instant-distribution-intro","superfluid-gelato-automation", "money-streaming-intro/money-streaming-intro-hardhat"]
- install: ["clean-install"]
- node-version: [16]
- steps:
- - uses: actions/checkout@v3
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v3
- with:
- node-version: ${{ matrix.node-version }}
- - name: Install, Build, and Test
- run: |
- cd "projects/${{ matrix.project }}"
- yarn install
- yarn build
- yarn test
-
build-foundry-example:
name: Build Foundry Examples
runs-on: ubuntu-latest
@@ -42,15 +17,10 @@ jobs:
# build all examples independently
fail-fast: false
matrix:
- project: ["money-streaming-intro/money-streaming-intro-foundry"]
+ project: ["money-streaming-intro-foundry", "gda-advertisement-auction"]
install: ["clean-install"]
- node-version: [16]
steps:
- uses: actions/checkout@v3
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v3
- with:
- node-version: ${{ matrix.node-version }}
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
@@ -58,7 +28,6 @@ jobs:
- name: Install, Build, and Test
run: |
cd "projects/${{ matrix.project }}"
- forge install superfluid-protocol-monorepo=https://github.com/superfluid-finance/protocol-monorepo@dev --no-commit
- forge install https://github.com/OpenZeppelin/openzeppelin-contracts@v4.9.3 --no-commit
+ forge install
forge build
forge test
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..8f4ae33
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,18 @@
+[submodule "projects/money-streaming-intro-foundry/lib/superfluid-protocol-monorepo"]
+ path = projects/money-streaming-intro-foundry/lib/superfluid-protocol-monorepo
+ url = https://github.com/superfluid-finance/protocol-monorepo
+[submodule "projects/money-streaming-intro-foundry/lib/openzeppelin-contracts"]
+ path = projects/money-streaming-intro-foundry/lib/openzeppelin-contracts
+ url = https://github.com/OpenZeppelin/openzeppelin-contracts
+[submodule "projects/money-streaming-intro-foundry/lib/forge-std"]
+ path = projects/money-streaming-intro-foundry/lib/forge-std
+ url = https://github.com/foundry-rs/forge-std
+[submodule "projects/gda-advertisement-auction/lib/forge-std"]
+ path = projects/gda-advertisement-auction/lib/forge-std
+ url = https://github.com/foundry-rs/forge-std
+[submodule "projects/gda-advertisement-auction/lib/superfluid-protocol-monorepo"]
+ path = projects/gda-advertisement-auction/lib/superfluid-protocol-monorepo
+ url = https://github.com/superfluid-finance/protocol-monorepo
+[submodule "projects/gda-advertisement-auction/lib/openzeppelin-contracts"]
+ path = projects/gda-advertisement-auction/lib/openzeppelin-contracts
+ url = https://github.com/OpenZeppelin/openzeppelin-contracts
diff --git a/.husky/pre-commit b/.husky/pre-commit
deleted file mode 100755
index 0da96d6..0000000
--- a/.husky/pre-commit
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env sh
-. "$(dirname -- "$0")/_/husky.sh"
-
-npx pretty-quick --staged
diff --git a/.prettierignore b/.prettierignore
deleted file mode 100644
index 692ba7e..0000000
--- a/.prettierignore
+++ /dev/null
@@ -1,27 +0,0 @@
-# OSX
-.DS_Store
-
-# env
-.env
-
-# node
-node_modules
-package-lock.json
-yarn.lock
-yarn-error.log
-
-# editooors
-.idea
-.vscode
-
-# tsc / hardhat / foundry
-artifacts
-cache
-out
-data
-build
-dist
-lib
-
-# github
-.github
diff --git a/.prettierrc b/.prettierrc
deleted file mode 100644
index 43a0bc2..0000000
--- a/.prettierrc
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "tabWidth": 4,
- "useTabs": false,
- "semi": false,
- "singleQuote": false,
- "trailingComma": "none",
- "arrowParens": "avoid",
- "printWidth": 80,
- "overrides": [
- {
- "files": "*.sol",
- "options": {
- "printWidth": 100,
- "tabWidth": 4,
- "useTabs": false,
- "singleQuote": false,
- "bracketSpacing": false,
- "explicitTypes": "always"
- }
- }
- ]
-}
diff --git a/CONTRIBUTING b/CONTRIBUTING
deleted file mode 100644
index fe0b5c8..0000000
--- a/CONTRIBUTING
+++ /dev/null
@@ -1,65 +0,0 @@
-# Contributing
-
-Thank you for your interest in contributing to the Superfluid examples repository!
-
-Before getting started, be sure to review the [code of conduct](./code-of-conduct.md).
-
-## Editing an Existing Project
-
-To edit an existing project, follow the directions to get started under the [README](./README.md).
-
-## Creating a New Example
-
-To create a new example, start by opening an issue on this GitHub repository using the "New Example"
-template and follow its instructions.
-
-## Style Guidelines
-
-### Linting
-
-ESLint is used for linting and will prevent commits if the code does not conform to the standard.
-
-### Project Layout
-
-Each project should follow a similar pattern. Example projects should exist within the `./examples`
-directory.
-
-Inside of each project, the following is required.
-
-1. `README.md` file documenting its functionality and use.
-2. `package.json` with all local dependencies.
-3. `build-and-test.sh` with execute permission for the workflows.
-4. `hardhat.config.js` with the local configuration. When using Foundry, and exception may be made.
-5. `.env.template` if the project requires environment variables.
-
-### Testing
-
-While 100% test coverage is not required, it is highly recommended to get as close as possible.
-
-### Typescript
-
-If the project uses Typescript, be sure to extend the base tsconfig files in
-[this directory](./config).
-
-### Comments
-
-Natspec comments should always use three slashes `///` instead of the star pattern `/** */`.
-Natspec should be on every external function, modifier, public variable, event, and error. All
-parameters and return values should be documented.
-
-General comments should always use two slashes `//`.
-
-Comments that indicate a "section" of the code should use `// ---` where the dashes continue to the
-100th character in the line.
-
-Example:
-
-```
-// -------------------------------------------------------------------------------------------------
-// SECTION NAME
-
-...
-```
-
-Javascript files do not have to conform to this comment standard.
-
diff --git a/LICENSE b/LICENSE
index 6eee3fb..52e32c6 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,9 +1,9 @@
-Superfluid Protocol
+MIT License
-Copyright @ 2020-2022 Superfluid Finance Ltd
+Copyright © 2020-2024 Superfluid Finance Ltd
-This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-You should have received a copy of the GNU Affero General Public License along with this program. If not, see .
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
index 1ecaf76..f759444 100644
--- a/README.md
+++ b/README.md
@@ -11,8 +11,7 @@ Each example has their own dependencies. This is to reduce complexity when using
one or a small number of examples from this repository.
To get started with any exmaple project, navigate to the appropriate example
-directory and view the "Installation" section of its README file. Most projects
-use `npm`, but others may use `forge` or another tool.
+directory and view the "Installation" section of its README file.
## New Example Requests
@@ -26,8 +25,5 @@ example, open an issue and select the "New Example" template.
The following is a list of example projects in this repository. Follow the link
on each to see their local README file.
-- [Borrow Against Salary](./projects/borrow-against-salary/README.md)
-- [Instant Distribution Intro](./projects/instant-distribution-intro/README.md)
-- [Money Streaming Intro](./projects/money-streaming-intro)
-- [Tradeable Cashflow NFT](./projects/tradeable-cashflow/README.md)
-- [Gelato ACL Automation](./projects/superfluid-gelato-automation/)
+- [Money Streaming Intro](./projects/money-streaming-intro-foundry/README.md)
+- [GDA Advertisement Auction](./projects/gda-advertisement-auction/README.md)
diff --git a/code-of-conduct.md b/code-of-conduct.md
deleted file mode 100644
index 5aa66ee..0000000
--- a/code-of-conduct.md
+++ /dev/null
@@ -1,132 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-We as members, contributors, and leaders pledge to make participation in our
-community a harassment-free experience for everyone, regardless of age, body
-size, visible or invisible disability, ethnicity, sex characteristics, gender
-identity and expression, level of experience, education, socio-economic status,
-nationality, personal appearance, race, caste, color, religion, or sexual
-identity and orientation.
-
-We pledge to act and interact in ways that contribute to an open, welcoming,
-diverse, inclusive, and healthy community.
-
-## Our Standards
-
-Examples of behavior that contributes to a positive environment for our
-community include:
-
-- Demonstrating empathy and kindness toward other people
-- Being respectful of differing opinions, viewpoints, and experiences
-- Giving and gracefully accepting constructive feedback
-- Accepting responsibility and apologizing to those affected by our mistakes,
- and learning from the experience
-- Focusing on what is best not just for us as individuals, but for the overall
- community
-
-Examples of unacceptable behavior include:
-
-- The use of sexualized language or imagery, and sexual attention or advances of
- any kind
-- Trolling, insulting or derogatory comments, and personal or political attacks
-- Public or private harassment
-- Publishing others' private information, such as a physical or email address,
- without their explicit permission
-- Other conduct which could reasonably be considered inappropriate in a
- professional setting
-
-## Enforcement Responsibilities
-
-Community leaders are responsible for clarifying and enforcing our standards of
-acceptable behavior and will take appropriate and fair corrective action in
-response to any behavior that they deem inappropriate, threatening, offensive,
-or harmful.
-
-Community leaders have the right and responsibility to remove, edit, or reject
-comments, commits, code, wiki edits, issues, and other contributions that are
-not aligned to this Code of Conduct, and will communicate reasons for moderation
-decisions when appropriate.
-
-## Scope
-
-This Code of Conduct applies within all community spaces, and also applies when
-an individual is officially representing the community in public spaces.
-Examples of representing our community include using an official e-mail address,
-posting via an official social media account, or acting as an appointed
-representative at an online or offline event.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported to the community leaders responsible for enforcement at
-[INSERT CONTACT METHOD].
-All complaints will be reviewed and investigated promptly and fairly.
-
-All community leaders are obligated to respect the privacy and security of the
-reporter of any incident.
-
-## Enforcement Guidelines
-
-Community leaders will follow these Community Impact Guidelines in determining
-the consequences for any action they deem in violation of this Code of Conduct:
-
-### 1. Correction
-
-**Community Impact**: Use of inappropriate language or other behavior deemed
-unprofessional or unwelcome in the community.
-
-**Consequence**: A private, written warning from community leaders, providing
-clarity around the nature of the violation and an explanation of why the
-behavior was inappropriate. A public apology may be requested.
-
-### 2. Warning
-
-**Community Impact**: A violation through a single incident or series of
-actions.
-
-**Consequence**: A warning with consequences for continued behavior. No
-interaction with the people involved, including unsolicited interaction with
-those enforcing the Code of Conduct, for a specified period of time. This
-includes avoiding interactions in community spaces as well as external channels
-like social media. Violating these terms may lead to a temporary or permanent
-ban.
-
-### 3. Temporary Ban
-
-**Community Impact**: A serious violation of community standards, including
-sustained inappropriate behavior.
-
-**Consequence**: A temporary ban from any sort of interaction or public
-communication with the community for a specified period of time. No public or
-private interaction with the people involved, including unsolicited interaction
-with those enforcing the Code of Conduct, is allowed during this period.
-Violating these terms may lead to a permanent ban.
-
-### 4. Permanent Ban
-
-**Community Impact**: Demonstrating a pattern of violation of community
-standards, including sustained inappropriate behavior, harassment of an
-individual, or aggression toward or disparagement of classes of individuals.
-
-**Consequence**: A permanent ban from any sort of public interaction within the
-community.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage],
-version 2.1, available at
-[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
-
-Community Impact Guidelines were inspired by
-[Mozilla's code of conduct enforcement ladder][mozilla coc].
-
-For answers to common questions about this code of conduct, see the FAQ at
-[https://www.contributor-covenant.org/faq][faq]. Translations are available at
-[https://www.contributor-covenant.org/translations][translations].
-
-[homepage]: https://www.contributor-covenant.org
-[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
-[mozilla coc]: https://github.com/mozilla/diversity
-[faq]: https://www.contributor-covenant.org/faq
-[translations]: https://www.contributor-covenant.org/translations
diff --git a/config/tsconfig.base.json b/config/tsconfig.base.json
deleted file mode 100644
index cf71a0c..0000000
--- a/config/tsconfig.base.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "compilerOptions": {
- "moduleResolution": "node",
- "declaration": true,
- "declarationMap": true,
- "sourceMap": true,
- "allowSyntheticDefaultImports": true,
- "skipLibCheck": true,
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "forceConsistentCasingInFileNames": true,
- "noImplicitAny": true,
- "noImplicitOverride": true,
- "noImplicitThis": true,
- "noImplicitReturns": true,
- "strict": true
- }
-}
diff --git a/config/tsconfig.node.json b/config/tsconfig.node.json
deleted file mode 100644
index c7663f5..0000000
--- a/config/tsconfig.node.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "extends": "./tsconfig.base.json",
- "compilerOptions": {
- "module": "CommonJS",
- "target": "ES2021",
- "lib": ["ES2021"],
- "types": ["node"]
- }
-}
diff --git a/package.json b/package.json
deleted file mode 100644
index 5f18ad1..0000000
--- a/package.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "examples",
- "version": "1.0.0",
- "repository": "git@github.com:superfluid-finance/super-examples.git",
- "author": "superfluid-finance",
- "license": "MIT",
- "devDependencies": {
- "@typescript-eslint/eslint-plugin": "^5.30.6",
- "@typescript-eslint/parser": "^5.30.6",
- "eslint": "^8.19.0",
- "husky": "^8.0.1",
- "prettier": "^2.7.1",
- "prettier-plugin-solidity": "^1.0.0-dev.22",
- "pretty-quick": "^3.1.3"
- },
- "scripts": {
- "prepare": "husky install",
- "prettier": "prettier --write ."
- }
-}
diff --git a/projects/borrow-against-salary/.env-template b/projects/borrow-against-salary/.env-template
deleted file mode 100644
index 92272b9..0000000
--- a/projects/borrow-against-salary/.env-template
+++ /dev/null
@@ -1,4 +0,0 @@
-GOERLI_URL=
-EMPLOYER_PRIVATE_KEY=
-BORROWER_PRIVATE_KEY=
-LENDER_PRIVATE_KEY=
diff --git a/projects/borrow-against-salary/README.md b/projects/borrow-against-salary/README.md
deleted file mode 100644
index c712d31..0000000
--- a/projects/borrow-against-salary/README.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# Borrowing against a Superfluid salary stream
-
-This example is a base implementation of a loan contract which is tied to a salary stream.
-
-### The application assumes 3 parties:
-
-1. Employer - likely one who is whitelisted or a trustworthy employer
-2. Borrower - an employee currently receiving a salary stream from the Employer
-3. Lender - an outside party who lends to the Borrower
-
-### There are several steps involved in the origination of each loan contract:
-
-1. The `Borrower` deploys a new `EmploymentLoan.sol` contract, and passes the following into the constructor:
-
-- borrow amount
-- the desired interest rate
-- the duration of the loan
-- employer address
-- the borrower's own address
-- the token to be borrowed
-- address of the Superfluid host contract on the current network
-
-2. Once the contract is deployed, the borrower will instruct their employer to begin sending 100% of their salary into the contract. Because the application is a Super App, our contract will to run the `afterAgreementCreated` callback, where we have inserted logic which will initially send 100% of the incoming flow to the borrower. In this case, the borrower will still be receiving 100% of their salary.
-
-3. A lender may call `approve()` on the borrowToken contract, passing in the address of the current employmentLoan contract as the spender. From there, the lender may call the `lend()` function to enter into a loan agreement with the borrower. The lend function will ensure the employer is indeed streaming money into the contract. If this check passes, then the lent funds will be sent to the borrower, and the flow from the contract to the employee will be split so that the lender is now receiving a streaming interest payment which is taken directly from the borrower's salary. The borrower's incoming salary stream is now equal to 100% of the previous salary amount - the lender's interest rate stream amount.
-
-4. If the employer stops the flow rate into the employment loan contract, then the flow from the contract to the lender and borrower is stopped by making use of the `afterAgreementTerminated` callback. If the contract at any point starts once again receiving a stream in the borrow token which is enough to pay for the lender's interest rate payments, a new stream in the borrow token is started to both the lender and borrower once again as in step 3. The contract will note that the loan is still open, so the lender will begin receiving their interest once again.
-
-5. Once a loan is completed, the borrower may call closeLoan() to stop the stream to the lender, and once again receive 100% of their salary stream. A loan can be terminated early at any time by the borrower if the borrower is willing to pay off the remainder of the loan in a single transaction.
-
-### Opportunities for Further Work
-
-1. There is no collateral mechanism here, which prevents this from being done in a fully permissionless and 100% secure way. You can see the example shown in this workshop for an implementation that requires collateral to be locked by the borrower: https://www.youtube.com/watch?v=yxzOimYwxHY
-2. The Loan contract is not tradeable for the lender. It would be interesting to mint the lender a tradeable cashflow NFT to represent their rights to interest payment streams so that these loans may be traded on the secondary market.
-3. The borrower needs to manually call closeLoan() to terminate the stream to the lender once the loan has been completed. It would be worth using a Keeper to ensure that the loan is closed as quickly as possible upon completion.
-4. This system is peer to peer, and would be hard to scale by itself. How could you build a system that generalizes this using lending pools that can be drawn from instead?
diff --git a/projects/borrow-against-salary/cache/solidity-files-cache.json b/projects/borrow-against-salary/cache/solidity-files-cache.json
deleted file mode 100644
index c79d1df..0000000
--- a/projects/borrow-against-salary/cache/solidity-files-cache.json
+++ /dev/null
@@ -1,990 +0,0 @@
-{
- "_format": "hh-sol-cache-2",
- "files": {
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\contracts\\EmploymentLoan.sol": {
- "lastModificationDate": 1683836703927,
- "contentHash": "8feac0cbf4bf69f79000262d7e467a53",
- "sourceName": "contracts/EmploymentLoan.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol",
- "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol",
- "@superfluid-finance/ethereum-contracts/contracts/apps/SuperAppBaseCFA.sol"
- ],
- "versionPragmas": [
- ">=0.8.0"
- ],
- "artifacts": [
- "EmploymentLoan"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\apps\\SuperTokenV1Library.sol": {
- "lastModificationDate": 1683730720817,
- "contentHash": "0c86e0e3f51e35daf4d0927725367c4a",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "../interfaces/superfluid/ISuperfluid.sol",
- "../interfaces/agreements/IConstantFlowAgreementV1.sol",
- "../interfaces/agreements/IInstantDistributionAgreementV1.sol"
- ],
- "versionPragmas": [
- ">= 0.8.0"
- ],
- "artifacts": [
- "SuperTokenV1Library"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\apps\\SuperAppBaseCFA.sol": {
- "lastModificationDate": 1683818648884,
- "contentHash": "afb644e24e5605d732849c1ee2d83312",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/apps/SuperAppBaseCFA.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "../interfaces/superfluid/ISuperfluid.sol",
- "./SuperTokenV1Library.sol"
- ],
- "versionPragmas": [
- ">= 0.8.0"
- ],
- "artifacts": [
- "SuperAppBaseCFA"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\ISuperfluid.sol": {
- "lastModificationDate": 1683730720732,
- "contentHash": "923d8bee2334395f7ad909b8e98e07e9",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "./ISuperfluidGovernance.sol",
- "./ISuperfluidToken.sol",
- "./ISuperToken.sol",
- "./ISuperTokenFactory.sol",
- "./ISuperAgreement.sol",
- "./ISuperApp.sol",
- "./Definitions.sol",
- "../tokens/TokenInfo.sol",
- "@openzeppelin/contracts/token/ERC20/IERC20.sol",
- "@openzeppelin/contracts/token/ERC777/IERC777.sol"
- ],
- "versionPragmas": [
- ">= 0.8.4"
- ],
- "artifacts": [
- "ISuperfluid"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\agreements\\IConstantFlowAgreementV1.sol": {
- "lastModificationDate": 1683730720677,
- "contentHash": "253f76f0473cf1297607b03447c4b53e",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "../superfluid/ISuperAgreement.sol",
- "../superfluid/ISuperfluidToken.sol"
- ],
- "versionPragmas": [
- ">= 0.8.4"
- ],
- "artifacts": [
- "IConstantFlowAgreementV1"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\agreements\\IInstantDistributionAgreementV1.sol": {
- "lastModificationDate": 1683730720693,
- "contentHash": "60042f78e0fa54a8547790c391ab27c1",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/IInstantDistributionAgreementV1.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "../superfluid/ISuperAgreement.sol",
- "../superfluid/ISuperfluidToken.sol"
- ],
- "versionPragmas": [
- ">= 0.8.4"
- ],
- "artifacts": [
- "IInstantDistributionAgreementV1"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\ISuperfluidGovernance.sol": {
- "lastModificationDate": 1683730720736,
- "contentHash": "f39a1c0568c38958f3c5c80b6fb1603c",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluidGovernance.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "./ISuperAgreement.sol",
- "./ISuperToken.sol",
- "./ISuperfluidToken.sol",
- "./ISuperfluid.sol"
- ],
- "versionPragmas": [
- ">= 0.8.4"
- ],
- "artifacts": [
- "ISuperfluidGovernance"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@openzeppelin\\contracts\\token\\ERC777\\IERC777.sol": {
- "lastModificationDate": 1682695447813,
- "contentHash": "35b56a00de0fb16f9e6a8d7464d31b0b",
- "sourceName": "@openzeppelin/contracts/token/ERC777/IERC777.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [],
- "versionPragmas": [
- "^0.8.0"
- ],
- "artifacts": [
- "IERC777"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\ISuperTokenFactory.sol": {
- "lastModificationDate": 1683730720758,
- "contentHash": "e49894d55d38f583c443600c4c99f8c6",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperTokenFactory.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "./ISuperToken.sol",
- "../tokens/ERC20WithTokenInfo.sol"
- ],
- "versionPragmas": [
- ">= 0.8.4"
- ],
- "artifacts": [
- "ISuperTokenFactory"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\ISuperfluidToken.sol": {
- "lastModificationDate": 1683730720752,
- "contentHash": "095cd6cdf7df13a739649f8917862cb0",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluidToken.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "./ISuperAgreement.sol"
- ],
- "versionPragmas": [
- ">= 0.8.4"
- ],
- "artifacts": [
- "ISuperfluidToken"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\ISuperToken.sol": {
- "lastModificationDate": 1683730720758,
- "contentHash": "61469de32bea27827319123c4a735dab",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "./ISuperfluid.sol",
- "./ISuperfluidToken.sol",
- "../tokens/TokenInfo.sol",
- "@openzeppelin/contracts/token/ERC777/IERC777.sol",
- "@openzeppelin/contracts/token/ERC20/IERC20.sol",
- "./IConstantOutflowNFT.sol",
- "./IConstantInflowNFT.sol",
- "./IPoolAdminNFT.sol",
- "./IPoolMemberNFT.sol"
- ],
- "versionPragmas": [
- ">= 0.8.4"
- ],
- "artifacts": [
- "ISuperToken"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\tokens\\TokenInfo.sol": {
- "lastModificationDate": 1683730720838,
- "contentHash": "6326411b7eb3d451fdffd149d821a7cb",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/tokens/TokenInfo.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [],
- "versionPragmas": [
- ">= 0.8.4"
- ],
- "artifacts": [
- "TokenInfo"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@openzeppelin\\contracts\\token\\ERC20\\IERC20.sol": {
- "lastModificationDate": 1682695447813,
- "contentHash": "ad7c2d0af148c8f9f097d65deeb4da6b",
- "sourceName": "@openzeppelin/contracts/token/ERC20/IERC20.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [],
- "versionPragmas": [
- "^0.8.0"
- ],
- "artifacts": [
- "IERC20"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\ISuperApp.sol": {
- "lastModificationDate": 1683730720726,
- "contentHash": "5057526e30b17d708447527cb6485d6f",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperApp.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "./ISuperToken.sol"
- ],
- "versionPragmas": [
- ">= 0.8.4"
- ],
- "artifacts": [
- "ISuperApp"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\ISuperAgreement.sol": {
- "lastModificationDate": 1683730720718,
- "contentHash": "49d978f06d4edeb5125a7152d6897e69",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperAgreement.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "./ISuperfluidToken.sol"
- ],
- "versionPragmas": [
- ">= 0.8.4"
- ],
- "artifacts": [
- "ISuperAgreement"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\Definitions.sol": {
- "lastModificationDate": 1683730720644,
- "contentHash": "d6576f4814532782fca96c1bd26db384",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/Definitions.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [],
- "versionPragmas": [
- ">= 0.8.4"
- ],
- "artifacts": [
- "BatchOperation",
- "ContextDefinitions",
- "FlowOperatorDefinitions",
- "SuperAppDefinitions",
- "SuperfluidGovernanceConfigs"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\IConstantOutflowNFT.sol": {
- "lastModificationDate": 1683730720677,
- "contentHash": "d68a7fe94e12d2277eedd4054fc59a6b",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/IConstantOutflowNFT.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "./ISuperfluidToken.sol",
- "./IFlowNFTBase.sol"
- ],
- "versionPragmas": [
- ">=0.8.4"
- ],
- "artifacts": [
- "IConstantOutflowNFT"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\IPoolAdminNFT.sol": {
- "lastModificationDate": 1683730720702,
- "contentHash": "6a5ee5e8ea02a99a32948c3ba8f750a8",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/IPoolAdminNFT.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [],
- "versionPragmas": [
- ">=0.8.4"
- ],
- "artifacts": [
- "IPoolAdminNFT"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\IConstantInflowNFT.sol": {
- "lastModificationDate": 1683730720677,
- "contentHash": "50e7ff0bc0e1235a45c52de2eae4df43",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/IConstantInflowNFT.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "./ISuperToken.sol",
- "./IFlowNFTBase.sol"
- ],
- "versionPragmas": [
- ">=0.8.4"
- ],
- "artifacts": [
- "IConstantInflowNFT"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\IPoolMemberNFT.sol": {
- "lastModificationDate": 1683730720702,
- "contentHash": "71ace2838abebb46b969d54537e4458d",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/IPoolMemberNFT.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [],
- "versionPragmas": [
- ">=0.8.4"
- ],
- "artifacts": [
- "IPoolMemberNFT"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\tokens\\ERC20WithTokenInfo.sol": {
- "lastModificationDate": 1683730720654,
- "contentHash": "77968d7579793b9f87e33dec4d917f44",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/tokens/ERC20WithTokenInfo.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "@openzeppelin/contracts/token/ERC20/IERC20.sol",
- "./TokenInfo.sol"
- ],
- "versionPragmas": [
- ">= 0.8.4"
- ],
- "artifacts": [
- "ERC20WithTokenInfo"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@superfluid-finance\\ethereum-contracts\\contracts\\interfaces\\superfluid\\IFlowNFTBase.sol": {
- "lastModificationDate": 1683730720687,
- "contentHash": "10e54273c5b21ca0b88131952611bf26",
- "sourceName": "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/IFlowNFTBase.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol",
- "./ISuperToken.sol"
- ],
- "versionPragmas": [
- ">=0.8.4"
- ],
- "artifacts": [
- "IFlowNFTBase"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@openzeppelin\\contracts\\token\\ERC721\\extensions\\IERC721Metadata.sol": {
- "lastModificationDate": 1682695447813,
- "contentHash": "efbc0d15b80a74e34dbe8da0f3e879bb",
- "sourceName": "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "../IERC721.sol"
- ],
- "versionPragmas": [
- "^0.8.0"
- ],
- "artifacts": [
- "IERC721Metadata"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@openzeppelin\\contracts\\token\\ERC721\\IERC721.sol": {
- "lastModificationDate": 1682695447813,
- "contentHash": "eb7e61db29f31d88b3c1cef1b063d338",
- "sourceName": "@openzeppelin/contracts/token/ERC721/IERC721.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "../../utils/introspection/IERC165.sol"
- ],
- "versionPragmas": [
- "^0.8.0"
- ],
- "artifacts": [
- "IERC721"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\node_modules\\@openzeppelin\\contracts\\utils\\introspection\\IERC165.sol": {
- "lastModificationDate": 1682695447797,
- "contentHash": "03e6768535ac4da0e9756f1d8a4a018a",
- "sourceName": "@openzeppelin/contracts/utils/introspection/IERC165.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [],
- "versionPragmas": [
- "^0.8.0"
- ],
- "artifacts": [
- "IERC165"
- ]
- },
- "C:\\Users\\Joel Jesudason\\Documents\\Superfluid\\main\\super-examples\\projects\\borrow-against-salary\\contracts\\LoanFactory.sol": {
- "lastModificationDate": 1683813275785,
- "contentHash": "8cb81f60a1a10e3635d86eb606c68233",
- "sourceName": "contracts/LoanFactory.sol",
- "solcConfig": {
- "version": "0.8.14",
- "settings": {
- "optimizer": {
- "enabled": false,
- "runs": 200
- },
- "outputSelection": {
- "*": {
- "*": [
- "abi",
- "evm.bytecode",
- "evm.deployedBytecode",
- "evm.methodIdentifiers",
- "metadata"
- ],
- "": [
- "ast"
- ]
- }
- }
- }
- },
- "imports": [
- "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol",
- "./EmploymentLoan.sol"
- ],
- "versionPragmas": [
- ">=0.8.0"
- ],
- "artifacts": [
- "LoanFactory"
- ]
- }
- }
-}
diff --git a/projects/borrow-against-salary/contracts/EmploymentLoan.sol b/projects/borrow-against-salary/contracts/EmploymentLoan.sol
deleted file mode 100644
index dd3f142..0000000
--- a/projects/borrow-against-salary/contracts/EmploymentLoan.sol
+++ /dev/null
@@ -1,379 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity >=0.8.0;
-
-import {ISuperfluid, ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
-
-import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
-
-import {SuperAppBaseFlow} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperAppBaseFlow.sol";
-
-/// @title Employment Loan Contract
-/// @author Superfluid
-contract EmploymentLoan is SuperAppBaseFlow {
-
- /// @notice Importing the SuperToken Library to make working with streams easy.
- using SuperTokenV1Library for ISuperToken;
- // ---------------------------------------------------------------------------------------------
- // STORAGE & IMMUTABLES
-
- /// @notice Total amount borrowed.
- int256 public immutable borrowAmount;
-
- /// @notice Interest rate, in whole number. I.e. 8% interest rate would be passed as '8'
- int8 public immutable interestRate;
-
- /// @notice Number of months the loan will be paid back in. I.e. 2 years = '24'
- int256 public immutable paybackMonths;
-
- /// @notice Address of employer - must be allow-listed for this example
- address public immutable employer;
-
- /// @notice Borrower address.
- address public immutable borrower;
-
- /// @notice Token being borrowed.
- ISuperToken public immutable borrowToken;
-
- /// @notice Lender address.
- address public lender;
-
- /// @notice boolean flag to track whether or not the loan is open
- bool public loanOpen;
-
- /// @notice Timestamp of the loan start time.
- uint256 public loanStartTime;
-
- /// @notice boolean flag to track whether the loan was closed. In contrary to @loanOpen, this variable changes state only once.
- bool public isClosed;
-
- // ---------------------------------------------------------------------------------------------
- //MODIFIERS
-
- ///@dev checks that only the borrowToken is used when sending streams into this contract
- ///@param superToken the token being streamed into the contract
- function isAcceptedSuperToken(ISuperToken superToken) public view override returns (bool) {
- return address(superToken) == address(borrowToken);
- }
-
- constructor(
- int256 _borrowAmount, // amount to be borrowed
- int8 _interestRate, // annual interest rate, in whole number - i.e. 8% would be passed as 8
- int256 _paybackMonths, // total payback months
- address _employer, // allow-listed employer address
- address _borrower, // borrower address
- ISuperToken _borrowToken, // super token to be used in borrowing
- ISuperfluid _host // address of SF host
- ) SuperAppBaseFlow(
- _host,
- true,
- true,
- true
- ) {
- borrowAmount = _borrowAmount;
- interestRate = _interestRate;
- paybackMonths = _paybackMonths;
- employer = _employer;
- borrower = _borrower;
- borrowToken = _borrowToken;
- host = _host;
- loanOpen = false;
- isClosed = false;
- }
-
- /// @dev Calculates the flow rate to be sent to the lender to repay the stream.
- /// @return paymentFlowRate The flow rate to be paid to the lender.
- function getPaymentFlowRate() public view returns (int96 paymentFlowRate) {
- return (
- int96(
- ((borrowAmount + ((borrowAmount * int256(interestRate)) / int256(100))) /
- paybackMonths) / ((365 / 12) * 86400)
- //365/12 = average days in a month; 86400 = seconds in a day (24 hours); -> 365/12 * 86400 average seconds in a month
- )
- );
- }
-
- // ---------------------------------------------------------------------------------------------
- // FUNCTIONS & CORE LOGIC
-
- /// @notice Get the total amount of super tokens that the borrower still needs to repay on the
- /// loan.
- /// @return Total number of remaining tokens to be paid on the loan in wei used to calculate
- /// whether or not a loan may be closed.
- function getTotalAmountRemaining() public view returns (uint256) {
- //if there is no time left on loan, return zero
- int256 secondsLeft = (paybackMonths * int256((365 * 86400) / 12)) -
- int256(block.timestamp - loanStartTime);
- if (secondsLeft <= 0) {
- return 0;
- } else {
- //if an amount is left, return the total amount to be paid
- return uint256(secondsLeft) * uint256(int256(getPaymentFlowRate()));
- }
- }
-
- /// @notice lender can use this function to send funds to the borrower and start the loan
- /// @dev function also handles the splitting of flow to lender
- function lend() external {
- int96 employerFlowRate = borrowToken.getFlowRate(employer, address(this));
-
- require(!isClosed, "Loan already closed");
- require(employerFlowRate >= getPaymentFlowRate(), "insufficient flowRate");
-
- //lender must approve contract before running next line
- borrowToken.transferFrom(msg.sender, borrower, uint256(borrowAmount));
-
- //want to make sure that tokens are sent successfully first before setting lender to msg.sender
- int96 netFlowRate = borrowToken.getNetFlowRate(address(this));
-
- int96 outFlowRate = borrowToken.getFlowRate(address(this), borrower);
-
- //update flow to borrower (aka the employee)
- borrowToken.updateFlow(
- borrower,
- ((netFlowRate - outFlowRate) * -1) - getPaymentFlowRate()
- );
-
- //create flow to lender
- borrowToken.createFlow(msg.sender, getPaymentFlowRate());
-
- loanOpen = true;
- lender = msg.sender;
- loanStartTime = block.timestamp;
- }
-
- /// @notice handle the case of a stream being created into the contract
- /// @param ctx the context value passed into updateOutflow in super app callbacks
- /// @param paymentFlowRate the flow rate to be sent to the lender if a loan were to activate
- /// (this could be the same value as outFlowRate)
- /// @param inFlowRate the flow rate sent into the contract from the employer
- /// used within the _updateOutflow function which is ultimately called in the callbacks
- function _updateOutFlowCreate(
- bytes calldata ctx,
- int96 paymentFlowRate,
- int96 inFlowRate
- ) private returns (bytes memory newCtx) {
- newCtx = ctx;
- //get the current sender of the flow
- address sender = host.decodeCtx(ctx).msgSender;
- //this will revert and no outflow or inflow will be created if the sender of the flow is not
- // the emploer
- require(sender == employer, "sender of flow must be the employer");
- // @dev If there is no existing outflow, then create new flow to equal inflow
- // sender must also be the employer
- //create flow to employee
- //if loan is still open, we need to make sure that the right amount of funds are sent to the
- // borrower & lender
- if (loanOpen == true) {
- newCtx = borrowToken.createFlowWithCtx(
- borrower,
- inFlowRate - paymentFlowRate,
- newCtx
- );
- newCtx = borrowToken.createFlowWithCtx(lender, paymentFlowRate, newCtx);
- } else {
- //if loanOpen is not true, we need to send the borrower the full inflow
- newCtx = borrowToken.createFlowWithCtx(borrower, inFlowRate, newCtx);
- }
- }
-
- /// @dev manages edge cases related to flow updates
- /// to be used within _updateOutflow function
- /// @param ctx context passed by super app callback
- /// @param paymentFlowRate the flow rate to be sent to the lender if a loan were to activate
- /// (this could be the same value as outFlowRate)
- /// @param outFlowRateLender the flow rate being sent to lender from the contract
- /// @param inFlowRate the flow rate sent into the contract from the employer
- /// @dev if flowrate into the contract is enough to cover loan repayment, then just update
- /// outflow to borrower. if flowrate into contract is not enough to cover loan repayment, we
- /// need to ensure that the lender gets everything going into the contract
- function _updateOutFlowUpdate(
- bytes calldata ctx,
- int96 paymentFlowRate,
- int96 outFlowRateLender,
- int96 inFlowRate
- ) private returns (bytes memory newCtx) {
- newCtx = ctx;
- // this will get us the amount of money that should be redirected to the lender out of the
- // inflow, denominated in borrow token
-
- int96 borrowerInFlow = borrowToken.getFlowRate(address(this), borrower);
-
- //if the amount being sent is enough to cover loan
- if ((inFlowRate - paymentFlowRate) > 0) {
- //if there is currently an outflow to the lender
- if (outFlowRateLender > 0) {
- //if the borrower is receiving money
- if (borrowerInFlow > 0) {
- newCtx = borrowToken.updateFlowWithCtx(
- borrower,
- inFlowRate - paymentFlowRate,
- newCtx
- );
- } else {
- newCtx = borrowToken.createFlowWithCtx(
- borrower,
- inFlowRate - paymentFlowRate,
- newCtx
- );
- }
- newCtx = borrowToken.updateFlowWithCtx(lender, paymentFlowRate, newCtx);
- } else {
- newCtx = borrowToken.updateFlowWithCtx(borrower, inFlowRate, newCtx);
- }
- // the following case is here because the lender will be paid first
- // if there's not enough money to pay off the loan in full, the lender gets paid
- // everything coming in to the contract
- } else if ((inFlowRate - paymentFlowRate <= 0) && inFlowRate > 0) {
- // if inFlowRate is less than the required amount to pay interest, but there's still a
- // flow, we'll stream it all to the lender
- if (outFlowRateLender > 0) {
- newCtx = borrowToken.deleteFlowWithCtx(address(this), borrower, newCtx);
- newCtx = borrowToken.updateFlowWithCtx(lender, inFlowRate, newCtx);
- } else {
- //in this case, there is no lender outFlowRate..so we need to just update the outflow to borrower
- newCtx = borrowToken.updateFlowWithCtx(borrower, inFlowRate, newCtx);
- }
- }
- }
-
- /// @notice handles deletion of flow into contract
- /// @dev ensures that streams sent out of the contract are also stopped
- /// @param ctx context passed by super app callback
- /// @param outFlowRateLender the flow rate being sent to lender from the contract
- function _updateOutFlowDelete(bytes calldata ctx, int96 outFlowRateLender)
- private
- returns (bytes memory newCtx)
- {
- newCtx = ctx;
- // delete flow to lender in borrow token if they are currently receiving a flow
- if (outFlowRateLender > 0) {
- newCtx = borrowToken.deleteFlowWithCtx(address(this), lender, newCtx);
- }
- // delete flow to borrower in borrow token
- newCtx = borrowToken.deleteFlowWithCtx(address(this), borrower, newCtx);
- }
-
- /// @notice handles create, update, and delete case - to be run in each callback
- /// @param ctx context passed by super app callback
- function _updateOutflow(bytes calldata ctx) private returns (bytes memory newCtx) {
- newCtx = ctx;
- //this will get us the amount of money that should be redirected to the lender out of the inflow, denominated in borrow token
- int96 paymentFlowRate = getPaymentFlowRate();
- // @dev This will give me the new flowRate, as it is called in after callbacks
- int96 netFlowRate = borrowToken.getNetFlowRate(address(this));
-
- //current amount being sent to lender
- int96 outFlowRateLender = borrowToken.getFlowRate(address(this), lender);
- //current amount being sent to borrower
- int96 outFlowRateBorrower = borrowToken.getFlowRate(address(this), borrower);
- //total outflow rate in borrow token - only 2
- int96 outFlowRate = outFlowRateLender + outFlowRateBorrower;
- //total inflow rate in borrow token
- int96 inFlowRate = netFlowRate + outFlowRate;
-
- if (inFlowRate < 0) {
- inFlowRate = inFlowRate * -1; // Fixes issue when inFlowRate is negative
- }
-
- // @dev If inFlow === 0 && outflowRate > 0, then delete existing flows.
- if (inFlowRate == int96(0)) {
- newCtx = _updateOutFlowDelete(ctx, outFlowRateLender);
- }
- //if flow exists, update the flow according to various params
- else if (outFlowRate != int96(0)) {
- newCtx = _updateOutFlowUpdate(ctx, paymentFlowRate, outFlowRateLender, inFlowRate);
- }
- //no flow exists into the contract in borrow token
- else {
- newCtx = _updateOutFlowCreate(ctx, paymentFlowRate, inFlowRate);
- // @dev If there is no existing outflow, then create new flow to equal inflow
- }
- }
-
- /// @notice function to close a loan that is already completed
- function closeCompletedLoan() external {
- require(getTotalAmountRemaining() <= 0);
-
- int96 currentLenderFlowRate = borrowToken.getFlowRate(address(this), lender);
- borrowToken.deleteFlow(address(this), lender);
-
- int96 currentFlowRate = borrowToken.getFlowRate(address(this), borrower);
- borrowToken.updateFlow(borrower, currentFlowRate + currentLenderFlowRate);
- loanOpen = false;
- isClosed = true;
- }
-
- ///@notice allows lender or borrower to close a loan that is not yet finished
- ///@param amountForPayoff the amount to be paid right now to close the loan in wei
- /// @dev if the loan is paid off, or if the loan is closed by the lender, pass 0. if the loan is
- /// not yet paid off, pass in the required amount to close loan
- function closeOpenLoan(uint256 amountForPayoff) external {
- int96 currentLenderFlowRate = borrowToken.getFlowRate(address(this), lender);
- int96 currentFlowRate = borrowToken.getFlowRate(address(this), borrower);
-
- // lender may close the loan early to forgive the debt
- if (msg.sender == lender) {
- borrowToken.deleteFlow(address(this), lender);
- borrowToken.updateFlow(borrower, currentFlowRate + currentLenderFlowRate);
- loanOpen = false;
- isClosed = true;
- } else {
- require(amountForPayoff >= (getTotalAmountRemaining()), "insuf funds");
- require(getTotalAmountRemaining() > 0, "you should call closeOpenLoan() instead");
- borrowToken.transferFrom(msg.sender, lender, amountForPayoff);
-
- borrowToken.deleteFlow(address(this), lender);
-
- borrowToken.updateFlow(borrower, currentFlowRate + currentLenderFlowRate);
- loanOpen = false;
- isClosed = true;
- }
- }
-
- // ---------------------------------------------------------------------------------------------
- // SUPER APP CALLBACKS
-
- /// @dev super app after flow created callback
- function onFlowCreated(
- ISuperToken /*superToken*/,
- address /*sender*/,
- bytes calldata ctx
- )
- internal
- override
- returns (bytes memory newCtx)
- {
- newCtx = _updateOutflow(ctx);
- }
-
- /// @dev super app after flow updated callback
- function onFlowUpdated(
- ISuperToken /*superToken*/,
- address /*sender*/,
- int96 /*previousFlowRate*/,
- uint256 /*lastUpdated*/,
- bytes calldata ctx
- )
- internal
- override
- returns (bytes memory newCtx)
- {
- newCtx = _updateOutflow(ctx);
- }
-
- /// @dev super app after flow deleted callback
- function onFlowDeleted(
- ISuperToken /*superToken*/,
- address /*sender*/,
- address /*receiver*/,
- int96 /*previousFlowRate*/,
- uint256 /*lastUpdated*/,
- bytes calldata ctx
- )
- internal
- override
- returns (bytes memory newCtx)
- {
- newCtx = _updateOutflow(ctx);
- }
-}
\ No newline at end of file
diff --git a/projects/borrow-against-salary/contracts/LoanFactory.sol b/projects/borrow-against-salary/contracts/LoanFactory.sol
deleted file mode 100644
index 51a59b5..0000000
--- a/projects/borrow-against-salary/contracts/LoanFactory.sol
+++ /dev/null
@@ -1,54 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity >=0.8.0;
-
-import {ISuperfluid, ISuperToken, ISuperApp, ISuperAgreement, SuperAppDefinitions} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
-
-import {EmploymentLoan} from "./EmploymentLoan.sol";
-
-contract LoanFactory {
- /// @notice counter which is iterated +1 for each new loan created.
- /// @dev Note that the value begins at 0 here, but the first one will start at one.
- uint256 public loanId;
-
- /// @notice mapping of loanId to the loan contract
- mapping(uint256 => EmploymentLoan) public idToLoan;
-
- /// @notice mapping of loan owner (i.e. the msg.sender on the call) to the loan Id
- mapping(address => uint256) public employmentLoanOwners;
-
- /// @notice Creates new loan contract.
- /// @param _borrowAmount Amount to borrow.
- /// @param _interestRate Interest rate.
- /// @param _paybackMonths Number of months for repayment.
- /// @param _employer Employer address.
- /// @param _borrower Borrower address.
- /// @param _borrowToken Token to borrow.
- /// @param _host Superfluid host.
- /// @return Loan ID.
- function createNewLoan(
- int256 _borrowAmount,
- int8 _interestRate,
- int8 _paybackMonths,
- address _employer,
- address _borrower,
- ISuperToken _borrowToken,
- ISuperfluid _host
- ) external returns (uint256) {
- EmploymentLoan newLoan = new EmploymentLoan(
- _borrowAmount,
- _interestRate,
- _paybackMonths,
- _employer,
- _borrower,
- _borrowToken,
- _host
- );
-
- loanId++;
-
- idToLoan[loanId] = newLoan;
- employmentLoanOwners[msg.sender] = loanId;
-
- return loanId;
- }
-}
diff --git a/projects/borrow-against-salary/hardhat.config.js b/projects/borrow-against-salary/hardhat.config.js
deleted file mode 100644
index a28160a..0000000
--- a/projects/borrow-against-salary/hardhat.config.js
+++ /dev/null
@@ -1,38 +0,0 @@
-require("@nomiclabs/hardhat-waffle")
-require("@nomiclabs/hardhat-ethers")
-require("dotenv").config()
-
-task("accounts", "Prints the list of accounts", async (_, hre) => {
- const accounts = await hre.ethers.getSigners()
-
- for (const account of accounts) {
- console.log(account.address)
- }
-})
-
-module.exports = {
- solidity: "0.8.14",
- settings: {
- optimizer: {
- enabled: true,
- runs: 1000
- }
- },
- // UNCOMMENT WHEN RUNNING SCRIPTS
- networks: {
- hardhat: {
- blockGasLimit: 100000000
- }
- // goerli: {
- // url: `${process.env.GOERLI_URL}`,
- // accounts: [
- // `${process.env.BORROWER_PRIVATE_KEY}`,
- // `${process.env.EMPLOYER_PRIVATE_KEY}`,
- // `${process.env.LENDER_PRIVATE_KEY}`
- // ]
- // }
- },
- namedAccounts: {
- deployer: 0
- }
-}
diff --git a/projects/borrow-against-salary/package.json b/projects/borrow-against-salary/package.json
deleted file mode 100644
index 72090b4..0000000
--- a/projects/borrow-against-salary/package.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "superfluid-isa",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "test": "npx hardhat test --network hardhat",
- "build": "npx hardhat compile"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "@nomiclabs/hardhat-ethers": "^2.0.5",
- "@nomiclabs/hardhat-waffle": "^2.0.3",
- "@openzeppelin/test-helpers": "^0.5.15",
- "chai": "^4.3.6",
- "ethereum-waffle": "^3.4.0",
- "ethers": "^5.6.0",
- "hardhat": "^2.9.1"
- },
- "dependencies": {
- "@openzeppelin/contracts": "^4.5.0",
- "@superfluid-finance/ethereum-contracts": "^1.5.0",
- "@superfluid-finance/sdk-core": "^0.4.4",
- "dotenv": "^16.0.0",
- "graphql": "^16.3.0"
- }
-}
diff --git a/projects/borrow-against-salary/scripts/createEmployerFlow.js b/projects/borrow-against-salary/scripts/createEmployerFlow.js
deleted file mode 100644
index 991a2ef..0000000
--- a/projects/borrow-against-salary/scripts/createEmployerFlow.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const ethers = require("ethers")
-const { Framework } = require("@superfluid-finance/sdk-core")
-require("dotenv").config()
-//here is where you'll put your loan address that you'll be interacting with
-const loanAddress = ""
-
-async function main() {
- //note - make sure that the proper URL is added
- const url = `${process.env.GOERLI_URL}`
- const customHttpProvider = new ethers.providers.JsonRpcProvider(url)
-
- const network = await customHttpProvider.getNetwork()
- const sf = await Framework.create({
- chainId: network.chainId,
- provider: customHttpProvider
- })
-
- const employer = sf.createSigner({
- privateKey: process.env.EMPLOYER_PRIVATE_KEY,
- provider: customHttpProvider
- })
-
- const daix = await sf.loadSuperToken("fDAIx")
-
- const employerFlowOperation = daix.createFlow({
- receiver: loanAddress,
- flowRate: "3858024691358024", //10k per month
- })
-
- console.log("running create flow script...")
-
- await employerFlowOperation.exec(employer).then(tx => {
- console.log("Your tx succeeded!")
- console.log(tx)
- })
-}
-
-// We recommend this pattern to be able to use async/await everywhere
-// and properly handle errors.
-main()
- .then(() => process.exit(0))
- .catch(error => {
- console.error(error)
- process.exit(1)
- })
diff --git a/projects/borrow-against-salary/scripts/deleteEmployerFlow.js b/projects/borrow-against-salary/scripts/deleteEmployerFlow.js
deleted file mode 100644
index cd65f49..0000000
--- a/projects/borrow-against-salary/scripts/deleteEmployerFlow.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const ethers = require("ethers")
-const { Framework } = require("@superfluid-finance/sdk-core")
-require("dotenv").config()
-//here is where you'll put your loan address that you'll be interacting with
-const loanAddress = ""
-
-async function main() {
- //note - make sure that the proper URL is added
- const url = `${process.env.GOERLI_URL}`
- const customHttpProvider = new ethers.providers.JsonRpcProvider(url)
-
- const network = await customHttpProvider.getNetwork()
- const sf = await Framework.create({
- chainId: network.chainId,
- provider: customHttpProvider
- })
-
- const employer = sf.createSigner({
- privateKey: process.env.EMPLOYER_PRIVATE_KEY,
- provider: customHttpProvider
- })
-
- const daix = await sf.loadSuperToken("fDAIx")
-
- const employerFlowOperation = daix.deleteFlow({
- sender: employer.address,
- receiver: loanAddress,
- })
-
- console.log("running delete flow script...")
-
- await employerFlowOperation.exec(employer).then(tx => {
- console.log("Your tx succeeded!")
- console.log(tx)
- })
-}
-
-// We recommend this pattern to be able to use async/await everywhere
-// and properly handle errors.
-main()
- .then(() => process.exit(0))
- .catch(error => {
- console.error(error)
- process.exit(1)
- })
diff --git a/projects/borrow-against-salary/scripts/deployFactory.js b/projects/borrow-against-salary/scripts/deployFactory.js
deleted file mode 100644
index 3cc4147..0000000
--- a/projects/borrow-against-salary/scripts/deployFactory.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const ethers = require("ethers")
-const { Framework } = require("@superfluid-finance/sdk-core")
-require("dotenv").config()
-
-async function main() {
- //NOTE: this is set as the goerli url, but can be changed to reflect your RPC URL and network of choice
- const url = `${process.env.GOERLI_URL}`
- const customHttpProvider = new ethers.providers.JsonRpcProvider(url)
-
- const network = await customHttpProvider.getNetwork()
-
- const sf = await Framework.create({
- chainId: network.chainId,
- provider: customHttpProvider
- })
-
- const deployer = sf.createSigner({
- privateKey: process.env.EMPLOYER_PRIVATE_KEY, // deployer here doesn't matter much
- provider: customHttpProvider
- })
-
- //NOTE - this is DAIx on goerli - you can change this token to suit your network and desired token address
- const daix = await sf.loadSuperToken("fDAIx")
-
- console.log("running deploy script...")
- // We get the contract to deploy
- const LoanFactory = await hre.ethers.getContractFactory("LoanFactory")
- const loanFactory = await LoanFactory.connect(deployer).deploy()
-
- await loanFactory.deployed()
-
- //NOTE: you will need this address to run other scripts, so we recommend getting it from the console
- console.log("LoanFactory.sol deployed to:", loanFactory.address)
-}
-
-// We recommend this pattern to be able to use async/await everywhere
-// and properly handle errors.
-main()
- .then(() => process.exit(0))
- .catch(error => {
- console.error(error)
- process.exit(1)
- })
diff --git a/projects/borrow-against-salary/scripts/deployLoan.js b/projects/borrow-against-salary/scripts/deployLoan.js
deleted file mode 100644
index 273cd8b..0000000
--- a/projects/borrow-against-salary/scripts/deployLoan.js
+++ /dev/null
@@ -1,67 +0,0 @@
-const ethers = require("ethers")
-const { Framework } = require("@superfluid-finance/sdk-core")
-const LoanFactoryABI =
- require("../artifacts/contracts/LoanFactory.sol/LoanFactory.json").abi
-require("dotenv").config()
-
-//place deployed address of the loan factory here...
-const LoanFactoryAddress = "0x7b5655c12Fc4fceCCD8C3e144c413a0Ae5dc8DbA"
-
-//NOTE: this is set as the goerli url, but can be changed to reflect your RPC URL and network of choice
-const url = process.env.GOERLI_URL
-
-const customHttpProvider = new ethers.providers.JsonRpcProvider(url)
-
-async function main() {
- const network = await customHttpProvider.getNetwork()
-
- const sf = await Framework.create({
- chainId: network.chainId,
- provider: customHttpProvider
- })
-
- const borrower = sf.createSigner({
- privateKey: process.env.BORROWER_PRIVATE_KEY,
- provider: customHttpProvider
- })
-
- const employer = sf.createSigner({
- privateKey: process.env.EMPLOYER_PRIVATE_KEY,
- provider: customHttpProvider
- })
-
- const daix = await sf.loadSuperToken("fDAIx") //get fDAIx on goerli
-
- const loanFactory = new ethers.Contract(
- LoanFactoryAddress,
- LoanFactoryABI,
- customHttpProvider
- )
-
- await loanFactory
- .connect(borrower)
- .createNewLoan(
- ethers.utils.parseEther("1000"), //borrow amount = 1000 dai
- 8, // 8% interest rate
- 24, //24 months payback period
- employer.address, //address of employer who will be effectively whitelisted in this case
- borrower.address, // address of borrower
- daix.address, //daix address - this is the token we'll be using: borrowing in and paying back
- sf.settings.config.hostAddress //address of host
- )
- .then(tx => {
- console.log(
- "deployment successful! here is your tx hash: ",
- tx.hash
- )
- })
-}
-
-// We recommend this pattern to be able to use async/await everywhere
-// and properly handle errors.
-main()
- .then(() => process.exit(0))
- .catch(error => {
- console.error(error)
- process.exit(1)
- })
diff --git a/projects/borrow-against-salary/scripts/getLoanById.js b/projects/borrow-against-salary/scripts/getLoanById.js
deleted file mode 100644
index 71c7fb3..0000000
--- a/projects/borrow-against-salary/scripts/getLoanById.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const ethers = require("ethers")
-const { Framework } = require("@superfluid-finance/sdk-core")
-const LoanFactoryABI =
- require("../artifacts/contracts/LoanFactory.sol/LoanFactory.json").abi
-require("dotenv").config()
-
-//place deployed address of the loan factory here...
-const LoanFactoryAddress = ""
-
-//place the ID of your loan here. Note that loanIds start at 1
-const LoanId = 1
-//NOTE: this is set as the goerli url, but can be changed to reflect your RPC URL and network of choice
-const url = process.env.GOERLI_URL
-
-const customHttpProvider = new ethers.providers.JsonRpcProvider(url)
-
-async function main() {
- const network = await customHttpProvider.getNetwork()
-
- const sf = await Framework.create({
- chainId: network.chainId,
- provider: customHttpProvider
- })
-
- const loanFactory = new ethers.Contract(
- LoanFactoryAddress,
- LoanFactoryABI,
- customHttpProvider
- )
-
- const loanAddress = await loanFactory.getLoanAddressByID(LoanId)
-
- console.log(`The address of loan ${LoanId} is ${loanAddress}`)
-}
-
-main()
- .then(() => process.exit(0))
- .catch(error => {
- console.error(error)
- process.exit(1)
- })
diff --git a/projects/borrow-against-salary/scripts/initialFunding.js b/projects/borrow-against-salary/scripts/initialFunding.js
deleted file mode 100644
index 9353b56..0000000
--- a/projects/borrow-against-salary/scripts/initialFunding.js
+++ /dev/null
@@ -1,51 +0,0 @@
-//most recent loan address
-const ethers = require("ethers")
-const { Framework } = require("@superfluid-finance/sdk-core")
-require("dotenv").config()
-
-const loanAddress = "" //NOTE: must change to reflect actual loan address
-
-//NOTE - this should be run first to ensure that the contract has a small token balance
-
-async function main() {
- const url = `${process.env.GOERLI_URL}`
- const customHttpProvider = new ethers.providers.JsonRpcProvider(url)
- const network = await customHttpProvider.getNetwork()
-
- const sf = await Framework.create({
- chainId: network.chainId,
- provider: customHttpProvider
- })
-
- const employer = sf.createSigner({
- privateKey: process.env.EMPLOYER_PRIVATE_KEY,
- provider: customHttpProvider
- })
-
- const borrower = sf.createSigner({
- privateKey: process.env.BORROWER_PRIVATE_KEY,
- provider: customHttpProvider
- })
-
- const daix = await sf.loadSuperToken("fDAIx")
-
- const transferAmount = ethers.utils.parseEther("100")
-
- const borrowerTransferOperation = daix.transfer({
- receiver: loanAddress,
- amount: transferAmount // 100 dai
- })
-
- console.log("running transfer operation...")
-
- await borrowerTransferOperation.exec(borrower).then(console.log)
-}
-
-// We recommend this pattern to be able to use async/await everywhere
-// and properly handle errors.
-main()
- .then(() => process.exit(0))
- .catch(error => {
- console.error(error)
- process.exit(1)
- })
diff --git a/projects/borrow-against-salary/scripts/lend.js b/projects/borrow-against-salary/scripts/lend.js
deleted file mode 100644
index 71d95ee..0000000
--- a/projects/borrow-against-salary/scripts/lend.js
+++ /dev/null
@@ -1,49 +0,0 @@
-const ethers = require("ethers")
-const { Framework } = require("@superfluid-finance/sdk-core")
-const LoanContract = require("../artifacts/contracts/EmploymentLoan.sol/EmploymentLoan.json")
-const { network } = require("hardhat")
-const LoanContractABI = LoanContract.abi
-require("dotenv").config()
-
-//NOTE
-//lender should call lend on the above contract using sdk
-
-async function main() {
- const url = `${process.env.GOERLI_URL}`
- const customHttpProvider = new ethers.providers.JsonRpcProvider(url)
-
- const network = await customHttpProvider.getNetwork()
-
- const sf = await Framework.create({
- chainId: network.chainId,
- provider: customHttpProvider
- })
-
- //most recent loan address
- const loanAddress = "" //NOTE - must be updated to reflect actual loan address
-
- const lender = sf.createSigner({
- privateKey: process.env.LENDER_PRIVATE_KEY,
- provider: customHttpProvider
- })
-
- const employmentLoan = new ethers.Contract(
- loanAddress,
- LoanContractABI,
- lender
- )
-
- await employmentLoan
- .connect(lender)
- .lend()
- .then(tx => {
- console.log(tx)
- })
-}
-
-main()
- .then(() => process.exit(0))
- .catch(error => {
- console.error(error)
- process.exit(1)
- })
diff --git a/projects/borrow-against-salary/scripts/lenderApproval.js b/projects/borrow-against-salary/scripts/lenderApproval.js
deleted file mode 100644
index 1d5447e..0000000
--- a/projects/borrow-against-salary/scripts/lenderApproval.js
+++ /dev/null
@@ -1,58 +0,0 @@
-//most recent loan address
-const loanAddress = "" //NOTE - update w actual loan address
-const ethers = require("ethers")
-const { Framework } = require("@superfluid-finance/sdk-core")
-const LoanContract = require("../artifacts/contracts/EmploymentLoan.sol/EmploymentLoan.json")
-const LoanContractABI = LoanContract.abi
-require("dotenv").config()
-
-//NOTE
-//lender should call lend on the above contract using sdk
-
-async function main() {
- const url = `${process.env.GOERLI_URL}`
- const customHttpProvider = new ethers.providers.JsonRpcProvider(url)
-
- const network = await customHttpProvider.getNetwork()
-
- const sf = await Framework.create({
- chainId: network.chainId,
- provider: customHttpProvider
- })
-
- const lender = sf.createSigner({
- privateKey: process.env.LENDER_PRIVATE_KEY,
- provider: customHttpProvider
- })
-
- const daix = await sf.loadSuperToken("fDAIx")
-
- const employmentLoan = new ethers.Contract(
- loanAddress,
- LoanContractABI,
- lender
- )
-
- const borrowAmount = await employmentLoan.borrowAmount()
-
- const lenderBalance = await daix.balanceOf({
- account: lender.address,
- providerOrSigner: lender
- })
-
- const lenderApprovalOperation = daix.approve({
- receiver: employmentLoan.address,
- amount: borrowAmount
- })
-
- await lenderApprovalOperation.exec(lender).then(tx => {
- console.log(tx)
- })
-}
-
-main()
- .then(() => process.exit(0))
- .catch(error => {
- console.error(error)
- process.exit(1)
- })
diff --git a/projects/borrow-against-salary/scripts/updateEmployerFlow.js b/projects/borrow-against-salary/scripts/updateEmployerFlow.js
deleted file mode 100644
index d51a49d..0000000
--- a/projects/borrow-against-salary/scripts/updateEmployerFlow.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const ethers = require("ethers")
-const { Framework } = require("@superfluid-finance/sdk-core")
-require("dotenv").config()
-//here is where you'll put your loan address that you'll be interacting with
-const loanAddress = ""
-
-async function main() {
- //note - make sure that the proper URL is added
- const url = `${process.env.GOERLI_URL}`
- const customHttpProvider = new ethers.providers.JsonRpcProvider(url)
-
- const network = await customHttpProvider.getNetwork()
- const sf = await Framework.create({
- chainId: network.chainId,
- provider: customHttpProvider
- })
-
- const employer = sf.createSigner({
- privateKey: process.env.EMPLOYER_PRIVATE_KEY,
- provider: customHttpProvider
- })
-
- const daix = await sf.loadSuperToken("fDAIx")
-
- const employerFlowOperation = sf.cfaV1.updateFlow({
- receiver: loanAddress,
- flowRate: "2858024691358024",
- superToken: daix.address
- })
-
- console.log("running update flow script...")
-
- await employerFlowOperation.exec(employer).then(tx => {
- console.log("Your tx succeeded!")
- console.log(tx)
- })
-}
-
-// We recommend this pattern to be able to use async/await everywhere
-// and properly handle errors.
-main()
- .then(() => process.exit(0))
- .catch(error => {
- console.error(error)
- process.exit(1)
- })
diff --git a/projects/borrow-against-salary/test/EmploymentLoan.test.js b/projects/borrow-against-salary/test/EmploymentLoan.test.js
deleted file mode 100644
index a3b996a..0000000
--- a/projects/borrow-against-salary/test/EmploymentLoan.test.js
+++ /dev/null
@@ -1,788 +0,0 @@
-const { Framework } = require("@superfluid-finance/sdk-core")
-const { ethers , network} = require("hardhat")
-const { assert } = require("chai")
-const LoanArtifact = require("../artifacts/contracts/EmploymentLoan.sol/EmploymentLoan.json")
-const { deployTestFramework } = require("@superfluid-finance/ethereum-contracts/dev-scripts/deploy-test-framework");
-const TestToken = require("@superfluid-finance/ethereum-contracts/build/contracts/TestToken.json")
-
-
-let contractsFramework;
-let sfDeployer;
-let sf
-let dai
-let daix
-let admin
-let borrower
-let lender
-let employer
-let loanFactory
-let employmentLoan
-
-const alotOfEth = ethers.utils.parseEther("100000")
-
-before(async function () {
- //get accounts from hardhat
- [admin, borrower, lender, employer] = await ethers.getSigners()
-
- sfDeployer = await deployTestFramework();
- // deploy the framework locally
- contractsFramework = await sfDeployer.frameworkDeployer.getFramework();
-
- // initialize framework
- sf = await Framework.create({
- chainId: 31337,
- provider: admin.provider,
- resolverAddress: contractsFramework.resolver, // (empty)
- protocolReleaseVersion: "test"
- });
-
- // DEPLOYING DAI and DAI wrapper super token (which will be our `spreaderToken`)
- tokenDeployment = await sfDeployer.frameworkDeployer.deployWrapperSuperToken(
- "Fake DAI Token",
- "fDAI",
- 18,
- ethers.utils.parseEther("100000000000000000000000").toString()
- );
-
- daix = await sf.loadSuperToken("fDAIx");
- dai = new ethers.Contract(daix.underlyingToken.address, TestToken.abi, admin);
-
- const LoanFactory = await ethers.getContractFactory("LoanFactory", admin)
- loanFactory = await LoanFactory.deploy()
-
- await loanFactory.deployed()
-
- let borrowAmount = ethers.utils.parseEther("1000")
- let interest = 10
- let paybackMonths = 12
-
- await loanFactory.createNewLoan(
- borrowAmount, //borrowing 1000 fDAI tokens
- interest, // 10% annual interest
- paybackMonths, //in months
- employer.address, //address of employer
- borrower.address, //address of borrower
- daix.address,
- sf.settings.config.hostAddress
- )
-
- let loanAddress = await loanFactory.idToLoan(1)
-
- employmentLoan = new ethers.Contract(loanAddress, LoanArtifact.abi, admin)
-})
-
-beforeEach(async function () {
- await dai.mint(admin.address, alotOfEth)
-
- await dai.mint(employer.address, alotOfEth);
- await dai.mint(employer.address, alotOfEth);
-
- await dai.mint(lender.address, alotOfEth)
-
- await dai.approve(daix.address, alotOfEth)
-
- await dai.connect(employer).approve(daix.address, alotOfEth)
-
- await dai.connect(lender).approve(daix.address, alotOfEth)
-
- await daix.upgrade(alotOfEth)
-
- await daix.upgrade({amount: alotOfEth}).exec(employer);
-
- await daix.upgrade({amount: alotOfEth}).exec(lender);
-
- await daix.transfer({receiver: employmentLoan.address, amount: alotOfEth});
-})
-
-describe("employment loan deployment", async function () {
- it("0 deploys correctly", async function () {
- let borrowAmount = ethers.utils.parseEther("1000")
- let interest = 10
- let paybackMonths = 12
-
- let actualBorrowAmount = await employmentLoan.borrowAmount()
- let actualInterest = await employmentLoan.interestRate()
- let actualPaybackMonths = await employmentLoan.paybackMonths()
- let acutalEmployerAddress = await employmentLoan.employer()
- let actualBorrower = await employmentLoan.borrower()
- let actualBorrowToken = await employmentLoan.borrowToken()
-
- assert.equal(
- borrowAmount,
- actualBorrowAmount.toString(),
- "borrow amount not equal to intended amount"
- )
-
- assert.equal(
- interest,
- actualInterest,
- "interest rate not equal to intended rate"
- )
-
- assert.equal(
- paybackMonths,
- actualPaybackMonths,
- "payback months not equal to intended months"
- )
-
- assert.equal(
- employer.address,
- acutalEmployerAddress,
- "wrong employer address"
- )
-
- assert.equal(borrower.address, actualBorrower, "wrong borrower address")
-
- assert.equal(daix.address, actualBorrowToken, "wrong borrow token")
- })
-})
-
-describe("Loan is initialized properly", async function () {
- it("1 First flow into contract works correctly", async function () {
- let employerFlowOperation = daix.createFlow({
- receiver: employmentLoan.address,
- flowRate: "3215019290123456" // ~100k per year in usd
- })
-
- await employerFlowOperation.exec(employer)
-
- let employerNetFlowRate = await daix.getNetFlow({
- account: employer.address,
- providerOrSigner: employer
- })
-
- let borrowerNetFlowRate = await daix.getNetFlow({
- account: borrower.address,
- providerOrSigner: employer
- })
-
- let contractNetFlowRate = await daix.getNetFlow({
- account: employmentLoan.address,
- providerOrSigner: employer
- })
-
- assert.equal(employerNetFlowRate, -3215019290123456)
-
- assert.equal(borrowerNetFlowRate, 3215019290123456)
-
- assert.equal(contractNetFlowRate, 0)
- })
-
- it("2 - Flow Reduction works correctly", async function () {
- //testing reduction in flow
-
- const reduceFlowOperation = daix.updateFlow({
- receiver: employmentLoan.address,
- flowRate: "1000000"
- })
-
- await reduceFlowOperation.exec(employer)
-
- const newEmployerFlowRate = await daix.getFlow({
- sender: employer.address,
- receiver: employmentLoan.address,
- providerOrSigner: employer
- })
-
- const newBorrowerFlowRate = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: borrower.address,
- providerOrSigner: borrower
- })
-
- const newContractFlowRate = await daix.getNetFlow({
- account: employmentLoan.address,
- providerOrSigner: employer
- })
-
- assert.equal(
- newEmployerFlowRate.flowRate,
- "1000000",
- "wrong employer flow rate"
- )
-
- assert.equal(
- newBorrowerFlowRate.flowRate,
- "1000000",
- "wrong borrower flow rate"
- )
-
- assert.equal(newContractFlowRate, 0, "contract is not balanced")
- })
-
- it("3 - should show that a loan is not closed (anyone can become a lender)", async function () {
- //before the lend function is called, both isClosed and loanOpen are false
-
- const loanOpen = await employmentLoan.loanOpen()
- assert.equal(loanOpen, false);
-
- const isClosed = await employmentLoan.isClosed()
- assert.equal(isClosed, false);
- })
-
- it("4 Lend Function works correctly", async function () {
- //should reduce flow rate, test to ensure failure, then test update flow rate
- //try calling lend - should revert
-
- const borrowAmount = await employmentLoan.borrowAmount()
-
- const daixApproval = daix.approve({receiver: employmentLoan.address, amount: borrowAmount});
- await daixApproval.exec(lender);
-
- const employerUpdateFlowOperation = daix.updateFlow({
- receiver: employmentLoan.address,
- flowRate: "3215019290123456"
- })
-
- await employerUpdateFlowOperation.exec(employer)
-
- let borrowerBalBefore = await daix.balanceOf({account: borrower.address, providerOrSigner: admin});
-
- let lenderBalBefore = await daix.balanceOf({account: lender.address, providerOrSigner: admin});
-
- let borrowerFlowRateBefore = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: borrower.address,
- providerOrSigner: borrower
- })
-
-
- //SENDING A SMALL AMOUNT OF FUNDS INTO CONTRACT FOR BUFFER
- await daix.transfer({receiver: employmentLoan.address, amount: ethers.utils.parseEther("100")}).exec(employer);
-
- await employmentLoan.connect(lender).lend()
-
- let lenderBalAfter = await daix.balanceOf({account: lender.address, providerOrSigner: admin});
-
- let borrowerBalAfter = await daix.balanceOf({account: borrower.address, providerOrSigner: admin});
-
- let borrowerFlowRateAfter = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: borrower.address,
- providerOrSigner: borrower
- })
-
- let lenderFlowRateAfter = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: lender.address,
- providerOrSigner: lender
- })
-
- let employerFlow = await daix.getFlow({
- sender: employer.address,
- receiver: employmentLoan.address,
- providerOrSigner: lender
- })
-
- let expectedLender = await employmentLoan.lender()
- let loanStartedTime = await employmentLoan.loanStartTime()
-
- let expectedFlowRate = await employmentLoan.getPaymentFlowRate()
-
- assert.isAtLeast(
- Number(borrowerBalBefore + borrowAmount),
- Number(borrowerBalAfter),
- "borrower bal did not increase enough"
- )
-
- assert.isAtMost(
- lenderBalBefore - borrowAmount,
- Number(lenderBalAfter),
- "lender should have less money"
- )
-
- assert.equal(
- Number(borrowerFlowRateAfter.flowRate),
- Number(
- Number(employerFlow.flowRate) -
- Number(lenderFlowRateAfter.flowRate)
- ),
- "borrower flow rate incorrect"
- //borrower flow rate should decrease by paymentFlowrate amount after lend is called
- )
-
- assert.equal(
- //lender flow rate should increase by proper amount when lend is called
- Number(lenderFlowRateAfter.flowRate),
- Number(borrowerFlowRateBefore.flowRate) -
- (Number(borrowerFlowRateBefore.flowRate) - expectedFlowRate),
- "lender flowRate incorrect"
- )
-
- assert.equal(
- Number(lender.address),
- Number(expectedLender),
- "lender is not correct"
- )
-
- assert.notEqual(
- loanStartedTime,
- 0,
- "loan has not been started properly"
- )
- })
-
- it("5 - flow is reduced", async function () {
- const updateFlowOp = await daix.updateFlow({
- receiver: employmentLoan.address,
- flowRate: "10000"
- })
-
- await updateFlowOp.exec(employer)
-
- const borrowFlowToLender = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: lender.address,
- providerOrSigner: lender
- })
-
- const borrowerNewFlowRate = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: borrower.address,
- providerOrSigner: borrower
- })
-
- assert.equal(
- borrowFlowToLender.flowRate,
- "10000",
- "lender should be getting remainder"
- )
- //remaining amount should go to borrower
- assert.equal(
- borrowerNewFlowRate.flowRate,
- 0,
- "borrower new flow should be zero"
- )
- })
-
- it("6 - should allow a loan to become solvent again after a flow is reduced", async function () {
- let employerFlowOperation = daix.updateFlow({
- receiver: employmentLoan.address,
- flowRate: "3215019290123456" // ~100k per year in usd
- })
-
- await employerFlowOperation.exec(employer)
-
- const employerFlowRate = await daix.getFlow({
- sender: employer.address,
- receiver: employmentLoan.address,
- providerOrSigner: lender
- })
-
- const borrowTokenFlowToLenderAfter = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: lender.address,
- providerOrSigner: lender
- })
- //should be total inflow to contract from employer - flow to lender
-
- const borrowTokenFlowToBorrowerAfter = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: borrower.address,
- providerOrSigner: lender
- })
-
- //should be total inflow to contract from employer - flow to lender
-
- assert.equal(
- Number(borrowTokenFlowToBorrowerAfter.flowRate),
- Number(
- Number(employerFlowRate.flowRate) -
- Number(borrowTokenFlowToLenderAfter.flowRate)
- ),
- "borrower flow rate incorrect"
- //borrower flow rate should decrease by paymentFlowrate amount after lend is called
- )
-
- assert.equal(
- //lender flow rate should increase by proper amount when lend is called
- Number(borrowTokenFlowToLenderAfter.flowRate),
- Number(employerFlowRate.flowRate) -
- Number(borrowTokenFlowToBorrowerAfter.flowRate),
- "lender flowRate incorrect"
- )
- })
-
- it("7 - flow is deleted", async function () {
- //delete flow
-
- const deleteFlowOp = await daix.deleteFlow({
- sender: employer.address,
- receiver: employmentLoan.address
- })
-
- await deleteFlowOp.exec(employer)
-
- const newEmployerFlowRate = await daix.getFlow({
- sender: employer.address,
- receiver: employmentLoan.address,
- providerOrSigner: employer
- })
-
- const borrowFlowToLender = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: lender.address,
- providerOrSigner: lender
- })
-
- const borrowerNewFlowRate = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: borrower.address,
- providerOrSigner: borrower
- })
-
- assert.equal(
- newEmployerFlowRate.flowRate,
- 0,
- "employer to contract flow rate should be 0"
- )
-
- assert.equal(
- borrowFlowToLender.flowRate,
- 0,
- "lender should no longer receive daix"
- )
-
- //remaining amount should go to borrower
- assert.equal(
- borrowerNewFlowRate.flowRate,
- "0",
- "borrower new flow should be zero"
- )
- })
-
- it("8 - should allow loan to become solvent again after deletion ", async function () {
- //re start flow
-
- let employerFlowOperation = daix.createFlow({
- receiver: employmentLoan.address,
- flowRate: "3215019290123456" // ~100k per year in usd
- })
-
- await employerFlowOperation.exec(employer)
-
- const employerFlowRate = await daix.getFlow({
- sender: employer.address,
- receiver: employmentLoan.address,
- providerOrSigner: lender
- })
-
- const borrowTokenFlowToLenderAfter = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: lender.address,
- providerOrSigner: lender
- })
- //should be total inflow to contract from employer - flow to lender
-
- const borrowTokenFlowToBorrowerAfter = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: borrower.address,
- providerOrSigner: lender
- })
-
- //should be total inflow to contract from employer - flow to lender
- assert.equal(
- Number(borrowTokenFlowToBorrowerAfter.flowRate),
- Number(
- Number(employerFlowRate.flowRate) -
- Number(borrowTokenFlowToLenderAfter.flowRate)
- ),
- "borrower flow rate incorrect"
- //borrower flow rate should decrease by paymentFlowrate amount after lend is called
- )
- assert.equal(
- //lender flow rate should increase by proper amount when lend is called
- Number(borrowTokenFlowToLenderAfter.flowRate),
- Number(employerFlowRate.flowRate) -
- Number(borrowTokenFlowToBorrowerAfter.flowRate),
- "lender flowRate incorrect"
- )
- })
-
- //todo fix - looks like transfer and approve opp don't work here
- it("9 closing the loan early with payment from borrower", async function () {
- //borrower sends payment to pay off loan
- const amountLeft = await employmentLoan
- .connect(borrower)
- .getTotalAmountRemaining()
- const lenderBalBefore = await daix.balanceOf({account: lender.address, providerOrSigner: admin})
-
- //somewhat impractical, but we'll assume that the borrower is sent money from lender (they just need the money in general to pay off loan)
- await daix.transfer({receiver: borrower.address, amount: amountLeft}).exec(lender);
-
- await daix.approve({receiver: employmentLoan.address, amount: amountLeft}).exec(borrower);
-
- await employmentLoan.connect(borrower).closeOpenLoan(amountLeft)
-
- const lenderFlowRateAfterCompletion = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: lender.address,
- providerOrSigner: lender
- })
-
- const borrowerFlowRateAfterCompletion = await daix.getFlow({
- sender: employmentLoan.address,
- receiver: borrower.address,
- providerOrSigner: borrower
- })
-
- const employerFlowRateAfterCompletion = await daix.getFlow({
- sender: employer.address,
- receiver: employmentLoan.address,
- providerOrSigner: employer
- })
-
- const loanStatus = await employmentLoan.loanOpen()
-
- assert.equal(loanStatus, false)
-
- //This is exactly why there is a need for another variable besides @loanOpen - to differentiate between loans before and after being paid off.
- //It's impossible to do that with just @loanOpen.
- const isClosed = await employmentLoan.isClosed()
- assert.equal(isClosed, true);
-
- assert.equal(
- lenderFlowRateAfterCompletion.flowRate,
- 0,
- "lender flow rate should now be zero"
- )
- assert.equal(
- borrowerFlowRateAfterCompletion.flowRate,
- employerFlowRateAfterCompletion.flowRate,
- "employer should now send 100% of flow to employee"
- )
- assert.isAtLeast(
- Number(Number(lenderBalBefore) + Number(amountLeft)),
- Number(lenderBalBefore),
- "lender should see increase in borrow token balance"
- )
- })
-
- it("10 closing the loan early from lender", async function () {
- //other party sends payment to pay off loan
- let borrowAmount = ethers.utils.parseEther("1000")
- let interest = 10
- let paybackMonths = 12
-
- await loanFactory.createNewLoan(
- borrowAmount, //borrowing 1000 fDAI tokens
- interest, // 10% annual interest
- paybackMonths, //in months
- employer.address, //address of employer
- borrower.address, //address of borrower
- daix.address,
- sf.settings.config.hostAddress
- )
-
- let loan2Address = await loanFactory.idToLoan(2)
- let employmentLoan2 = new ethers.Contract(
- loan2Address,
- LoanArtifact.abi,
- admin
- )
-
- await dai.connect(borrower).mint(borrower.address, alotOfEth);
- await dai.connect(borrower).approve(daix.address, alotOfEth)
- await daix.upgrade({amount: alotOfEth}).exec(borrower);
-
- await daix.transfer({receiver: employmentLoan2.address, amount: alotOfEth}).exec(borrower);
-
- //create flow
-
- const createFlowOperation = daix.createFlow({
- receiver: employmentLoan2.address,
- flowRate: "3215019290123456"
- })
-
- await createFlowOperation.exec(employer)
-
- //lend
-
- await daix.approve({receiver: employmentLoan2.address, amount: borrowAmount.toString()}).exec(lender);
-
- //SENDING A SMALL AMOUNT OF FUNDS INTO CONTRACT FOR BUFFER
- // await daix.transfer({receiver: employmentLoan.address, amount: ethers.utils.parseEther("100")}).exec(employer);
-
- await employmentLoan2.connect(lender).lend()
-
- //make sure it worked
- const borrowerFlow = await daix.getFlow({
- sender: employmentLoan2.address,
- receiver: borrower.address,
- providerOrSigner: borrower
- })
-
- const lenderFlow = await daix.getFlow({
- sender: employmentLoan2.address,
- receiver: lender.address,
- providerOrSigner: lender
- })
-
- const employerFlow = await daix.getFlow({
- sender: employer.address,
- receiver: employmentLoan2.address,
- providerOrSigner: employer
- })
-
- let pass6Months = 86400 * (365 / 2)
- await network.provider.send("evm_increaseTime", [pass6Months])
- await network.provider.send("evm_mine")
-
- //close loan before it ends
- await employmentLoan2.connect(lender).closeOpenLoan(0)
-
- const borrowerFlowAfter = await daix.getFlow({
- sender: employmentLoan2.address,
- receiver: borrower.address,
- providerOrSigner: borrower
- })
-
- const lenderFlowAfter = await daix.getFlow({
- sender: employmentLoan2.address,
- receiver: lender.address,
- providerOrSigner: lender
- })
-
- const loanStatus = await employmentLoan2.loanOpen()
- assert.equal(loanStatus, false)
-
- const isClosed = await employmentLoan2.isClosed()
- assert.equal(isClosed, true);
-
- assert.isBelow(
- Number(borrowerFlow.flowRate),
- Number(employerFlow.flowRate),
- "borrower flow rate should be less than total amount sent into loan by employer prior to the closing of the loan"
- )
- assert.isAbove(
- Number(lenderFlow.flowRate),
- 0,
- "lender should have positive flow rate prior to loan ending"
- )
- assert.equal(
- borrowerFlowAfter.flowRate,
- employerFlow.flowRate,
- "borrower flow after loan ends should be equal to full value of employer flow"
- )
- assert.equal(
- lenderFlowAfter.flowRate,
- 0,
- "lender flow rate should be zero after"
- )
- })
-
- it("11 borrower closing the loan once completed", async function () {
- //borrower closes loan once complete
- let borrowAmount = ethers.utils.parseEther("1000")
- let interest = 10
- let paybackMonths = 12
-
- await loanFactory.createNewLoan(
- borrowAmount, //borrowing 1000 fDAI tokens
- interest, // 10% annual interest
- paybackMonths, //in months
- employer.address, //address of employer
- borrower.address, //address of borrower
- daix.address,
- sf.settings.config.hostAddress
- )
-
- let loan3Address = await loanFactory.idToLoan(3)
-
- let employmentLoan3 = new ethers.Contract(
- loan3Address,
- LoanArtifact.abi,
- admin
- )
-
-
- await dai.connect(borrower).mint(borrower.address, alotOfEth)
- await dai.connect(borrower).approve(daix.address, alotOfEth);
- await daix.upgrade({amount: alotOfEth}).exec(borrower);
- await daix.transfer({receiver: employmentLoan3.address, amount: alotOfEth}).exec(borrower);
-
- //create flow
-
- const createLoan3FlowOperation = daix.createFlow({
- receiver: employmentLoan3.address,
- flowRate: "3215019290123456"
- })
-
- await createLoan3FlowOperation.exec(employer)
-
- //lend
-
- await daix.approve({receiver: employmentLoan3.address, amount: borrowAmount.toString()}).exec(lender);
-
- //SENDING A SMALL AMOUNT OF FUNDS INTO CONTRACT FOR BUFFER
- await daix.transfer({receiver: employmentLoan.address, amount: ethers.utils.parseEther("100")}).exec(employer);
-
- await employmentLoan3.connect(lender).lend()
-
- //make sure it worked
- const borrowerFlow = await daix.getFlow({
- sender: employmentLoan3.address,
- receiver: borrower.address,
- providerOrSigner: borrower
- })
-
- const lenderFlow = await daix.getFlow({
- sender: employmentLoan3.address,
- receiver: lender.address,
- providerOrSigner: lender
- })
-
- const employerFlow = await daix.getFlow({
- sender: employer.address,
- receiver: employmentLoan3.address,
- providerOrSigner: employer
- })
-
- //we will close loan 1 hour after the loan expires
- let passLoanDuration = 86400 * (365 / 12) * paybackMonths + 3600
- await network.provider.send("evm_increaseTime", [passLoanDuration])
- await network.provider.send("evm_mine")
-
- //close loan before it ends
- await employmentLoan3.connect(borrower).closeCompletedLoan()
-
- const borrowerFlowAfter = await daix.getFlow({
- sender: employmentLoan3.address,
- receiver: borrower.address,
- providerOrSigner: borrower
- })
-
- const lenderFlowAfter = await daix.getFlow({
- sender: employmentLoan3.address,
- receiver: lender.address,
- providerOrSigner: lender
- })
-
- const loanStatus = await employmentLoan3.loanOpen();
- assert.equal(loanStatus, false);
-
- const isClosed = await employmentLoan3.isClosed()
- assert.equal(isClosed, true);
-
- assert.isBelow(
- Number(borrowerFlow.flowRate),
- Number(employerFlow.flowRate),
- "borrower flow rate should be less than total amount sent into loan by employer prior to the closing of the loan"
- );
- assert.isAbove(
- Number(lenderFlow.flowRate),
- 0,
- "lender should have positive flow rate prior to loan ending"
- );;
- assert.equal(
- borrowerFlowAfter.flowRate,
- employerFlow.flowRate,
- "borrower flow after loan ends should be equal to full value of employer flow"
- );
- assert.equal(
- lenderFlowAfter.flowRate,
- 0,
- "lender flow rate should be zero after"
- );
- });
-});
\ No newline at end of file
diff --git a/projects/flow-splitter/.gitignore b/projects/flow-splitter/.gitignore
deleted file mode 100644
index 00dad77..0000000
--- a/projects/flow-splitter/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
-node_modules
-.env
-coverage
-coverage.json
-typechain
-typechain-types
-
-# Hardhat files
-cache
-artifacts
-
diff --git a/projects/flow-splitter/README.md b/projects/flow-splitter/README.md
deleted file mode 100644
index 5cb8cf7..0000000
--- a/projects/flow-splitter/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Flow Splitter Super App
-
-This project demonstrates a Superfluid Super App smart contract that routes incoming streams to two receiver accounts on the basis of a set proportions.
-
-
-
-
-
-
-
-It also does a great job of demonstrating the usage of the SuperAppBaseCFA.
\ No newline at end of file
diff --git a/projects/flow-splitter/contracts/FlowSplitter.sol b/projects/flow-splitter/contracts/FlowSplitter.sol
deleted file mode 100644
index c21636f..0000000
--- a/projects/flow-splitter/contracts/FlowSplitter.sol
+++ /dev/null
@@ -1,220 +0,0 @@
-// SPDX-License-Identifier: UNLICENSED
-pragma solidity 0.8.18;
-
-// Uncomment this line to use console.log
-// import "hardhat/console.sol";
-
-import {SuperTokenV1Library} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
-import {SuperAppBaseFlow} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperAppBaseFlow.sol";
-import {
- ISuperfluid,
- ISuperToken
-} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
-
-/// @title FlowSplitter
-/// @author Superfluid | Modified by @0xdavinchee
-/// @dev A negative sideReceiverPortion portion is not allowed
-/// A portion > 1000 is fine though because the protocol will
-/// revert when trying to create a flow with a negative flow rate
-/// A flowRate which is less than 1000 will be rounded down to 0 and will revert
-/// Also an inflow which does not contain a whole number will be rounded down,
-/// this will also lead to a revert.
-contract FlowSplitter is SuperAppBaseFlow {
- using SuperTokenV1Library for ISuperToken;
-
- /// @dev Account that ought to be routed the majority of the inflows
- address public immutable MAIN_RECEIVER;
-
- /// @dev Account that ought to be routed the minority of the inflows
- address public immutable SIDE_RECEIVER;
-
- /// @dev Account that deployed the contract
- address public immutable CREATOR;
-
- /// @dev Super Token that the FlowSplitter will accept streams of
- ISuperToken public immutable ACCEPTED_SUPER_TOKEN;
-
- /// @dev number out of 1000 representing portion of inflows to be redirected to SIDE_RECEIVER
- /// Ex: 300 would represent 30%
- int96 public sideReceiverPortion;
-
- error INVALID_PORTION();
- error SAME_RECEIVERS_NOT_ALLOWED();
- error NO_SELF_FLOW();
- error NOT_CREATOR();
-
- /// @dev emitted when the split of the outflow to MAIN_RECEIVER and SIDE_RECEIVER is updated
- event SplitUpdated(int96 mainReceiverPortion, int96 newSideReceiverPortion);
-
- constructor(
- ISuperfluid host_,
- ISuperToken acceptedSuperToken_,
- address creator_,
- address mainReceiver_,
- address sideReceiver_,
- int96 sideReceiverPortion_
- ) SuperAppBaseFlow(host_, true, true, true) {
- if (sideReceiverPortion_ <= 0 || sideReceiverPortion_ == 1000) revert INVALID_PORTION();
- if (mainReceiver_ == sideReceiver_) revert SAME_RECEIVERS_NOT_ALLOWED();
- if (mainReceiver_ == address(this) || sideReceiver_ == address(this)) revert NO_SELF_FLOW();
-
- ACCEPTED_SUPER_TOKEN = acceptedSuperToken_;
- CREATOR = creator_;
- MAIN_RECEIVER = mainReceiver_;
- SIDE_RECEIVER = sideReceiver_;
- sideReceiverPortion = sideReceiverPortion_;
- }
-
- /// @dev checks that only the acceptedToken is used when sending streams into this contract
- /// @param superToken_ the token being streamed into the contract
- function isAcceptedSuperToken(ISuperToken superToken_) public view override returns (bool) {
- return superToken_ == ACCEPTED_SUPER_TOKEN;
- }
-
- /// @notice Returns the outflow rates to main and side receiver given flowRate_ and an arbitrary
- /// sideReceiverPortion_
- /// @dev If either returns 0, it will revert when trying to create a flow
- /// because the protocol does not allow creating flows with a flow rate of 0
- /// Also, if the sum of the two outflows is not equal to the inflow, it means the app will
- /// receive a residual flow.
- /// @param flowRate_ the inflow rate
- /// @param sideReceiverPortion_ the portion of the inflow to be redirected to SIDE_RECEIVER
- /// @return mainFlowRate the outflow rate to MAIN_RECEIVER
- /// @return sideFlowRate the outflow rate to SIDE_RECEIVER
- /// @return residualFlowRate the residual flow rate
- function getMainAndSideReceiverFlowRates(int96 flowRate_, int96 sideReceiverPortion_)
- external
- pure
- returns (int96 mainFlowRate, int96 sideFlowRate, int96 residualFlowRate)
- {
- mainFlowRate = (flowRate_ * (1000 - sideReceiverPortion_)) / 1000;
- sideFlowRate = (flowRate_ * sideReceiverPortion_) / 1000;
- residualFlowRate = flowRate_ - (mainFlowRate + sideFlowRate);
- }
-
- /// @notice Updates the split of the outflow to MAIN_RECEIVER and SIDE_RECEIVER
- /// @dev Only the creator should be able to call update split.
- /// @param newSideReceiverPortion_ the new portion of inflows to be redirected to SIDE_RECEIVER
- function updateSplit(int96 newSideReceiverPortion_) external {
- if (newSideReceiverPortion_ <= 0 || newSideReceiverPortion_ >= 1000) revert INVALID_PORTION();
- if (msg.sender != CREATOR) revert NOT_CREATOR();
-
- sideReceiverPortion = newSideReceiverPortion_;
-
- // get current outflow rate
- int96 totalOutflowRate = ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), MAIN_RECEIVER)
- + ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), SIDE_RECEIVER);
-
- int96 mainReceiverPortion = 1000 - newSideReceiverPortion_;
-
- // update outflows
- // @note there is a peculiar bug here where you can't change the outflow in any way
- ACCEPTED_SUPER_TOKEN.updateFlow(MAIN_RECEIVER, (totalOutflowRate * mainReceiverPortion) / 1000);
- ACCEPTED_SUPER_TOKEN.updateFlow(SIDE_RECEIVER, (totalOutflowRate * newSideReceiverPortion_) / 1000);
-
- emit SplitUpdated(mainReceiverPortion, newSideReceiverPortion_);
- }
-
- // ---------------------------------------------------------------------------------------------
- // CALLBACK LOGIC
-
- function onFlowCreated(ISuperToken superToken_, address sender_, bytes calldata ctx_)
- internal
- override
- returns (bytes memory newCtx)
- {
- newCtx = ctx_;
-
- // get inflow rate from sender_
- int96 inflowRate = superToken_.getFlowRate(sender_, address(this));
-
- // if there's no outflow already, create outflows
- if (superToken_.getFlowRate(address(this), MAIN_RECEIVER) == 0) {
- newCtx =
- superToken_.createFlowWithCtx(MAIN_RECEIVER, (inflowRate * (1000 - sideReceiverPortion)) / 1000, newCtx);
-
- newCtx = superToken_.createFlowWithCtx(SIDE_RECEIVER, (inflowRate * sideReceiverPortion) / 1000, newCtx);
- }
- // otherwise, there's already outflows which should be increased
- else {
- newCtx = superToken_.updateFlowWithCtx(
- MAIN_RECEIVER,
- ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), MAIN_RECEIVER)
- + (inflowRate * (1000 - sideReceiverPortion)) / 1000,
- newCtx
- );
-
- newCtx = superToken_.updateFlowWithCtx(
- SIDE_RECEIVER,
- ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), SIDE_RECEIVER)
- + (inflowRate * sideReceiverPortion) / 1000,
- newCtx
- );
- }
- }
-
- function onFlowUpdated(
- ISuperToken superToken_,
- address sender_,
- int96 previousFlowRate_,
- uint256, /*lastUpdated*/
- bytes calldata ctx_
- ) internal override returns (bytes memory newCtx) {
- newCtx = ctx_;
-
- // get inflow rate change from sender_
- int96 inflowChange = superToken_.getFlowRate(sender_, address(this)) - previousFlowRate_;
-
- // update outflows
- newCtx = superToken_.updateFlowWithCtx(
- MAIN_RECEIVER,
- ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), MAIN_RECEIVER)
- + (inflowChange * (1000 - sideReceiverPortion)) / 1000,
- newCtx
- );
-
- newCtx = superToken_.updateFlowWithCtx(
- SIDE_RECEIVER,
- ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), SIDE_RECEIVER) + (inflowChange * sideReceiverPortion) / 1000,
- newCtx
- );
- }
-
- function onFlowDeleted(
- ISuperToken superToken_,
- address, /*sender_*/
- address receiver_,
- int96 previousFlowRate_,
- uint256, /*lastUpdated*/
- bytes calldata ctx_
- ) internal override returns (bytes memory newCtx) {
- newCtx = ctx_;
-
- // remaining inflow is equal to total outflow less the inflow that just got deleted
- int96 remainingInflow = (
- ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), MAIN_RECEIVER)
- + ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), SIDE_RECEIVER)
- ) - previousFlowRate_;
-
- // handle "rogue recipients" with sticky stream - see readme
- if (receiver_ == MAIN_RECEIVER || receiver_ == SIDE_RECEIVER) {
- newCtx = superToken_.createFlowWithCtx(receiver_, previousFlowRate_, newCtx);
- }
-
- // if there is no more inflow, outflows should be deleted
- if (remainingInflow <= 0) {
- newCtx = superToken_.deleteFlowWithCtx(address(this), MAIN_RECEIVER, newCtx);
-
- newCtx = superToken_.deleteFlowWithCtx(address(this), SIDE_RECEIVER, newCtx);
- }
- // otherwise, there's still inflow left and outflows must be updated
- else {
- newCtx = superToken_.updateFlowWithCtx(
- MAIN_RECEIVER, (remainingInflow * (1000 - sideReceiverPortion)) / 1000, newCtx
- );
-
- newCtx =
- superToken_.updateFlowWithCtx(SIDE_RECEIVER, (remainingInflow * sideReceiverPortion) / 1000, newCtx);
- }
- }
-}
diff --git a/projects/flow-splitter/hardhat.config.js b/projects/flow-splitter/hardhat.config.js
deleted file mode 100644
index d5dd5f4..0000000
--- a/projects/flow-splitter/hardhat.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-require("@nomicfoundation/hardhat-toolbox");
-
-/** @type import('hardhat/config').HardhatUserConfig */
-module.exports = {
- solidity: "0.8.18",
-};
diff --git a/projects/flow-splitter/package.json b/projects/flow-splitter/package.json
deleted file mode 100644
index 0f12d51..0000000
--- a/projects/flow-splitter/package.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name": "hardhat-project",
- "devDependencies": {
- "@nomicfoundation/hardhat-toolbox": "^2.0.2",
- "hardhat": "^2.14.0"
- },
- "dependencies": {
- "@superfluid-finance/ethereum-contracts": "^1.6.0",
- "@superfluid-finance/sdk-core": "^0.6.5"
- }
-}
diff --git a/projects/flow-splitter/resources/diagram.png b/projects/flow-splitter/resources/diagram.png
deleted file mode 100644
index 48fddd0..0000000
Binary files a/projects/flow-splitter/resources/diagram.png and /dev/null differ
diff --git a/projects/flow-splitter/scripts/deploy.js b/projects/flow-splitter/scripts/deploy.js
deleted file mode 100644
index 88becbb..0000000
--- a/projects/flow-splitter/scripts/deploy.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// We require the Hardhat Runtime Environment explicitly here. This is optional
-// but useful for running the script in a standalone fashion through `node