Code Monkey home page Code Monkey logo

v1-core's Introduction

Porter Smart Contracts Porter Smart Contracts

app testnet landing docs discord blog twitter

Security

Please report any security issues to [email protected]

V1

Smart Contracts powering the Porter protocol.

Contracts

mainnet rinkeby
BondFactory 0x9f20521ef789fd2020e708390b1e6c701d8218ba 0x0ae42cF40Fb46A926e2dcCE92b2Fe785d2D1E0A0
Bond Implementation 0x79537dcba69fea2b8dc8292b3726195fe947e332 0xebc0d87f2fb27c967a3cb0e36f279579b0116261

What does it do? How does it work?

The Porter V1 protocol allows a borrower to create a Bond. Each minted bond share has some amount of collateral backing and will be redeemable 1 share for 1 stablecoin at maturity. To incentivize lenders, the bond shares will be sold at a discount either OTC or through an auction.

For more information on this process, the documentation site gives an overview of what the protocol does and some of the concepts like zero coupon bonds and the difference between "Simple" and "Convert" Bond types. For how the protocol works, check out the spec:

  • overview — An overview of the Bond and BondFactory as well as what actions Borrowers and Lenders can perform.
    • bond — More detailed look at the Bond actions and design decisions.
  • architecture — A technical document explaining how the Contracts interact and the lifecycle from deployment, creating a bond, and actions performed on that bond.
  • permissions — The trust model and implementation of that model.
  • state machine — The Bond represented as distinct states.

Development

For local development there are environment variables necessary to enable some hardhat plugins. To interact with the frontend, you will also need to update your wallet with a new network pointing to hardhat's network.

Network Name: Hardhat
RPC URL: http://localhost:8545
Chain ID: 31337
Currency: ETH

Then, run the local node with npx hardhat node. If forking a blockchain, avoid deploying dependencies with the --no-deploy flag: npx hardhat node --no-deploy.

Deployment

Using hardhat-deploy all of the scripts in the ./deploy folder are run. This will run the whole integration flow as well which includes deploying of the factory, tokens, creating bonds, doing bond actions, and starting auctions. If that is not desired, add a tags flag with what you want to deploy.

npx hardhat deploy --tags main-deployment # deploy bond factory
npx hardhat deploy --tags test-deployment # and deploy tokens
npx hardhat deploy --tags permissions # and grant roles & permissions
npx hardhat deploy --tags e2e # and run e2e test
npx hardhat deploy --tags bonds # and deploy test bonds
npx hardhat deploy --tags auctions # and start bond auctions
npx hardhat deploy --tags actions # and do bond actions

Additionally, all of the above commands can be run with --network rinkeby to deploy to the Rinkeby test network.

Note: The deploy script will run with the npx hardhat node as well as the npx hardhat test tasks.

Verification

The deployment script will automatically verify the BondFactory, Implementation contract, and TestERC20 token. To verify a contract not deployed within that script, use the hardhat-etherscan task.

npx hardhat verify <address>

Testing

Running the hardhat test suite

npx hardhat test

Fork testing requires first running the mainnet-fork

npx hardhat node

and making the target for testing the local node

npx hardhat test --network localhost

Running the fuzzing test suite with Echidna

Other useful commands

npx hardhat help
npx hardhat compile # create contract artifacts
npx hardhat clean # removes artifacts and maybe other things
npx hardhat coverage # runs the contract coverage report
npx hardhat integration # runs the integration task
npx hardhat settle-auction --auctionId <auctionId> # settles an auction
npx eslint '**/*.{js,ts}' --fix
npx prettier '**/*.{json,sol,md,ts}' --write
npx solhint 'contracts/**/*.sol' --fix

v1-core's People

Contributors

emersoncloud avatar luckyrobot avatar namaskar-1f64f avatar russeii avatar

Stargazers

 avatar  avatar  avatar  avatar

v1-core's Issues

Leverage deployed gnosis auction vs fork

Interaction with Gnosis Auction

Options

We have three main options on how to interface with Gnosis auction

  1. Use the contract as-is from the deployed address (recommended)
  2. Fork the contract and redeploy without changing the source code
  3. Fork and edit source code for a custom use case

Use the contract as-is from the deployed address (recommended)

  • More trust from users - they can see there's been over 30k transactions to this contract.
  • Users are confident that the auction code has not been modified & has the same level of security as the original
  • We can interact directly with both their testnet + mainnet deployments without any deployment overhead.
  • Technically gnosis auction has the ability to add a fee - but two separate developers said they will not be.
  • Possibility for us to use their subgraph instead of implementing it ourselves.
  • Our auctions will show up in Gnosis auction UI.
  • Recommended path from Peteris.

