Skip to content

Instantly share code, notes, and snippets.

@ssadler
Last active January 19, 2021 21:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssadler/7b1ca5a95ab35d6a61e2d7388adbccd4 to your computer and use it in GitHub Desktop.
Save ssadler/7b1ca5a95ab35d6a61e2d7388adbccd4 to your computer and use it in GitHub Desktop.
Maple data structure concept
-- Maple data structure concept
-- Scott Sadler, 18/01/21
-- Int is an Ethereum 32 bit word
-- Sometimes entities appear denormalized but should all be referenced by ID, either numeric or hash, depending on context
-- Fields like created, modified date not present
-- Nearly all of this was garnered from the "how-can-i-borrow-on-maple" page
--
data Borrower = Borrower
{ id :: Int
-- Is all this info published on chain? I suppose it's in the website DB and only visible to the delegates and admins
, name :: String
, address :: String
, website :: String
, contactName :: String
, contactNumber :: String
, socialMedia :: String
}
-- This is published on the app, and viewable by delegates
-- DB only
data RequestForQuote = RequestForQuote
{ id :: Int
, borrower :: Borrower
, amount :: Currency
, loanTerms :: LoanTerms
}
-- DB only
data Negotiation = Negotiation
{ delegate :: Delegate
, request :: RequestForQuote
, acceptedTerms :: Maybe LoanTerms
, onChainState :: NotCreated | CreatedPending | Funded
}
-- Backend only
-- Concept here is that it's like an Airbnb thread, which can include messages and other things like offers or refunds. Or Github PR with patches etc.
data Message = Message
{ negotiation :: Negotiation
, messageBody :: MessageBody
}
-- Backend only
data MessageBody = TextMessage | OfferMessage LoanOffer
-- Initially DB, then propagated to chain
data LoanTerms =
InterestOnly
{ amount :: Int
, amountUnit :: Currency
, collat :: BasisPoints
, collatUnit :: Currency
, loanMonths :: Int
, paymentFreq :: PaymentFrequency
, interestAPY :: Int
} |
-- The repayment structure could actually be a loan contract template, there is no technical reason it needs to be hardcoded in the db
-- However it would probably not be pragmatic to support totally dynamic loan algorithms to start with, MVP etc
SomeOtherRepaymentStructure
data Currency = Currency
{ symbol :: String
, decimals :: Int
}
-- Backend, periodically scraped from chain
data Reputation = Reputation
{ borrower :: Borrower
-- Converting to USD seems like the simplest way to give a historically stable view of transacted amounts
, usdCompleted :: Int
, usdPaid :: Int
, usdOutstanding :: Int
, usdFuture :: Int
, usdTotalCollateral :: Int
, goodRatings :: Int
, okRatings :: Int
, badRatings :: Int
}
-- Created on chain by borrower
data Loan = Loan
{ borrower :: BorrowerId
, requestId :: RequestId
, creditors :: [(PoolAddress, Amount)]
, terms :: LoanTerms -- Complete loan terms copied from db, hash is verified on db to match that in Negotiation
, collateralErc20 :: Address
, gracePeriodDays :: Int
, loanCreateDate :: Date
, loanStatus :: NotFunded | Funded | InArrears | Liquidated -- Or is liquidation partial per pool?
}
-- On chain, reflected to db
data Pool = Pool {
-- list of ERC20s with balance
-- list of liquidity providers with amount
-- Pool balance == sum(invested) - sum(loaned) must always be true
}
data LiquidityProvider = LiquidityProvider
{
-- etc
}
-- High level process:
--
-- Borrower creates request on db
-- Delegates negotiate
-- Borrower creates loan on chain (Metamask)
-- Scraper facilitates updating db with loan state changes, borrower reputation stats etc.
-- Ethereum contracts
--
-- At a minimum, i would guess:
-- * Gateway, which has a list of loans, and a list of liquidity pools
-- * Loans, keep repayment logic and balances separate
-- * Liquidity pools, one instance for each delegate, to keep balances separate
-- * Governance tracker, which tracks votes by LPs on polymorphic Amendments
-- Questions:
--
-- If delegates can make a counter offer, then how does that feed back into the loan request which may be funded by multiple delegates?
-- Does the borrower update their LoanRequest visible to all Delegates? Or can Loans have multiple repayment terms, but single liquidation?
-- Grace period in days or blocks?
-- I suppose the Master Loan Agreement is a contract template provided by Maple and designed to complement legally the on-chain smart contract?
-- And it becomes neccesary in the case that an under-collateralized loan goes into default?
-- I have missed out on governance here completely, are there any other large parts of the schema that arets of the schema that are not not present?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment