Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loan Contract #1903

Merged
merged 12 commits into from
Nov 6, 2020
Merged

Loan Contract #1903

merged 12 commits into from
Nov 6, 2020

Conversation

katelynsills
Copy link
Contributor

@katelynsills katelynsills commented Oct 22, 2020

Adds a basic loan contract using a priceAuthority, with tests.

Add collateral of a particular brand and get a loan of another brand. Collateral (as known as margin) must be greater than the loan value, at an amount set by the Maintenance Margin Requirement (mmr) in the terms of the contract. The loan does not have a distinct end time. Rather, if the value of the collateral changes such that insufficient margin is provided, the collateral is liquidated, and the loan is closed. At any time, the borrower can add collateral or repay the loan with interest, closing the loan.

The borrower can set up their own margin calls by getting the priceAuthority from the terms and calling E(priceAuthority).quoteWhenLT(allCollateral, x) where x is the value of the collateral in the Loan brand at which they want a reminder to addCollateral.

Note that all collateral must be of the same brand and all of the
loaned amount and interest must be of the same (separate) brand.

Terms:

  • mmr (default = 150) - the Maintenance Margin Requirement, in
    percent. The default is 150, meaning that collateral should be
    worth at least 150% of the loan. If the value of the collateral
    drops below mmr, liquidation occurs.
  • priceAuthority - will be used for getting the current value of
    collateral and setting liquidation triggers.
  • autoswapInstance - The running contract instance for an Autoswap
    or Multipool Autoswap installation. The publicFacet of the
    instance is used for producing an invitation to sell the
    collateral on liquidation.
  • periodAsyncIterable - the asyncIterable used for notifications
    that a period has passed, on which compound interest will be
    calculated using the interestRate.
  • interestRate - the rate in basis points that will be multiplied
    with the debt on every period to compound interest.

IssuerKeywordRecord:
Keyword: 'Collateral' - The issuer for the digital assets to be
escrowed as collateral.
Keyword: 'Loan' - The issuer for the digital assets to be loaned
out.

Closes #1942
Closes #1939

Copy link
Contributor

@Chris-Hibbert Chris-Hibbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nicely structured. I appreciate all the distinct source files, each well-commented.

This looks like a good approach. The main thing (other than just unfinished stuff) is that when liquidation is triggered, or the collateral changes, the code needs to recalculate the trigger levels and reschedule the trigger.

I've finished reading the contract code, and have the types and tests still to read.

packages/zoe/src/contracts/loan/lend.js Outdated Show resolved Hide resolved
packages/zoe/src/contracts/loan/borrow.js Outdated Show resolved Hide resolved
packages/zoe/src/contracts/loan/borrow.js Show resolved Hide resolved
packages/zoe/src/contracts/loan/borrow.js Outdated Show resolved Hide resolved
packages/zoe/src/contracts/loan/borrow.js Outdated Show resolved Hide resolved
packages/zoe/src/contracts/loan/close.js Outdated Show resolved Hide resolved
packages/zoe/src/contracts/loan/liquidate.js Outdated Show resolved Hide resolved
packages/zoe/src/contracts/loan/liquidate.js Outdated Show resolved Hide resolved
packages/zoe/src/contracts/loan/liquidate.js Outdated Show resolved Hide resolved
@katelynsills
Copy link
Contributor Author

This looks like a good approach. The main thing (other than just unfinished stuff) is that when liquidation is triggered, or the collateral changes, the code needs to recalculate the trigger levels and reschedule the trigger.

Oh good catch, I will fix

@katelynsills katelynsills added the Zoe package: Zoe label Oct 28, 2020
@rowgraus
Copy link

Remaining to-do: address liquidations re: comments from @Chris-Hibbert

@rowgraus rowgraus added this to the Chainlink Hackathon milestone Oct 28, 2020
@rowgraus
Copy link

rowgraus commented Nov 4, 2020

Adjust to allow loan to take mocked price from Chainlink instead of internal autoswap price authority

@katelynsills katelynsills marked this pull request as ready for review November 5, 2020 05:44
Copy link
Contributor

@Chris-Hibbert Chris-Hibbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly minor enhancements to doc or type info.

I suggest a few additional tests, some of which might point to code that doesn't exist. Would you look at these and see if any are needed before people start using the contract?

packages/zoe/src/contracts/loan/index.js Outdated Show resolved Hide resolved
Comment on lines +149 to +153
// TODO: implement
getPriceNotifier: () => {
const { notifier } = makeNotifierKit();
return notifier;
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been added in #1985.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like your version will get in first, and I'll integrate when I merge 1985.

packages/zoe/src/contracts/loan/close.js Outdated Show resolved Hide resolved
packages/zoe/src/contracts/loan/scheduleLiquidation.js Outdated Show resolved Hide resolved
packages/zoe/src/contracts/loan/borrow.js Show resolved Hide resolved

import { trade } from '../../../../src/contractSupport';

test('test doLiquidation with mocked autoswap', async t => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

additional test:

  • autoswap fails
  • multiple scheduled liquidations don't interfere

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'Multiple scheduled liquidations' is already tested.

For 'autoswap fails' - do you mean the trade fails? That is not tested.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't see a test that verifies that the two liquidations from an initial borrow and adding collateral don't interfere. Which test are you referring to?

For 'autoswap fails' - do you mean the trade fails?

Yeah, with autoswap, that pair might not have been initialized, or all the collateral could have been removed. There's no guarantee that autoswap will always succeed. Particularly in the start-up sequence, it's conceivable that a pair of currencies could be missing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't see a test that verifies that the two liquidations from an initial borrow and adding collateral don't interfere. Which test are you referring to?

'borrow, then addCollateral, then getLiquidationPromise'

performAddCollateral,
} from './helpers';

test.todo('makeAddCollateralInvitation - test bad proposal');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

additionally:

  • can we verify that a new liquidation trigger was rescheduled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is tested already.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See 'borrow, then addCollateral, then getLiquidationPromise'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That tests ends with t.falsy(liquidated);, so I think it shows that neither was triggered. I'm interested in the case where both price levels are exceeded, but only the rescheduled one should cause liquidation.

value is at 12
borrow 100 with 16 of collateral. (12 * 16 > 1.5 * 100)
value goes to 10 (10 * 16 > 1.5 * 100)
addCollateral of 10
value goes to 8; with 16 collateral, would have liquidated (8 * 16 < 1.5 * 100)
value goes to 5; now we should actually liquidate. (5 * 26 < 1.5 * 100)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, good point. That liquidated is old - the liquidation code doesn't call that anymore. Let me revise that test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Liquidation is added to that test

@katelynsills
Copy link
Contributor Author

@Chris-Hibbert Ready for another review

Copy link
Contributor

@Chris-Hibbert Chris-Hibbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates. This looks good now.

packages/zoe/src/contracts/loan/liquidate.js Outdated Show resolved Hide resolved
Comment on lines +149 to +153
// TODO: implement
getPriceNotifier: () => {
const { notifier } = makeNotifierKit();
return notifier;
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like your version will get in first, and I'll integrate when I merge 1985.

katelynsills and others added 5 commits November 5, 2020 21:02
Co-authored-by: Chris Hibbert <Chris-Hibbert@users.noreply.github.com>
Co-authored-by: Chris Hibbert <Chris-Hibbert@users.noreply.github.com>
Co-authored-by: Chris Hibbert <Chris-Hibbert@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Zoe package: Zoe
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add interest calculations to loan contract and tests Determine Interest Calculation for Loan Contract
3 participants