Fork the contract and redeploy without changing the source code

  • No quick way for users to tell that this fork has not been modified.
  • Redeploying the contract would cost 5m gas (.5 eth @ 100gwei).
  • Our auctions would not show up in Gnosis UI.
  • All porter data would be isolated.

Fork and edit source code for a custom use case

Add's more auditing overhead, protocol risk, and complexity. Avoid if possible.

Questions

If we want to take some sort of fee for facilitating or send a fee to the Sherpa, how would we do that?

There are a few different ways we can handle this:

  1. Take a certain number of the bonds after they have been created. These can either be sent to the porter treasury or distributed to sherpas. In the current implementation - the entity that creates the bond (broker contract) would be sent all of the bonds after creating them. The broker contract could keep 3% of the bonds and then send the other 97% of the bonds to the borrower.
  2. Take a certain % of the borrowing tokens or bonds after a successful auction. If we initiate the auction from our Broker - it will be the auctioneer. It would receive the borrowingToken upon the settlement of the auction and could keep 2% them and send the rest to the borrower (recommended)

@Namaskar-1F64F please correct me if I missed anything

Research clone factory to deploy erc20 bond contracts

We are leaning towards using a BondFactory to deploy a new ERC20 bond token before each gnosis auction and using the bond token as the auctioningToken

https://ropsten.etherscan.io/tx/0x387efb77e56e0b3f6066c8a853464c9a4b1b24ffbf0d49a0063793168f058638

2,271,956 gas to deploy current bond contract

https://ropsten.etherscan.io/tx/0xc164917ff5f918aec456e8d9912bd40ea9fc2715a69177093b421a93c6d2c498
1,154,924 gas to deploy very basic erc20 token

@ 100 gwei
100k gas = .01 eth
1m gas = .1 eth
10m gas = 1 eth

So ~ .2eth ($500) to deploy a bond contract - This seems like a lot but might be negligible to the DAOs issuing debt

Are there ways we can reduce these costs significantly?

https://github.com/optionality/clone-factory - would something like this be an option? Repo is quite old

Add support for multiple collateral types

What would it look like for us to support multiple collateral types?

Imagine an issuer would like to collateralize each bond with multiple types of collateral.

For example: each bond would be backed by 10 ABG (AlwaysBeGrowing Governance Token) and 5 ABC (AlwaysBeChanging Governance Token) and should be convertible into 2 ABG and 1 ABC tokens

1. Ratio Based

We could accept a collateralization ratio and a convertibility ratio for each token individually. These numbers are then used when dealing with any of the methods that interact with the collateral.

Collateralization ratio

To get the numbers in the example above - the collateralization ratio for ABG would be 1:10 and the ratio for ABC would be 1:5

Convertibility

Example convertability ratios would be 1:2 for ABG and 1:1 for ABC. This means a user could call convert to burn one of their bonds for 2 ABG and 1 ABC tokens.

2. Bucket Based

An alternative method would be to define the ratios of each type of token that will be backing the bond. For example - the backing ratio could be 1/3rd ABC and 2/3rd ABG tokens. The backing ratios must always add up to 1.

We can refer to the backing ratio as a bucket. So one bucket is .333 ABC + .666 ABG

The backing ratio would be provided at bond creation and would not be configurable after creating a bond.

Collateralization ratio

This would be how many buckets are backing the bond. A collateralization ratio of 1:15 would mean that 10 ABG tokens 5 ABC tokens would back each bond.

Convertibility

The convertibility ratio would be bond:bucket - so convertibility ratio of 1:3 means that each bond can be converted at any time for 3 buckets worth of bonds. So, 1 bond can be burned for 1 ABC and 2 ABG tokens.

Questions

  • initialize in our bond contract would need to accept an array of collateral types. @Namaskar-1F64F is there a limit here? What would be the max array items a caller would be able to add?
  • How would the ratios be stored?

Add auction contract + add auction to technical spec

Figure out what we need to do to adapt EasyAuction to our use case.

Questions:
How to send out bond tokens on successful auction?
Where should collateral be stored?
Multiple EasyAuction contracts or just one?

Create a diagram that outlines the permissions for each role

Currently when creating a bond we are going towards a pattern where the Broker creates the bond and becomes the "owner". The issuer has some special privileges on the bond itself like withdrawing collateral. Who should own the bond and what permissions should each action have?

Roadmap

Unofficial Technical Roadmap

This is a rough technical roadmap of what needs build for our initial vision. Timeline is subject to change. Many of the items can be done in parallel.

gantt
    title Unofficial Technical Roadmap
    dateFormat  YYYY-MM-DD
    excludes    weekends

axisFormat %b-%d
Secureum CAREX Report : milestone, m2, 2022-04-07, 0d
Audits Finished : milestone, m3, 2022-05-11, 0d
Testnet Ready : milestone, m4, 2022-05-13, 0d
Launch Week :milestone, m5, 2022-05-23, 0d


    section Frontend
    Core Page Design           :active, a1, 2022-04-01, 31d
    Auxiliary Page Design     :a2 ,2022-04-29, 3d
    section Smart Contracts
    Pre-audit fixes      :active, b1, 2022-04-07  , 7d

    section Audits
    Zellic          :c1, 2022-04-18, 5d
   Spearbit     :c2,  2022-05-02 , 7d

section Confrences
Permissionless :e1, 2022-05-16, 5d

0-3 Months (May mainnet launch internal goal) (July mainnet is public date)

3-6 Months

Explore governance

Explore tokenomics
Porter REFI

Trading platform
This will allows investors to trade their bonds which is one of the big value adds of bonds. They are liquid and tradable while loans are not. This is a high priority.

Credit default swaps
This will allow investors to hedge themselves when purchasing bonds

Bond ratings on demand
This will be helpful but Prime is working on this and it isn't a high priority.

Backing debt with a lien on the treasury or project token mint function
This will make debt much more trustless.

Ideas

#128
porter-finance/frontend#7

Resources

https://a16z.com/2020/01/09/progressive-decentralization-crypto-product-management/
https://docs.porter.finance

Issuance Fee

@jordanalexandermeyer Do we want an issuance fee for our V1?

If I remember correctly:

  • We want to take the fee in bonds every time new bond tokens are minted.
  • 2% fee

Broker pattern or token pattern?

Broker pattern vs token pattern

We have the option of having the broker contract act as an intermediary that handles the main functionality of our protocol (broker pattern) or we can implement this functionality on each of the different tokens themselves (token pattern)

Do we have one broker contract that holds all the collateral, handles convertability, handles repayment, handles bond redemption for each of the bonds? Or should we implement that logic on the bond itself and limit the functionality of the broker to just deploying the bond tokens?

  • AAVE uses the broker pattern while Compound uses the token pattern

  • We will be deploying a new bond contract for every single auction. For gas savings - we may want to keep the bond functionality minimal (Broker pattern). This may not be an issue if we follow the clone pattern for new bonds. This will be explored further in #15

Auction or OTC? (draft)

Bonds should be decoupled from gnosis auction. Gnosis auction is just a mechanism for selling the bonds. They should be designed in a way where they could be sold directly to lenders - or through other means.

Do we want to have the Auction for v1? Would it make sense to let borrowers decide the bond interest rate and allow investors to purchase the bonds at that given price instead of an Auction?

This would allow us to ignore the complicated mechanisms of gnosis auction and figure out of the demand for issuing / buying bonds is there.

Use tokens instead of ratios for collateral arguments

From #74 (comment)

Instead of determining the amount of tokens the user is allowed to mint in this step, can we accept supply as a parameter in the constructor along with convertibleTokens and collateralTokens?

supply + convertibleTokens will give the convertible tokens / bond
supply + collateralTokens will give the collateral tokens / bond

Issuers can't mint tokens until the correct amount of convertibleTokens and collateralTokens are deposited. And they can only mint supply tokens.

Thoughts?

Should we have `isBond` and a list of our bonds?

In Maple's contracts, they have an isLoan function in their LoanFactory here. I assume this is used to check if a contract address is a Maple loan. Also, they keep a list of all the loans here.

I propose @RusseII look into whether we should have these functions on our BondFactory.

What permissions does the Broker need on the Bond

We can have bond issuers go through the broker to create bonds. This would make the Broker "owner" of the bond. On the other hand, issuers could create bonds directly through the bond factory itself.

What benefits does having the Broker be the owner provide us? Should we purposefully disallow creation of bonds if the issuer does not go through the broker contract?

Setup scaffolding for frontend + make introductory design decisions

Any other frontend pre-work that we can do before we get the VectorDAO designs?

Upgradability

Upgradability

Refi

In the future - we will add a way for users to refinance their bonds with a refi vault.

We added two roles to facilitate this - the WITHDRAW_ROLE and the MINT_ROLE

Refi vault user flow:
Issuer makes new Simple/Convert product
Issuer makes new Refi vault
Issuer grants the MINT_ROLE of new product to Refi vault
Issuer grants the WITHDRAW_ROLE of old product to Refi vault

This would allow the refi vault to create new bonds and use the payments to repay the old bond and withdraw the collateral.

General

There is nothing else specific for upgradability built into the contracts. After a new bond is made it is immutable and can never be changed. Upgrades will come from up deploying new versions of the BondFactory contract and updating the contract used by our frontend.

Fill out issue exploring description on chain

Should we store description on chain?

https://ethereum.stackexchange.com/questions/11556/use-string-type-or-bytes32

Gas cost is 20k gas per 32 characters.

