Lending Plapp on predicate interface


#1

Overview

This document describes an architecture design of lending plapps (plasma apps). I outlined the specification referring to Dharma project functionalities. Special thanks to @ben-chain for review and thanks to @yuriko.

  1. Collateralizer(Alice) and Lender(Bob) swap their tokens
    • Alice makes her collateral state with token A and swap the collateral for Bob’s token B.
    • It means that Bob lent token B to Alice
  2. Collateral(tokenA) is returned to Alice if the total repayment has been repaid within the grace period.

Architecture

We defined 2 predicates, swap predicate and collateral predicate based on Plasma Group’s specification. You first use swap predicate to set up a collateral. Then, lender will execute collateral predicate.

Swap predicate

This is a setup phase of lending. The debtor makes the collateral state described in the next section and swap it for loaned token.

It’s basically the same design as swap predicate, but collateralizer wants to cancel collateral when a swap fails. Hence, requirements are

  • When a swap succeeds, the new state is a collateral state
  • When a swap fails, the new state is a simple ownership of collateralizer(Alice)

verifyTransaction

  • ensure witness is a signature by preState.data.owner
  • If predicate can ensure inclusion of a counter state(loan)
    • ensure inclusion of a counter state(loan)
    • ensure postState is a collateral state
  • If predicate can’t ensure inclusion of a counter state
    • ensure postState has the ownership of collateralizer

Collateral predicate

State object specification

struct lendingStateData:
  collateralizer: address
  lender: address
  amount: uint256
  grace_period: uint256

Methods

There are 2 methods.

refundCollateral method

Refund collateral. Lender gets a refund on the collateral after debt enters default.

returnCollateral method

Collateral is returned to the original collateralizer of the debt agreement.
The collateralizer can get collateral in exchange for the “repayment”.

verifyTransaction

Refund collateral.

  • ensure block.number is bigger than preState.data.grace_period
    • ensure witness is a signature by preState.data.lender
    • ensure block.number is bigger than preState.data.grace_period
    • ensure postState.range has the same amount as transaction.range
    • ensure postState is a ownership state of prestate.data.lender
  • ensure block.number is smaller than preState.data.grace_period
    • ensure witness is a signature by preState.data.collateralizer(Alice)
    • ensure “repayment” has valid history
      • finalize exit of “repayment” on behalf of lender(Bob)
      • or show deprecation of “repayment” by Bob
    • ensure “repayment” has the same amount as preState.data.amount
    • ensure postState.range has the same amount as transaction.range
    • ensure postState has the ownership state of collateralizer

Questions

  • Can Alice use tokenA after the repayment?

I think she can, as far as she proves that her “repayment” is valid. It means recievers of tokenA should verify tokenB’s history. It requires addtional amount of history.

When operator withholds a block, Alice should be able to exit her collateral state. The grace period should be added for its upcoming challenge period.

  • Can Bob use tokenA after debt enters default?

Bob can keep using tokenA after its grace period. When Bob attempts to use tokenA maliciously, for example when he (and colluded operator) transfers tokenA to someone before the grace period ends, Alice should be able to exit tokenA as soon as possible.


[Retrospective] Plasma Implementers Call #21!
#2

Do you need 2 predicates? As far as I understand, a single predicate should be able to mutate state where the transactions can be setupCollateral, swap, makePayment, refundCollateral and returnCollateral. As you mentioned that state can be denoted by

struct lendingStateData:
  collateralizer: address
  lender: address
  amount: uint256
  grace_period: uint256

If and when the plasma chain is rogue and either the debtor or lender want to exit, they can provide the proof of inclusion of the particular state they wish to exit from.

Attack scenario (just thinking out loud): Let’s say debtor took a loan of value x by putting a collateral of amount y such that y > x. Then they started paying x/12 of loan amount every month. So after 3 months they had 3x/4 in outstanding loan and x/2 after 6 months. Now imagine, that the asset volatility caused y < 3x/4 to happen. It is in debtor’s interest to claim they didn’t make any payments after 3 months (because at that point their collateral is worth less than the loan amount). So the debtor will start an exit from a state update after the 3rd month - Then the lender will challenge their exit using the state updates caused by payments from 4th to 6th month and signed by the debtor. Then debtor’s exit will be cancelled and plasma guarantees will save the lender!

To answer your question, yes Alice (if load paid) or Bob (if loan defaulted) can use tokenA as along as your plasma exit construction is secure and it enables the participants to exit with what they rightfully own.


#3

Thank you for your comment.

Do you need 2 predicates? As far as I understand, a single predicate should be able to mutate state where the transactions can be setupCollateral , swap , makePayment , refundCollateral and returnCollateral .

Oh, you’re right. I thought this swap predicate is more abstract one first. So, I split into 2 predicates. But maybe this swap predicate highly depends on collateral predicate. :sweat_smile:
It’s better to be designed as 1 predicate.

Attack scenario (just thinking out loud): Let’s say debtor took a loan of value x by putting a collateral of

Yes! :scream: I’ll update spec to support this scenario.


#4

I think we need timeout predicate standard which has 2 deprecate logics which support expired and not expired cases. fast-finality-predicate also requires timeout. The timeout should be verified in beginExit and the predicate choose one deprecation logic from 2 according to when exit was started. And when 2 or multiple exits are happen(also include limbo exit) simultaneously, “not expired exit” wins “expired exit”.