- Overview
- Main Contracts
- Libraries
- Verified Contracts
- Mainnet - Deployed 2023-02-10
- Mainnet - Deployed 2022-12-19
- Goerli Testnet - Deployed 2023-02-10
- Gorli Testnet - Deployed 2023-01-09
- Debt DAO Function Registry
- Interfaces
- LineFactory
- SecuredLine
- Spigot
- Escrow
- ABIs
- LineFactory
- SecuredLine
- Spigot
- Escrow
Overview
<< feel like we need more explainers here >>
<< basic basics >>
Master slave architecture with Line of Credit owning submodules - Spigot, Escrow, InterestRate
Ensure modularity and extensibility of integrations, security fixes, and financial covenants without affecting logic of other components of the system.
Line of Credit contract is also designed to be modular with internal functions that get overwritten by adapters for each module. For example _healthcheck gets overwritten by EscrowedLine to check if minimum collateral ratio has been breached.
Generally this type of architecture introduces lots of security risks in solidity mutating state in different contracts. Debt DAO mitigates this risk by following functional programming standards to avoid side effects in all function calls. We generally only change state in external functions and almost always right before the return statement. Overwritten internal functions/modifiers MUST only return early or add extra revert conditions, never create side effects.
Main Contracts
- Spigot.sol
- SecuredLine.sol
- Full SecuredLine dev docs (todo make dev docs and link)
- Only credit agreement currently supported in Debt DAO Marketplace
- Combines core LineOfCredit, SpigotedLine, and EscrowedLine logic for revenue + asset backed debt
- Modifies internal functions to add additional security checks to
_canDeclareInsolvent()
,liquidate()
,_healthcheck()
, and_init()
- LineOfCredit.sol
- Core financial data and business logic for lending agreement
- Allows dynamic interest rate market for borrower by letting lenders compete on rates and tokens lent
- SpigotedLine.sol
- Integration contract between LineOfCredit.sol and Spigot.sol allowing lines to own Spigots. This lets us
- LineOfCredit literally owns revenue streams to repay its own debt
- programmatically adjust revenue split to give Lenders 100% if borrower defaults
- Holds excess revenue tokens claimed from Spigot and credit tokens bought from swapTarget for future repayments, liquidations, or returning to borrower after repayment
- EscrowedLine.sol
- Light wrapper around Escrow contract to liquidate borrower collateral when they go into default
- LineFactory.sol
- Essentially āThe Marketplaceā. Defines āmarket regulationsā as global system vars that all lenders and borrowers are confined to
- Oracle - defines all tokens allowed to be lent, borrowed, and used as collateral in the credit marketplace
- SwapTarget - The exchange/market maker that will trade all tokens earned as revenue in Spigots to credit tokens owed to lenders
- Arbiter - The neutral 3rd party that facilitates all repayments, liquidations, defaults, refinancing, etc.
Libraries
- LineLib.sol
- General functionality shared across all contracts in repo e.g. safe transferring tokens, checking balances, etc.
- Stores all possible health statuses for Line of Credits
- CreditLib.sol
- Stores basic functions for interacting with Lender positions
- computing the id for a position
- Updating position financials e.g. accruing interest or repaying debt
- CreditListLib.sol
- Helper for array operations like adding and removing positions or sorting.
- Used for managing lender priority repayment queue with list of position ids
- SpigotLib.sol
- Handles calling priviliged functions on owned contracts namely claiming revenue
- updates Spigot state for revenue splits and recipients
- SpigotedLineLib.sol
- Trade logic for swapping, figuring out trade prices, and 0x integration logic
- Spigot ownership logic for
- EscrowLib.sol
- Calculates the total value of collateral assets escrowed
- Calculates collateral ratio based on collateral value
- Ensures that whitelisted (enabled) collateral enabled has a price feed
- LineFactoryLib.sol
- Stores functionality related to deploying multiple contracts simultaneously
- MutualConsent.sol
- Forked from Set Protocolās manager contract for Index Coop
- Essentially a 2/2 multisig baked into your contract
- Ensures that two predefined addresses both sign a transaction with the exact same inputs and then executes the function with those parameters after the second party has called the function (aka consented)
Verified Contracts
Mainnet - Deployed 2023-02-10
Main Contracts
- ModuleFactory:
0xa968954770Af47881309d99E36d61C725082B48E
- LineFactory:
0xe725e25961e04E685A573B1587F8297aC233cD07
- Oracle:
0x5a4AAF300473eaF8A9763318e7F30FA8a3f5Dd48
- FeedRegistry
0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf
- Arbiter: (debt dao line ops multisig)
0xE9039a6968ED998139e023ed8D41c7fA77B7fF7A
- SwapTarget: (0x exchange proxy)
0xdef1c0ded9bec7f1a1670819833240f027b25eff
Libs
- LineLib:
0x5250c45087cdAA3dACCBe44BdA987A1f7f3edb02
- CreditLib:
0x9dC5F61dc380BbC3fFBF62Ea1d485BB6122AA9dB
- CreditListLib:
0x3986081dE97eaB5128A99c852466728dD1D9b22F
- SpigotLib:
0x143CA632FdD00218A47e6bE8A117a5595c4b5E5f
- SpigotedLineLib:
0x49a04826F704CF2dFCd5d08bE565871B00932b67
- LineFactoryLib:
0x6e0B15415029A3F858Ea9585F50D35E689dCA0Ae
- EscrowLib:
0xcB442FdF4462123A99dA3627D5Ad4115f6323C0e
Mainnet - Deployed 2022-12-19
Main Contracts
- ModuleFactory:
0xC45677cf45080Df035fD4F2df082ae47EacA729e
- LineFactory:
0xd008d9b4e08DCdaF7F68dAe936EF5cb5FB84F3f4
- Oracle:
0x9EAb5422288805b59391D1442e29Fa16a04A0B22
- Arbiter: (debt dao line ops multisig)
0xE9039a6968ED998139e023ed8D41c7fA77B7fF7A
- SwapTarget: (0x exchange proxy)
0xdef1c0ded9bec7f1a1670819833240f027b25eff
Libs
- LineLib:
0x94a5DA097d3f27962980ab1a1761Cd9e7456252E
- CreditLib:
0x8e73667B175887B106A9F803F8b62DeffC11535e
- CreditListLib:
0x446912dF9f54cf08fA4Fe1bDDe9e3e09E39C09Ca
- SpigotLib:
0xf02b1843cae1A65A7CBD14C13251b4ec9fF23d78
- SpigotedLineLib:
0xA43508CEDDBc3067f236f05b98AEa7aad943A467
- LineFactoryLib:
0xdF146a765eA280dFbf1C98163FD894E4695867FB
- EscrowLib:
0x8f6813Ce50a201D77637b8D24E99feAAa6Ab0Bd2
Goerli Testnet - Deployed 2023-02-10
Main Contracts
- Module Factory:
0x627Bbf3200EeC7c757289caED46C74AE241be0b0
- LineFactory:
0x400C6ec8B915e5703E043AA646EA5cb225288D6c
- Oracle:
0x7EDe2714Ad78544cb3834a24215Fe5F871ea7B70
- Arbiter: (Thomas)
0x0325C59BA55F6705C2AC6213628222Cf193d423D
- SwapTarget: (MockZeroEx)
0xcb7b9188aDA88Cb0c991C807acc6b44097059DEc
Libs:
- LineLib:
0x3125CB1b18C43896530Ea5f743B6D135fC652307
- CreditLib:
0x544a5646E1EF70dd8aDE296eC362BAd2C11426DC
- CreditListLib:
0x45bC2F4f4ce55ca6b1B02CDc8Bbd359f4b5B5EBF
- SpigotLib:
0x5Fc4B340a51401d07E81962413c48C548777Aa8D
- SpigotedLineLib:
0x08fB2A4ee88Bc96773aA929db95706c5111eA615
- LineFactoryLib:
0x415984f675ba467b3793C198b8CbEff08Af6EB11
- EscrowLib:
0x42af022e0fDe1131a08FFAf5dA1cd58b16f03173
Gorli Testnet - Deployed 2023-01-09
Main Contracts
- Module Factory:
0x70a951E2D2Ee4Fc6D38325AB0e0ED1a789Eb2D8E
- LineFactory:
0x0E81C743aF01Dc8D77A0cC002daE94EB0433399d
- Oracle:
0x7EDe2714Ad78544cb3834a24215Fe5F871ea7B70
- Arbiter: (Thomas)
0x0325C59BA55F6705C2AC6213628222Cf193d423D
- SwapTarget: (MockZeroEx)
0xcb7b9188aDA88Cb0c991C807acc6b44097059DEc
Libs:
- LineLib:
0xec6e736d8774f9949Cb0985cB4cc1ec9224a601c
- CreditLib:
0xDb19FCFe818493ee84Ce33137b0851DE88c9fF13
- CreditListLib:
0x627A8B08F7d0F10F6BDC4Ef668841fb10B3B2b1d
- SpigotLib:
0x78064A7b6259BcE045d377593288273D22459dfe
- SpigotedLineLib:
0x09d811eEab9893d2285b38728574c55401Ea6A9B
- LineFactoryLib:
0xC6805c0B1Ba484128cE97e92CF5ca09d82B3D51e
- EscrowLib:
0x20b7C07AF032C3a999D9CECf804f4D3b9Fac6a3F
Example Contracts
- Mock Revenue Contract:
0x644cb5d8003efdb1840d5c061ec0df592123dd05
TODO integrate bobs comments here into function registry
Debt DAO Function Registry
Contract | Function Name | Modifiers | Description | Risks of Calling | Calls (sequential order DESC) | Called By | Function Signature |
---|---|---|---|---|---|---|---|
Spigot.sol | getOwnerTokens(address token) | view | Returns the amount of Revenue Tokens held by Spigot that the Owner can withdraw. | ||||
Spigot.sol | getOperatorTokens(address token) | view | Returns the amount of Revenue Tokens held by Spigot that the Operator can withdraw. | ||||
Spigot.sol | isWhitelisted(bytes4 functionSignature) | view | Returns if the function has been whitelisted across Revenue Contracts for the Operator to call in operate() | ||||
Spigot.sol | getSetting(address revenueContract) | view | Returns the config for a Revenue Contract:
- uint8 ownerSplit - % of revenue that goes to Owner. 0 decimals
- bytes4 claimFunction - function selector on Revenue Contract to claim revenue
- bytes4 transferOwnerFunction - function selector on Revenue Contract to relinquish ownership from Spigot | ||||
Spigot.sol | owner() | view | Returns the address of the current Spigot Owner. | ||||
Spigot.sol | operator() | view | Returns the address of the current Spigot Operator. | ||||
Spigoted Line .sol | unused(address token) | view | Returns the amount of Credit Tokens that have been bought with Revenue Tokens from the Spigot and which haven't yet been withdrawn by a Lender or otherwise used by the Borrower to repay.
The system ensures that the first Credit Token in the repayment queue is the one being bought.
A Line can have multiple Credit Tokens being lent out and borrowed plus multiple Revenue Tokens being escrowed to repay the debt. This variable holds all of these excess tokens | ||||
Line Of Credit.sol | nextInQ() | view | - Retrieves the next id in FIFO Lender repayment queue.
- Returns null if no positions currently have debt (no reason to prioritize any Lender so no queue so no ānext in queueā)
- Returns the next position id in queue and the most up to date financial data on that position as of that block. | ||||
Line Of Credit.sol | interestAccrued(bytes32 id) | view | - interestAccrued stored in position data inside Line contract may not always be up to date since state only gets updated when a tx is sent. To view the actual must up to data interest owed on a position we add the existing interestAccrued and call the Lineās interest rate contract to calculate the remaining interest owed up until this block. | ||||
Line Of Credit.sol | counts() | view | - Returns tuple of current amount of open positions on Line vs total amount of elements in ids array (closed positions are deleted and become null array elements) | ||||
Spigot.sol | claimRevenue(address revenueContract, bytes calldata claimData) | ANYONE | Claims Revenue Tokens earned by one or more Revenue Contracts and updates amount claimable by Owner and Operator.
If push payments: When revenue is sent directly to the Spigot without us doing anything. We must calculate how many have been sent to us and disburse. (push payments = claimFunction == bytes4(0) )
if pull payments: When we must call the Revenue Contract to claim Revenue Tokens and then disburse the amount of tokens received from Revenue Contract. (pull payments = claimFunction == bytes4('0xrealfunc') ) | ||||
Spigoted Line .sol | updateOwnerSplit(address revenueContract) | ANYONE | Checks current status of Line and current owner split of Revenue Contract on Lineās Spigot. Based on status will update owner split if necessary.
if Line status is ACTIVE AND owner split isnt the Lineās defaultRevenueSplit then calls Spigot to update owner split to default split.
If Line is LIQUIDATABLE AND owner split isnt 100% then calls Spigot to update owner split to 100%.
After setting owner split to 100%, we wait until revenue repayments returns Line status back to ACTIVE where updateOwnerSplit can be called again to set owner split back to the default. | ||||
Line Of Credit.sol | init() | ANYONE | - Checks if all Line modules have been initialized properly. Namely checks that Spigot and Escrow contracts marked as collateral are actually owned by the line.
- All modules are required to pass back an OK signal. If, and only if, all modules pass the check then the Line sets its status to ACTIVE and lenders and borrowers can start transacting on the contract. | ||||
Line Of Credit.sol | accrueInterest() | ANYONE | - Accrues interest across all positions currently open on the Line and updates state. | - Borrower can repeatedly call to cause rounding down when calculating interest. According to our math, the gas costs of such an attack is mitigated due to pure gas price costs even for 1 position.
This attack vector becomes more expensive the more Lenders so most feasible when only 1 Lender. | |||
Line Of Credit.sol | healthcheck() | ANYONE | - Checks all covenants programmed into Line contract and returns the current health status of the Line.
- If borrower has broken covenants then status will be LIQUIDATABLE, otherwise it will usually be ACTIVE. | ||||
Line Of Credit.sol | depositAndRepay(uint256 amount) | ANYONEwhileBorrowing | - Takes funds from callers wallet to repay Borrowerās debt. MUST repay next position in payment queue.
- Can be called by anyone not just Borrower. | - ANYONE can repay so you might accidentally repay someone elseās debt | |||
Line Of Credit.sol | updateOutstandingDebt() | ANYONE | - Total debt owed by Borrower across all positions. Returns a tuple of (totalPrincipal, totalInterest).
- Denominated in USD and 8 decimals.
- Updates state with new interest accrued. | ||||
Line Factory.sol | deploySpigot(address owner, address borrower, address operator) | ANYONE | Deploys a new Spigot with provided config and starts tracking it in the Debt DAO subgraph. | ||||
Line Factory.sol | deployEscrow(uint32 minCRatio, address owner, address borrower) | ANYONE | Deploys a new Escrow with provided config and starts tracking it in the Debt DAO subgraph. | ||||
Line Factory.sol | deploySecuredLine(address borrower, uint256 TTL) | ANYONE | Deploys a new Line of Credit using the arbiter, oracle, defaultRevenueSplit , and minCRatio for this LineFactory and the provided borrower and term length. Starts tracking Line in the Debt DAO subgraph. | ||||
Line Factory.sol | deploySecuredLineWithConfig(CoreLineParams calldata coreParams) | ANYONE | Deploys a new Line of Credit using the arbiter, oracle for this LineFactory and the provided borrower, term length, defaultRevenueSplit , and minCRatio . Starts tracking Line in the Debt DAO subgraph. | misconfigured defaultRevenueSplit and minCRatio that is too high or low. These are immutable so cant be changed once contract is deployed. | |||
Line Factory.sol | deploySecuredLineWithModules(
CoreLineParams calldata coreParams,
address mSpigot,
address mEscrow
) | ANYONE | Deploys a new Line of Credit using existing Spigot and Escrow contracts that have already been configured. | misconfigured defaultRevenueSplit and minCRatio that is too high or low. These are immutable so cant be changed once contract is deployed. | |||
Line Factory.sol | rolloverSecuredLine(address oldLine, address borrower, uint256 TTL) | ANYONE | Takes debt terms for an existing Line of Credit, copies them and deploys a new Line of Credit for a new (or same) borrower and term length. After this call succeeds, Borrower can call rollover on their Line with their new Line address. | ||||
Line Of Credit.sol | addCredit(uint128 dRate, uint128 fRate, uint256 amount, address token, address lender) | mutualConsentonlyLenderOrBorrowerwhileActive | mutualConsent proposal functionality:
- Requires mutualConsent of Lineās Borrower and the Lender passed in as addCredit params.
- First call to addCredit executes mutualConsent and creates the onchain proposal, second call accepts the onchain proposal and executes addCredit function.
- Lender or Borrower can call in either order. Whoever calls first is proposing the terms to the other.
- Lender and Borrower can call addCredit multiple times with different params to create multiple proposals
- Proposal is not accepted until Borrower AND Lender both send the EXACT same proposal params.
addCredit functionality once proposal is accepted:
- Position data is initialized in contract state with agreed terms
- Lender must approve amount of token before call to accept proposal
- Tokens are transferred from Lenders address to Line contract
- Facility rate interest starts immediately accruing on full Lender deposit
- Borrow must call borrow() to get receive tokens. | - Could approve malicious token that can steal your funds (ass borrower or lender)
- Create proposal with wrong terms (e.g. interest rate = 0%) that counterparty immediately accepts to exploit your fat finger mistake.
- May add volatile token which could cause borrower to be liquidated while borrowing if price moves against them
- | |||
Line Of Credit.sol | increaseCredit(bytes32 id, uint256 amount) | mutualConsentonlyLenderOrBorrowerwhileActive | Must have gone through addCredit flow to create position with id already.
Allows Lineās Borrower and positionās Lender to agree to increase total amount of Credit Tokens available to Borrow on that position.
mutualConsent proposal functionality:
- First call to addCredit executes mutualConsent and creates the onchain proposal, second call accepts the onchain proposal and executes increaseCredit function.
- Proposal is not accepted until Borrower AND Lender both send the EXACT same proposal params.
addCredit functionality once proposal is accepted:
- position data is updated in state to increase deposit
- Lender must approve amount of token before call to accept proposal
- Tokens are transferred from Lenders address to Line contract | ||||
Line Of Credit.sol | setRates(bytes32 id, uint128 dRate, uint128 fRate) | mutualConsentonlyLenderOrBorrower | Allows Borrower and Lender to agree to change the drawn rate and/or facility rate on an existing position. | ||||
Line Of Credit.sol | mutualConsent(address signerOne, address signerTwo) | mutualConsent | Internal util function that allows for arbitrary 2/2 multisigs with dynamic participants on any function in our contract. Requires 2 different addresses to be signers and the exact same msg.data when calling the mutualConsent modified function.
This function is the basis for allowing borrower to have agreements with multiple lenders at the same time. | ||||
Line Of Credit.sol | borrow(bytes32 id, uint256 amount) | onlyBorrowerwhileActive | Must have gone through addCredit flow to create position with id already.
Allows Lineās Borrower to withdraw funds from specified position.
Borrower starts paying drawn rate and/or facility rate based on position balance.
Position gets sorted into FIFO repayment queue if not already in queue. | ||||
Line Of Credit.sol | depositAndClose() | onlyBorrowerwhileBorrowing | Takes funds from Borrowerās wallet to fully repay all outstanding debt and interest on position and then closes position permanently. MUST repay and close next position in payment queue | ||||
Line Of Credit.sol | close(bytes32 id) | onlyBorrower | Allows Borrower to close any position with no outsanding debt. Takes funds from Borrowerās wallet to repay accrued facility fee and then closes position permanently. | ||||
Secured Line.sol | rollover(address newLine) | onlyBorrower | Helper function to allow Borrower to easily transfer settings and collateral from this line to a new line. Useful after ttl has expired and want to renew Line with minimal effort. Transfers Spigot and Escrow ownership to newLine. Arbiter functions on this Line will no longer work. The new, uninitialized Line deployed by borrower | ||||
Spigoted Line .sol | claimAndRepay() | onlyArbiter | Claims Revenue Tokens from the Spigot as Owner, trades them for Credit Tokens via a DEX and repays debt on next Lender in repayment queue.
Stores any bought Credit Tokens in excess of debt obligation + any leftover Revenue Tokens from trade into the Lineās unusedToken to use in useAndRepay for self-service repayments by Borrowers and Lenders or later trades. | ||||
Spigoted Line .sol | claimAndTrade() | onlyArbiter | Claims Revenue Tokens from the Spigot as Owner, trades them for Credit Tokens via a DEX and immediately stores any bought Credit Tokens + any leftover Revenue Tokens from trade into the Lineās unusedToken to use in useAndRepay for self-service repayments by Borrowers and Lenders or later trades. | ||||
Spigoted Line .sol | enableSpigot(address revenueContract, ISpigotSettings calldata settings) | onlyArbiter | Calls addSpigot on Lineās Spigot to add Revenue Contract config. addSpigot call has to come from Lineās address because it is the owner of the Spigot. | Could add a malicious Revenue Contract and/or config that causes funds to be stolen from Spigot. | |||
Spigoted Line .sol | updateWhitelist(address revenueContract, bytes4 operatorFunc) | onlyArbiter | Sets or updates the whitelisted functions that a Borrower (or whoever is Spigotās Operator) can call on Revenue Contracts so they continue generating revenue while they are collateralized in the Spigot to repay debt. Only callable by an Arbiter. | ||||
Secured Line.sol | liquidate() | onlyArbiter | Forcefully take collateral from Escrow and repay debt for lender. The current implementation just sends "liquidated" tokens to Arbiter to sell off how the deem fit and then manually repay with DepositAndRepay. | ||||
Spigoted Line .sol | addSpigot(address revenueContract, ISpigot.Setting calldata setting) | onlyArbiter | Enables automatic repayment of the loan by diverting revenue from the Borrowerās revenue generating contract/s. | Risk is that you add you revenue contract with incorrect claim transfer ownership selectors making it impossible to claim revenue | |||
Line Of Credit.sol | declareInsolvent() | onlyArbiter | If the borrower is incapable of repaying the loan, there needs to be an attempt to make the lender whole | ||||
Escrow.sol | enableCollateral(address token) | onlyArbiter | Called before a borrower can deposit a token as collateral | ||||
Spigot.sol | addSpigot(address revenueContract, SpigotSettings memory setting) | onlyOwner | Attach a new Revenue Contract to a Spigot. MUST include revenue split + valid transferOwner and claimRevenue functions
SpigotSettings:
- uint8 ownerSplit - % of revenue that goes to Owner. 0 decimals
- bytes4 claimFunction - function selector on Revenue Contract to claim revenue
- bytes4 transferOwnerFunction - function selector on Revenue Contract to relinquish ownership from Spigot | Could add a malicious Revenue Contract and/or config that causes funds to be stolen from Spigot. | |||
Spigot.sol | updateWhitelistedFunction(bytes4 func, bool isAllowed) | onlyOwner | Allows the Owner to update Spigot whitelist of functions Operator can call on Revenue Contracts. This allows Operator to perform managerial tasks on its Revenue Contracts so they continue generating revenue while they are collateralized in the Spigot to repay debt. | Could add a malicious function on Revenue Contract that causes funds to be stolen from Spigot. | |||
Spigot.sol | claimOwnerTokens(address token, uint256 amount) | onlyOwner | Owner withdraws their share of Revenue Tokens that have already been claimed via claimRevenue() | ||||
Spigot.sol | updateOwnerSplit(address revenueContract, uint8 split) | onlyOwner | Changes the revenue split between the Operator and the Owner based upon programmed conditions or otherwise if the Owner and Operator wish to change the split. | ||||
Spigot.sol | updateOwner(address newOwner) | onlyOwner | Puts a new Owner in control the Spigot.
| ||||
Spigot.sol | removeSpigot(address revenueContract) | onlyOwner | - Calls transferOwnerFunction on Revneu Contract settings and transfers ownership to Operator. | ||||
Spigot.sol | claimOperatorTokens(address token, uint256 amount) | onlyOperator | - Operator withdraws their share of Revenue Tokens that have already been claimed via claimRevenue() | ||||
Spigot.sol | operate(address revenueContract, bytes calldata msgData) | onlyOperator | - Allows an Operator to call the whitelisted functions on its Revenue Contracts attached to the Spigot and carry on its business as usual activities. | ||||
Spigot.sol | updateOperator(address newOperator) | onlyOperator | - Puts a new Operator address in place to interact with the Revenue Contracts if ever this were needed. | ||||
Line Of Credit.sol | revokeConsent(bytes calldata proposalData) | onlyLenderOrBorrower | If either a Borrower or Lender to create a proposed position (or update an existing position) and then changes their mind (e.g. params are wrong / unfavorable) they can revoke their proposal. This means the other party cannot complete the other half of mutualConsent() to create/update the position. This works on only one (1) proposal at a time, if you have made multiple proposals with different terms, you must manually revoke each proposal.
proposalData param is the original msg.data when registering your consent. Must be reconstructed from original data stored offchain and passed in as the ABI encoded function selector + function arguments from addCredit , increaseCredit , or setRates or any other mutualConsent function. This data is used along with the senders address to regenerate the actual proposal ID hash that is then removed from the mutualConsents[] mapping. msg.data is . | ||||
Spigoted Line .sol | useAndRepay(address token, uint256 amount) | onlyLenderOrBorrowerwhileBorrowing | Allows the Borrower or next Lender in repayment queue to use Credit Tokens stored in Lineās unusedTokens to repay debt. Credit Tokens must have already been claimed/traded in claimAndTrade or claimAndRepay and put in unusedTokens for this call to succeed. | ||||
Spigoted Line .sol | releaseSpigot() | onlyArbiterOrBorrower | Transfers ownership of the entire Spigot from the Line of Credit to either the Borrower (if a Line of Credit has been been fully repaid) or to the Arbiter (if the Line of Credit is liquidatable). | ||||
Spigoted Line .sol | sweep() | onlyArbiterOrBorrower | After a loan has been repaid, sends any remaining Revenue Tokens or Credit Tokens from a Spigot to the Borrower.
In case of a Borrower default however (loan status = liquidatable), this function serves as a liquidation mechanism that is called in an effort to increase the Lenders' recovery rate and reduce the "loss given default (LGD)ā | ||||
Line Of Credit.sol | withdraw(bytes32 id, uint256 amount) | onlyLender | |||||
#
[](https://www.notion.so/71b1953b5f044fb08c26fb9505b29424)
[](https://www.notion.so/365b30675e2f451b822c1c12927753e3)
[](https://www.notion.so/4a4f648af0df4630889448f882b9011b)
[](https://www.notion.so/9f2b1ee0932543438b119bbb7df66db4)
[](https://www.notion.so/c59cb5a1b1e64811b457ed570d4e01ae)
[](https://www.notion.so/58338bf5a88b473b851e597c43abb32a)
[](https://www.notion.so/13003a53fb504ebcbb8e959306054cb7)
[](https://www.notion.so/cdc95a983cbc49a683f9bfb5b9774d63)
[](https://www.notion.so/0d3518395bfb4571baf87087eb2d88dc)
[](https://www.notion.so/5798f6f5893d422a9bbe6e5f33408029) | |||||||
Interfaces
Most up to date on Github:
LineFactory
interface ILineFactory {
struct CoreLineParams {
address borrower;
uint256 ttl;
uint32 cratio;
uint8 revenueSplit;
}
event DeployedSecuredLine(
address indexed deployedAt,
address indexed escrow,
address indexed spigot,
address swapTarget,
uint8 revenueSplit
);
error ModuleTransferFailed(address line, address spigot, address escrow);
error InvalidRevenueSplit();
error InvalidOracleAddress();
error InvalidSwapTargetAddress();
error InvalidArbiterAddress();
error InvalidEscrowAddress();
error InvalidSpigotAddress();
function deployEscrow(
uint32 minCRatio,
address owner,
address borrower
) external returns (address);
function deploySpigot(
address owner,
address borrower,
address operator
) external returns (address);
function deploySecuredLine(address borrower, uint256 ttl)
external
returns (address);
function deploySecuredLineWithConfig(CoreLineParams calldata coreParams)
external
returns (address);
function deploySecuredLineWithModules(
CoreLineParams calldata coreParams,
address mSpigot,
address mEscrow
) external returns (address);
function rolloverSecuredLine(
address payable oldLine,
address borrower,
uint256 ttl
) external returns (address);
}
SecuredLine
interface ISecuredLine {
// Start ILineOfCredit inheritance
// Lender data
struct Credit {
// all denominated in token, not USD
uint256 deposit; // The total liquidity provided by a Lender in a given token on a Line of Credit
uint256 principal; // The amount of a Lender's Deposit on a Line of Credit that has actually been drawn down by the Borrower (in Tokens)
uint256 interestAccrued; // Interest due by a Borrower but not yet repaid to the Line of Credit contract
uint256 interestRepaid; // Interest repaid by a Borrower to the Line of Credit contract but not yet withdrawn by a Lender
uint8 decimals; // Decimals of Credit Token for calcs
address token; // The token being lent out (Credit Token)
address lender; // The person to repay
bool isOpen; // Status of position
}
// General Events
event UpdateStatus(uint256 indexed status); // store as normal uint so it can be indexed in subgraph
event DeployLine(address indexed oracle, address indexed arbiter, address indexed borrower);
event SortedIntoQ(bytes32 indexed id, uint256 indexed newIdx, uint256 indexed oldIdx, bytes32 oldId);
// MutualConsent borrower/lender events
event AddCredit(address indexed lender, address indexed token, uint256 indexed deposit, bytes32 id);
// can only reference id once AddCredit is emitted because it will be indexed offchain
event SetRates(bytes32 indexed id, uint128 indexed dRate, uint128 indexed fRate);
event IncreaseCredit(bytes32 indexed id, uint256 indexed deposit);
// Lender Events
// Emits data re Lender removes funds (principal) - there is no corresponding function, just withdraw()
event WithdrawDeposit(bytes32 indexed id, uint256 indexed amount);
// Emits data re Lender withdraws interest - there is no corresponding function, just withdraw()
event WithdrawProfit(bytes32 indexed id, uint256 indexed amount);
// Emitted when any credit line is closed by the line's borrower or the position's lender
event CloseCreditPosition(bytes32 indexed id);
// After accrueInterest runs, emits the amount of interest added to a Borrower's outstanding balance of interest due
// but not yet repaid to the Line of Credit contract
event InterestAccrued(bytes32 indexed id, uint256 indexed amount);
// Borrower Events
// receive full line or drawdown on credit
event Borrow(bytes32 indexed id, uint256 indexed amount);
// Emits that a Borrower has repaid an amount of interest Results in an increase in interestRepaid, i.e. interest not yet withdrawn by a Lender). There is no corresponding function
event RepayInterest(bytes32 indexed id, uint256 indexed amount);
// Emits that a Borrower has repaid an amount of principal - there is no corresponding function
event RepayPrincipal(bytes32 indexed id, uint256 indexed amount);
event Default(bytes32 indexed id);
// Access Errors
error NotActive();
error NotBorrowing();
error CallerAccessDenied();
// Tokens
error TokenTransferFailed();
error NoTokenPrice();
// Line
error BadModule(address module);
error NoLiquidity();
error PositionExists();
error CloseFailedWithPrincipal();
error NotInsolvent(address module);
error NotLiquidatable();
error AlreadyInitialized();
error PositionIsClosed();
error RepayAmountExceedsDebt(uint256 totalAvailable);
error CantStepQ();
error EthSupportDisabled();
error BorrowFailed();
// Fully public functions
function init() external returns (LineLib.STATUS);
// MutualConsent functions
/**
* @notice - On first call, creates proposed terms and emits MutualConsentRegistsered event. No position is created.
- On second call, creates position and stores in Line contract, sets interest rates, and starts accruing facility rate fees.
* @dev - Requires mutualConsent participants send EXACT same params when calling addCredit
* @dev - Fully executes function after a Borrower and a Lender have agreed terms, both Lender and borrower have agreed through mutualConsent
* @dev - callable by `lender` and `borrower`
* @param drate - The interest rate charged to a Borrower on borrowed / drawn down funds. In bps, 4 decimals.
* @param frate - The interest rate charged to a Borrower on the remaining funds available, but not yet drawn down
(rate charged on the available headroom). In bps, 4 decimals.
* @param amount - The amount of Credit Token to initially deposit by the Lender
* @param token - The Credit Token, i.e. the token to be lent out
* @param lender - The address that will manage credit line
* @return id - Lender's position id to look up in `credits`
*/
function addCredit(
uint128 drate,
uint128 frate,
uint256 amount,
address token,
address lender
) external payable returns (bytes32);
/**
* @notice - lets Lender and Borrower update rates on the lender's position
* - accrues interest before updating terms, per InterestRate docs
* - can do so even when LIQUIDATABLE for the purpose of refinancing and/or renego
* @dev - callable by Borrower or Lender
* @param id - position id that we are updating
* @param drate - new drawn rate. In bps, 4 decimals
* @param frate - new facility rate. In bps, 4 decimals
* @return - if function executed successfully
*/
function setRates(bytes32 id, uint128 drate, uint128 frate) external returns (bool);
/**
* @notice - Lets a Lender and a Borrower increase the credit limit on a position
* @dev - line status must be ACTIVE
* @dev - callable by borrower
* @dev - The function retains the `payable` designation, despite not accepting Eth via mutualConsent modifier, as a gas-optimization
* @param id - position id that we are updating
* @param amount - amount to deposit by the Lender
* @return - if function executed successfully
*/
function increaseCredit(bytes32 id, uint256 amount) external payable returns (bool);
// Borrower functions
/**
* @notice - Borrower chooses which lender position draw down on and transfers tokens from Line contract to Borrower
* @dev - callable by borrower
* @param id - the position to draw down on
* @param amount - amount of tokens the borrower wants to withdraw
* @return - if function executed successfully
*/
function borrow(bytes32 id, uint256 amount) external returns (bool);
/**
* @notice - Transfers token used in position id from msg.sender to Line contract.
* @dev - Available for anyone to deposit Credit Tokens to be available to be withdrawn by Lenders
* @dev - The function retains the `payable` designation, despite reverting with a non-zero msg.value, as a gas-optimization
* @notice - see LineOfCredit._repay() for more details
* @param amount - amount of `token` in `id` to pay back
* @return - if function executed successfully
*/
function depositAndRepay(uint256 amount) external payable returns (bool);
/**
* @notice - A Borrower deposits enough tokens to repay and close a credit line.
* @dev - callable by borrower
* @dev - The function retains the `payable` designation, despite reverting with a non-zero msg.value, as a gas-optimization
* @return - if function executed successfully
*/
function depositAndClose() external payable returns (bool);
/**
* @notice - Removes and deletes a position, preventing any more borrowing or interest.
* - Requires that the position principal has already been repais in full
* @dev - MUST repay accrued interest from facility fee during call
* @dev - callable by `borrower` or Lender
* @dev - The function retains the `payable` designation, despite reverting with a non-zero msg.value, as a gas-optimization
* @param id -the position id to be closed
* @return - if function executed successfully
*/
function close(bytes32 id) external payable returns (bool);
// Lender functions
/**
* @notice - Withdraws liquidity from a Lender's position available to the Borrower.
* - Lender is only allowed to withdraw tokens not already lent out
* - Withdraws from repaid interest (profit) first and then deposit is reduced
* @dev - can only withdraw tokens from their own position. If multiple lenders lend DAI, the lender1 can't withdraw using lender2's tokens
* @dev - callable by Lender on `id`
* @param id - the position id that Lender is withdrawing from
* @param amount - amount of tokens the Lender would like to withdraw (withdrawn amount may be lower)
* @return - if function executed successfully
*/
function withdraw(bytes32 id, uint256 amount) external returns (bool);
// Arbiter functions
/**
* @notice - Allow the Arbiter to signify that the Borrower is incapable of repaying debt permanently.
* - Recoverable funds for Lender after declaring insolvency = deposit + interestRepaid - principal
* @dev - Needed for onchain impairment accounting e.g. updating ERC4626 share price
* - MUST NOT have collateral left for call to succeed. Any collateral must already have been liquidated.
* @dev - Callable only by Arbiter.
* @return bool - If Borrower has been declared insolvent or not
*/
function declareInsolvent() external returns (bool);
/**
*
* @notice - Updates accrued interest for the whole Line of Credit facility (i.e. for all credit lines)
* @dev - Loops over all position ids and calls related internal functions during which InterestRateCredit.sol
* is called with the id data and then 'interestAccrued' is updated.
* @dev - The related internal function _accrue() is called by other functions any time the balance on an individual
* credit line changes or if the interest rates of a credit line are changed by mutual consent
* between a Borrower and a Lender.
* @return - if function executed successfully
*/
function accrueInterest() external returns (bool);
function healthcheck() external returns (LineLib.STATUS);
/**
* @notice - Cycles through position ids andselects first position with non-null principal to the zero index
* @dev - Only works if the first element in the queue is null
* @return bool - if call suceeded or not
*/
function stepQ() external returns (bool);
/**
* @notice - Returns the total debt of a Borrower across all positions for all Lenders.
* @dev - Denominated in USD, 8 decimals.
* @dev - callable by anyone
* @return totalPrincipal - total amount of principal, in USD, owed across all positions
* @return totalInterest - total amount of interest, in USD, owed across all positions
*/
function updateOutstandingDebt() external returns (uint256, uint256);
// State getters
function status() external returns (LineLib.STATUS);
function borrower() external returns (address);
function arbiter() external returns (address);
function oracle() external returns (IOracle);
/**
* @notice - getter for amount of active ids + total ids in list
* @return - (uint256, uint256) - active credit lines, total length
*/
function counts() external view returns (uint256, uint256);
/**
* @notice - getter for amount of active ids + total ids in list
* @return - (uint256, uint256) - active credit lines, total length
*/
function interestAccrued(bytes32 id) external returns (uint256);
/**
* @notice - info on the next lender position that must be repaid
* @return - (bytes32, address, address, uint, uint) - id, lender, token, principal, interestAccrued
*/
function nextInQ() external returns (bytes32, address, address, uint256, uint256);
/**
* @notice - how many tokens can be withdrawn from positions by borrower or lender
* @return - (uint256, uint256) - remaining deposit, claimable interest
*/
function available(bytes32 id) external returns (uint256, uint256);
// End ILineOfCredit inheritance
// Start ISpigotedLine inheritance
/**
* @notice - Log how many revenue tokens are used to repay debt after claimAndRepay
* - dont need to track value like other events because _repay already emits that
* - Mainly used to log debt that is paid via Spigot directly vs other sources. Without this event it's a lot harder to parse that offchain.
*/
event RevenuePayment(address indexed token, uint256 indexed amount);
error ReservesOverdrawn(address token, uint256 amountAvailable);
/**
* @notice - Log how many revenue tokens were traded for credit tokens.
* - Differs from RevenuePayment because we trade revenue at different times from repaying with revenue
* @dev - Can you use to figure out price of revenue tokens offchain since we only have an oracle for credit tokens
* @dev - Revenue tokens may be from reserves or from Spigot revenue.
*/
event TradeSpigotRevenue(
address indexed revenueToken,
uint256 revenueTokenAmount,
address indexed debtToken,
uint256 indexed debtTokensBought
);
event ReservesChanged (
address indexed token,
int256 indexed diff,
uint256 tokenType // 0 for revenue token, 1 for credit token
);
// Borrower functions
/**
* @notice - Directly repays a Lender using unused tokens already held by Line with no trading
* @dev - callable by `borrower` or first lender in repayment queue
* @param amount - amount of unused tokens to use to repay Lender
* @return - if function executed successfully
*/
function useAndRepay(uint256 amount) external returns (bool);
/**
* @notice - Claims revenue tokens from the Spigot, trades them for credit tokens via a Dex aggregator (Ox protocol) and uses the bought credit tokens to repay debt.
* - see SpigotedLine._claimAndTrade and SpigotedLineLib.claimAndTrade for more details on Spigot and trading logic
* - see LineOfCredit._repay() for more details on repayment logic
* @dev - does not trade asset if claimToken = credit.token
* @dev - callable by `arbiter`
* @param claimToken - The Revenue Token escrowed by Spigot to claim and use to repay debt
* @param zeroExTradeData - data generated by the 0x dex API to trade `claimToken` against their exchange contract
* @return newTokens - amount of credit tokens claimed or bought during call
*/
function claimAndRepay(address claimToken, bytes calldata zeroExTradeData) external returns (uint256);
/**
*
* @notice - allows borrower to trade revenue to credit tokens at a favorable price without repaying debt
* - sends all bought tokens to `unused` to be repaid later
* - see SpigotedLine._claimAndTrade and SpigotedLineLib.claimAndTrade for more details
* @dev - ensures first token in repayment queue is being bought
* @dev - callable by `arbiter`
* @param claimToken - The revenue token escrowed in the Spigot to sell in trade
* @param zeroExTradeData - 0x API data to use in trade to sell `claimToken` for `credits[ids[0]]`
* @return tokensBought - amount of credit tokens bought
*/
function claimAndTrade(address claimToken, bytes calldata zeroExTradeData) external returns (uint256 tokensBought);
// Spigot management functions
/**
* @notice - allow Line (aka Owner on Spigot) to add new revenue streams to repay credit
* @dev - see Spigot.addSpigot()
* @dev - callable `arbiter` ONLY
* @return - if function call was successful
*/
function addSpigot(address revenueContract, ISpigot.Setting calldata setting) external returns (bool);
/**
* @notice - Sets or resets the whitelisted functions that a Borrower [Operator] is allowed to perform on the revenue generating contracts
* @dev - see Spigot.updateWhitelistedFunction()
* @dev - callable `arbiter` ONLY
* @return - if function call was successful
*/
function updateWhitelist(bytes4 func, bool allowed) external returns (bool);
/**
* @notice - Changes the revenue split between the Treasury and the Line (Owner) based upon the status of the Line of Credit
* @dev - callable `arbiter` + `borrower`
* @param revenueContract - spigot to update
* @return didUpdate - whether or not split was updated
*/
function updateOwnerSplit(address revenueContract) external returns (bool);
/**
* @notice - Transfers ownership of the entire Spigot from its then Owner to either the Borrower (if a Line of Credit has been been fully repaid)
* - or to the Arbiter (if the Line of Credit is liquidatable).
* @dev - callable by borrower + arbiter
* @param to - address that caller wants to transfer Spigot ownership to
* @return bool - whether or not a Spigot was released
*/
function releaseSpigot(address to) external returns (bool);
/**
* @notice - sends unused tokens to borrower if REPAID or arbiter if LIQUIDATABLE or INSOLVENT
* - does not send tokens out if line is ACTIVE
* @dev - callable by `borrower` or `arbiter`
* @param to - address to send swept tokens to
* @param token - revenue or credit token to sweep
* @param amount - amount of reserve tokens to withdraw/liquidate
*/
function sweep(address to, address token, uint256 amount) external returns (uint256);
// getters
/**
* @notice - getter for `unusedTokens` mapping which is a private var
* @param token - address for an ERC20
* @return amount - amount of revenue tokens available to trade for credit tokens or credit tokens availble to repay debt with
*/
function unused(address token) external returns (uint256);
/**
* @notice - Looksup `unusedTokens` + spigot.getOwnerTokens` for how many tokens arbiter must sell in claimAndTrade/Repay
* @param token - address for an ERC20 earned as revenue
* @return amount - amount of unused + claimable revenue tokens available to trade for credit tokens or credit tokens availble to repay debt with
*/
function tradeable(address token) external returns (uint256);
function spigot() external returns (ISpigot);
// End ISpigotedLine inheritance
// Start ISecuredLine proper
// Rollover Errors
error DebtOwed();
error BadNewLine();
error BadRollover();
// Borrower functions
/**
* @notice - helper function to allow Borrower to easily transfer settings and collateral from this line to a new line
* - usefull after ttl has expired and want to renew Line with minimal effort
* @dev - transfers Spigot and Escrow ownership to newLine. Arbiter functions on this Line will no longer work
* @param newLine - the new, uninitialized Line deployed by borrower
* @return success - if
*/
function rollover(address newLine) external returns(bool);
// End ISecuredLine proper
}
Spigot
interface ISpigot {
struct Setting {
uint8 ownerSplit; // x/100 % to Owner, rest to Operator
bytes4 claimFunction; // function signature on contract to call and claim revenue
bytes4 transferOwnerFunction; // function signature on contract to call and transfer ownership
}
// Spigot Events
event AddSpigot(address indexed revenueContract, uint256 ownerSplit, bytes4 claimFnSig, bytes4 trsfrFnSig);
event RemoveSpigot(address indexed revenueContract, address token);
event UpdateWhitelistFunction(bytes4 indexed func, bool indexed allowed);
event UpdateOwnerSplit(address indexed revenueContract, uint8 indexed split);
event ClaimRevenue(address indexed token, uint256 indexed amount, uint256 escrowed, address revenueContract);
event ClaimOwnerTokens(address indexed token, uint256 indexed amount, address owner);
event ClaimOperatorTokens(address indexed token, uint256 indexed amount, address operator);
// Stakeholder Events
event UpdateOwner(address indexed newOwner);
event UpdateOperator(address indexed newOperator);
// Errors
error BadFunction();
error OperatorFnNotWhitelisted();
error OperatorFnNotValid();
error OperatorFnCallFailed();
error ClaimFailed();
error NoRevenue();
error UnclaimedRevenue();
error CallerAccessDenied();
error BadSetting();
error InvalidRevenueContract();
// ops funcs
function claimRevenue(
address revenueContract,
address token,
bytes calldata data
) external returns (uint256 claimed);
function operate(address revenueContract, bytes calldata data) external returns (bool);
// owner funcs
function claimOwnerTokens(address token) external returns (uint256 claimed);
function claimOperatorTokens(address token) external returns (uint256 claimed);
function addSpigot(address revenueContract, Setting memory setting) external returns (bool);
function removeSpigot(address revenueContract) external returns (bool);
// stakeholder funcs
function updateOwnerSplit(address revenueContract, uint8 ownerSplit) external returns (bool);
function updateOwner(address newOwner) external returns (bool);
function updateOperator(address newOperator) external returns (bool);
function updateWhitelistedFunction(bytes4 func, bool allowed) external returns (bool);
// Getters
function owner() external view returns (address);
function operator() external view returns (address);
function isWhitelisted(bytes4 func) external view returns (bool);
function getOwnerTokens(address token) external view returns (uint256);
function getOperatorTokens(address token) external view returns (uint256);
function getSetting(
address revenueContract
) external view returns (uint8 split, bytes4 claimFunc, bytes4 transferFunc);
}
Escrow
interface IEscrow {
struct Deposit {
uint amount;
bool isERC4626;
address asset; // eip4626 asset else the erc20 token itself
uint8 assetDecimals;
}
event AddCollateral(address indexed token, uint indexed amount);
event RemoveCollateral(address indexed token, uint indexed amount);
event EnableCollateral(address indexed token);
error InvalidCollateral();
error CallerAccessDenied();
error UnderCollateralized();
error NotLiquidatable();
// State var getters.
function line() external returns (address);
function oracle() external returns (address);
function borrower() external returns (address);
function minimumCollateralRatio() external returns (uint32);
// Functions
function isLiquidatable() external returns (bool);
function updateLine(address line_) external returns (bool);
function getCollateralRatio() external returns (uint);
function getCollateralValue() external returns (uint);
function enableCollateral(address token) external returns (bool);
function addCollateral(uint amount, address token) external payable returns (uint);
function releaseCollateral(uint amount, address token, address to) external returns (uint);
function liquidate(uint amount, address token, address to) external returns (bool);
}
ABIs
Most up to date on Github:
LineFactory
[
{
"inputs": [
{
"internalType": "address",
"name": "moduleFactory",
"type": "address"
},
{
"internalType": "address",
"name": "arbiter_",
"type": "address"
},
{
"internalType": "address",
"name": "oracle_",
"type": "address"
},
{
"internalType": "address payable",
"name": "swapTarget_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "InvalidArbiterAddress",
"type": "error"
},
{
"inputs": [],
"name": "InvalidEscrowAddress",
"type": "error"
},
{
"inputs": [],
"name": "InvalidOracleAddress",
"type": "error"
},
{
"inputs": [],
"name": "InvalidRevenueSplit",
"type": "error"
},
{
"inputs": [],
"name": "InvalidSpigotAddress",
"type": "error"
},
{
"inputs": [],
"name": "InvalidSwapTargetAddress",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "line",
"type": "address"
},
{
"internalType": "address",
"name": "spigot",
"type": "address"
},
{
"internalType": "address",
"name": "escrow",
"type": "address"
}
],
"name": "ModuleTransferFailed",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "deployedAt",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "escrow",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spigot",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "swapTarget",
"type": "address"
},
{
"indexed": false,
"internalType": "uint8",
"name": "revenueSplit",
"type": "uint8"
}
],
"name": "DeployedSecuredLine",
"type": "event"
},
{
"inputs": [],
"name": "arbiter",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "minCRatio",
"type": "uint32"
},
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "borrower",
"type": "address"
}
],
"name": "deployEscrow",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "borrower",
"type": "address"
},
{
"internalType": "uint256",
"name": "ttl",
"type": "uint256"
}
],
"name": "deploySecuredLine",
"outputs": [
{
"internalType": "address",
"name": "line",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "borrower",
"type": "address"
},
{
"internalType": "uint256",
"name": "ttl",
"type": "uint256"
},
{
"internalType": "uint32",
"name": "cratio",
"type": "uint32"
},
{
"internalType": "uint8",
"name": "revenueSplit",
"type": "uint8"
}
],
"internalType": "struct ILineFactory.CoreLineParams",
"name": "coreParams",
"type": "tuple"
}
],
"name": "deploySecuredLineWithConfig",
"outputs": [
{
"internalType": "address",
"name": "line",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "borrower",
"type": "address"
},
{
"internalType": "uint256",
"name": "ttl",
"type": "uint256"
},
{
"internalType": "uint32",
"name": "cratio",
"type": "uint32"
},
{
"internalType": "uint8",
"name": "revenueSplit",
"type": "uint8"
}
],
"internalType": "struct ILineFactory.CoreLineParams",
"name": "coreParams",
"type": "tuple"
},
{
"internalType": "address",
"name": "mSpigot",
"type": "address"
},
{
"internalType": "address",
"name": "mEscrow",
"type": "address"
}
],
"name": "deploySecuredLineWithModules",
"outputs": [
{
"internalType": "address",
"name": "line",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "operator",
"type": "address"
}
],
"name": "deploySpigot",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "oracle",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "oldLine",
"type": "address"
},
{
"internalType": "address",
"name": "borrower",
"type": "address"
},
{
"internalType": "uint256",
"name": "ttl",
"type": "uint256"
}
],
"name": "rolloverSecuredLine",
"outputs": [
{
"internalType": "address",
"name": "line",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "swapTarget",
"outputs": [
{
"internalType": "address payable",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
]
SecuredLine
[
{
"inputs": [
{
"internalType": "address",
"name": "oracle_",
"type": "address"
},
{
"internalType": "address",
"name": "arbiter_",
"type": "address"
},
{
"internalType": "address",
"name": "borrower_",
"type": "address"
},
{
"internalType": "address payable",
"name": "swapTarget_",
"type": "address"
},
{
"internalType": "address",
"name": "spigot_",
"type": "address"
},
{
"internalType": "address",
"name": "escrow_",
"type": "address"
},
{
"internalType": "uint256",
"name": "ttl_",
"type": "uint256"
},
{
"internalType": "uint8",
"name": "defaultSplit_",
"type": "uint8"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "AlreadyInitialized",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "module",
"type": "address"
}
],
"name": "BadModule",
"type": "error"
},
{
"inputs": [],
"name": "BadNewLine",
"type": "error"
},
{
"inputs": [],
"name": "BadRollover",
"type": "error"
},
{
"inputs": [],
"name": "BorrowFailed",
"type": "error"
},
{
"inputs": [],
"name": "CallerAccessDenied",
"type": "error"
},
{
"inputs": [],
"name": "CantStepQ",
"type": "error"
},
{
"inputs": [],
"name": "CloseFailedWithPrincipal",
"type": "error"
},
{
"inputs": [],
"name": "DebtOwed",
"type": "error"
},
{
"inputs": [],
"name": "EthSupportDisabled",
"type": "error"
},
{
"inputs": [],
"name": "InvalidConsent",
"type": "error"
},
{
"inputs": [],
"name": "NoLiquidity",
"type": "error"
},
{
"inputs": [],
"name": "NoTokenPrice",
"type": "error"
},
{
"inputs": [],
"name": "NonZeroEthValue",
"type": "error"
},
{
"inputs": [],
"name": "NotActive",
"type": "error"
},
{
"inputs": [],
"name": "NotBorrowing",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "module",
"type": "address"
}
],
"name": "NotInsolvent",
"type": "error"
},
{
"inputs": [],
"name": "NotLiquidatable",
"type": "error"
},
{
"inputs": [],
"name": "NotUserConsent",
"type": "error"
},
{
"inputs": [],
"name": "PositionExists",
"type": "error"
},
{
"inputs": [],
"name": "PositionIsClosed",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "totalAvailable",
"type": "uint256"
}
],
"name": "RepayAmountExceedsDebt",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint256",
"name": "amountAvailable",
"type": "uint256"
}
],
"name": "ReservesOverdrawn",
"type": "error"
},
{
"inputs": [],
"name": "TokenTransferFailed",
"type": "error"
},
{
"inputs": [],
"name": "Unauthorized",
"type": "error"
},
{
"inputs": [],
"name": "UnsupportedMutualConsentFunction",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "lender",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "deposit",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
}
],
"name": "AddCredit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "Borrow",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
}
],
"name": "CloseCreditPosition",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
}
],
"name": "Default",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "oracle",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "arbiter",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "borrower",
"type": "address"
}
],
"name": "DeployLine",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "uint256",
"name": "deposit",
"type": "uint256"
}
],
"name": "IncreaseCredit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "InterestAccrued",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "escrow",
"type": "address"
}
],
"name": "Liquidate",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes32",
"name": "proposalId",
"type": "bytes32"
}
],
"name": "MutualConsentAccepted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes32",
"name": "proposalId",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "address",
"name": "taker",
"type": "address"
}
],
"name": "MutualConsentRegistered",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes32",
"name": "proposalId",
"type": "bytes32"
}
],
"name": "MutualConsentRevoked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "RepayInterest",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "RepayPrincipal",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "int256",
"name": "diff",
"type": "int256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenType",
"type": "uint256"
}
],
"name": "ReservesChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "RevenuePayment",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "uint128",
"name": "dRate",
"type": "uint128"
},
{
"indexed": true,
"internalType": "uint128",
"name": "fRate",
"type": "uint128"
}
],
"name": "SetRates",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "uint256",
"name": "newIdx",
"type": "uint256"
},
{
"indexed": true,
"internalType": "uint256",
"name": "oldIdx",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "oldId",
"type": "bytes32"
}
],
"name": "SortedIntoQ",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "revenueToken",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "revenueTokenAmount",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "debtToken",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "debtTokensBought",
"type": "uint256"
}
],
"name": "TradeSpigotRevenue",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "status",
"type": "uint256"
}
],
"name": "UpdateStatus",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "WithdrawDeposit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "WithdrawProfit",
"type": "event"
},
{
"inputs": [],
"name": "accrueInterest",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint128",
"name": "drate",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "frate",
"type": "uint128"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "address",
"name": "lender",
"type": "address"
}
],
"name": "addCredit",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "revenueContract",
"type": "address"
},
{
"components": [
{
"internalType": "uint8",
"name": "ownerSplit",
"type": "uint8"
},
{
"internalType": "bytes4",
"name": "claimFunction",
"type": "bytes4"
},
{
"internalType": "bytes4",
"name": "transferOwnerFunction",
"type": "bytes4"
}
],
"internalType": "struct ISpigot.Setting",
"name": "setting",
"type": "tuple"
}
],
"name": "addSpigot",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "arbiter",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
}
],
"name": "available",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "borrow",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "borrower",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "claimToken",
"type": "address"
},
{
"internalType": "bytes",
"name": "zeroExTradeData",
"type": "bytes"
}
],
"name": "claimAndRepay",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "claimToken",
"type": "address"
},
{
"internalType": "bytes",
"name": "zeroExTradeData",
"type": "bytes"
}
],
"name": "claimAndTrade",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
}
],
"name": "close",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "counts",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "credits",
"outputs": [
{
"internalType": "uint256",
"name": "deposit",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "principal",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "interestAccrued",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "interestRepaid",
"type": "uint256"
},
{
"internalType": "uint8",
"name": "decimals",
"type": "uint8"
},
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "address",
"name": "lender",
"type": "address"
},
{
"internalType": "bool",
"name": "isOpen",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "deadline",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "declareInsolvent",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "defaultRevenueSplit",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "depositAndClose",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "depositAndRepay",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "escrow",
"outputs": [
{
"internalType": "contract IEscrow",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "healthcheck",
"outputs": [
{
"internalType": "enum LineLib.STATUS",
"name": "",
"type": "uint8"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "ids",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "increaseCredit",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "init",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
}
],
"name": "interestAccrued",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "interestRate",
"outputs": [
{
"internalType": "contract InterestRateCredit",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "targetToken",
"type": "address"
}
],
"name": "liquidate",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "mutualConsentProposals",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "nextInQ",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
},
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "uint128",
"name": "",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "",
"type": "uint128"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "oracle",
"outputs": [
{
"internalType": "contract IOracle",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "releaseSpigot",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_reconstrucedMsgData",
"type": "bytes"
}
],
"name": "revokeConsent",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newLine",
"type": "address"
}
],
"name": "rollover",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"internalType": "uint128",
"name": "drate",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "frate",
"type": "uint128"
}
],
"name": "setRates",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "spigot",
"outputs": [
{
"internalType": "contract ISpigot",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "status",
"outputs": [
{
"internalType": "enum LineLib.STATUS",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "stepQ",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "swapTarget",
"outputs": [
{
"internalType": "address payable",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "sweep",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "tradeable",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "unused",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "updateOutstandingDebt",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "revenueContract",
"type": "address"
}
],
"name": "updateOwnerSplit",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "func",
"type": "bytes4"
},
{
"internalType": "bool",
"name": "allowed",
"type": "bool"
}
],
"name": "updateWhitelist",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "useAndRepay",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "withdraw",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]
Spigot
[
{
"inputs": [
{
"internalType": "address",
"name": "_owner",
"type": "address"
},
{
"internalType": "address",
"name": "_operator",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "BadFunction",
"type": "error"
},
{
"inputs": [],
"name": "BadSetting",
"type": "error"
},
{
"inputs": [],
"name": "CallerAccessDenied",
"type": "error"
},
{
"inputs": [],
"name": "ClaimFailed",
"type": "error"
},
{
"inputs": [],
"name": "InvalidRevenueContract",
"type": "error"
},
{
"inputs": [],
"name": "NoRevenue",
"type": "error"
},
{
"inputs": [],
"name": "OperatorFnCallFailed",
"type": "error"
},
{
"inputs": [],
"name": "OperatorFnNotValid",
"type": "error"
},
{
"inputs": [],
"name": "OperatorFnNotWhitelisted",
"type": "error"
},
{
"inputs": [],
"name": "UnclaimedRevenue",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "revenueContract",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "ownerSplit",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes4",
"name": "claimFnSig",
"type": "bytes4"
},
{
"indexed": false,
"internalType": "bytes4",
"name": "trsfrFnSig",
"type": "bytes4"
}
],
"name": "AddSpigot",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "operator",
"type": "address"
}
],
"name": "ClaimOperatorTokens",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "ClaimOwnerTokens",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "escrowed",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "revenueContract",
"type": "address"
}
],
"name": "ClaimRevenue",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "revenueContract",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "RemoveSpigot",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "newOperator",
"type": "address"
}
],
"name": "UpdateOperator",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "UpdateOwner",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "revenueContract",
"type": "address"
},
{
"indexed": true,
"internalType": "uint8",
"name": "split",
"type": "uint8"
}
],
"name": "UpdateOwnerSplit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes4",
"name": "func",
"type": "bytes4"
},
{
"indexed": true,
"internalType": "bool",
"name": "allowed",
"type": "bool"
}
],
"name": "UpdateWhitelistFunction",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "revenueContract",
"type": "address"
},
{
"components": [
{
"internalType": "uint8",
"name": "ownerSplit",
"type": "uint8"
},
{
"internalType": "bytes4",
"name": "claimFunction",
"type": "bytes4"
},
{
"internalType": "bytes4",
"name": "transferOwnerFunction",
"type": "bytes4"
}
],
"internalType": "struct ISpigot.Setting",
"name": "setting",
"type": "tuple"
}
],
"name": "addSpigot",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "claimOperatorTokens",
"outputs": [
{
"internalType": "uint256",
"name": "claimed",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "claimOwnerTokens",
"outputs": [
{
"internalType": "uint256",
"name": "claimed",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "revenueContract",
"type": "address"
},
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "claimRevenue",
"outputs": [
{
"internalType": "uint256",
"name": "claimed",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "getOperatorTokens",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "getOwnerTokens",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "revenueContract",
"type": "address"
}
],
"name": "getSetting",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
},
{
"internalType": "bytes4",
"name": "",
"type": "bytes4"
},
{
"internalType": "bytes4",
"name": "",
"type": "bytes4"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "func",
"type": "bytes4"
}
],
"name": "isWhitelisted",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "revenueContract",
"type": "address"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "operate",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "operator",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "revenueContract",
"type": "address"
}
],
"name": "removeSpigot",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOperator",
"type": "address"
}
],
"name": "updateOperator",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "updateOwner",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "revenueContract",
"type": "address"
},
{
"internalType": "uint8",
"name": "ownerSplit",
"type": "uint8"
}
],
"name": "updateOwnerSplit",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "func",
"type": "bytes4"
},
{
"internalType": "bool",
"name": "allowed",
"type": "bool"
}
],
"name": "updateWhitelistedFunction",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]
Escrow
[
{
"inputs": [
{
"internalType": "uint32",
"name": "_minimumCollateralRatio",
"type": "uint32"
},
{
"internalType": "address",
"name": "_oracle",
"type": "address"
},
{
"internalType": "address",
"name": "_line",
"type": "address"
},
{
"internalType": "address",
"name": "_borrower",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "CallerAccessDenied",
"type": "error"
},
{
"inputs": [],
"name": "InvalidCollateral",
"type": "error"
},
{
"inputs": [],
"name": "NotLiquidatable",
"type": "error"
},
{
"inputs": [],
"name": "UnderCollateralized",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "AddCollateral",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "EnableCollateral",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "RemoveCollateral",
"type": "event"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "addCollateral",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "borrower",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "enableCollateral",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getCollateralRatio",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getCollateralValue",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "isLiquidatable",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "line",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "liquidate",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "minimumCollateralRatio",
"outputs": [
{
"internalType": "uint32",
"name": "",
"type": "uint32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "oracle",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "releaseCollateral",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_line",
"type": "address"
}
],
"name": "updateLine",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
]