Example: It would be 140k gas to store this on chain:

Bribe Protocol aims to revolutionize dGov with incentivized protocol participation. Improving upon current DAO governance models, Bribe coordinates voters into powerful coalitions up for auction by a highest bidder.

(215 characters / 32) = 6.7 rounded up is 7
(20k gas * 7) = 140k

@ 100 gwei
100k gas = .01 eth
1m gas = .1 eth
10m gas = 1 eth

Pros

Cons

How to handle bond auctions?

Now that we are selling overcollateralized convertible bonds without liquidations - the price of bonds can change significantly based on the price of the underlying collateral.

If the price of the collateral drops below 100% collaterialization ratio - the bonds will drop in price
If the price of the collateral appreciates so it's profitable to purchase the bonds and immediately convert the price of the bonds will increase significantly and track the token.

Once a gnosis auction is started there is no way to cancel the ongoing auction. We theoretically still would be able to modify the collateral backing the bond or the convertibility ratio though...

Do we know what the expected user flow is? I would guess that no matter what bondholders would probably advertise the auction ahead of time. Additionally this would likely be a topic on their governance forum no? Could the governance form be used as the intent to issue a bond?

How long do bond-purchasers need to do due diligence on the bonds?

Add a feature that allows issuers to grant and revoke repayment + withdraw collateral access

After releasing Porter Convert, we'd like to release a refinancing product. This product would allow users to repay old bond issuances with a new bond issuance. The following process would take place:

  1. Investor buys new bond
  2. Money is used to pay off old bond collateral
  3. Old bond collateral is transferred to the new bond vault
  4. New bonds are minted against collateral and given to investor.

Therefore, an issuer would need to allow our refinance contract to repay the bond and withdraw their collateral. We should add a feature that allows issuers to grant and revoke repayment + withdraw collateral access. We need to add this feature before our audit.

Handle case with partial repayment and default

When an issuer repays back a partial amount of borrow token and the bond defaults, give the bond holders a portion of that token in addition to the collateral.

Question: Should the issuer instead be able to withdraw the deposited borrow amount?

Add description to bonds

In current implementation of the current product spec there is a field for prospectus.

This may no longer be necessary since bonds are now overcollaterlized. Check with Jordan if its still in product spec after it gets updated on March 2nd

Start Porter Subgraph

  • Learn about https://thegraph.com/en/
  • Figure out how exactly we can use this in our protocol - I'm thinking that we create a subgraph then query the subgraph to get the information needed on each of our product screens: https://github.com/porter-finance/product/tree/main/spec/pages
  • Note down what data we'd need to expose from our smart contracts for the subgraph to enable our frontend
  • Made a subgraph repo (public)
  • What would the costs of using the Graph be?
  • Estimate level of work to build out the full subgraph
  • Any better alternatives?

There are a lot of examples of subgraphs.

Should we use NFTs to represent debt position?

Overview

When a new bond is created - we can mint a NFT and send it to the issuer of the bond.

This NFT would serve two primary purposes:

  1. Access control: Only the owner of the NFT would be allow to interact with specific methods on the bond, like withdrawing collateral. Ownership transfer is as simple as transferring the NFT.
  2. Asset Representation: This would give borrowing an asset that represents their borrowing position. Thier borrowing position would be viewable in etherscan and in defi aggregators.

Technical

The current implementation relies on the issuer address being passed in at the creation of the bond. There is no current way to update the issuer. It would possible to add that logic into the contract

Using NFTs would simplify transferability - as transferring the issuer is just transferring the NFT

The Broker contract would follow ERC721 and would be responsible for minting an NFT during the bond issuance.

Misc

Jelly.fi does something similar

Once a lender chooses a borrower, an NFT is generated on-chain that represents the parameters of the agreement. Each NFT comes with unique artwork. In addition, the NFT displays essential information about the agreement between the borrower and lender that can be viewed on-chain at any time. Each position can be sold to another person.

Further Research

@RusseII to watch https://www.youtube.com/watch?v=VgsODQMGI2M
@RusseII to explore what the NFT implementation would look like

Questions

@Pet3ris is there anything I'm missing here?

Create state transition diagram

The bond has different states in which different actors can perform different actions. What are all of those actors/actions/reactions?

Implement simple bond contract + add details to bond section of technical spec

Current info about bondtoken here - #1

It may help if we start with the simplest design - no factories - no convertibility - no upgradability -imagine we want to create just a simple bond token.

  1. The state of the bond needs to be managed.
  • What is the interest?
  • When is the payment due?
  • How much is owed?
  • What is the current state of the bond? (good standing, defaulted)
  1. The borrowing party needs a way to pay back the bond
  2. The lending parties need a way to redeem their bonds for interest + principle at maturity (edited)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.