Loan Assignment

Loan Assignment

The Borrower sends a loan request to the Lending Contract to initiate a loan.

{
	"borrower":"bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297",
	"maturityTime": "2024-10-10T10:10:10z",
	"hashLock": "hash of loan_secret"
}

The Lending Contract then assigns a unique vault, the Collateral Vault, for the loan. Expressed in a Miniscript-like pseudocode, the lock script for this vault is as follows:

or(
    // case 1 - the DCA and Borrower can collaborate to create CETs
    and(
        pk(borrower_pk),
        thresh(T, pk(dca0_pk),pk(dca1_pk),...pk(dcaN_pk))
    ),
    
    // case 2 - the Borrower can reclaim collateral after loan repayment
		// the threshold adapted signature comes from the DCA
    and(
        pk(borrower_pk),
        thresh(pk(dca0_pk),pk(dca1_pk),...pk(dcaN_pk)),
    ),
    
    // case 3 - DCA owns collateral after `maturityTime`
    and(
        hash256(loanHash),
        after(maturityTime),
        thresh(T, pk(dca0_pk),pk(dca1_pk),...pk(dcaN_pk))
    ),
    
    // case 4 - collateral reverts to Borrower after final timeout
    and(
        pk(borrower_pk),
        after(final_timeout)
    )
)

The Collateral Vault is the basis of all further collateral-related operations. This paper will go into detail regarding each spending condition, below. For the moment, we can make a few observations to aid in understanding.

The DCA multi-sig participants are indexed from 0..N, with a threshold T of signatures required to spend.

The aggregated adapter signature setup in the above script is worth looking at in more detail. We can describe the Adapter Signature process formally as follows. Let λ represent the secret scalar, and G be the base point of the elliptic curve. The adaptor point A is computed as A = λG. Let m denote the message, which is the SHA-256 hash of the Loan Request JSON data: m = SHA256(LR_JSON)

Given a private key sk, a nonce seed η, and the adaptor point A, we define the adaptor signature σ_A = SignAdaptor(sk, m, η, A).

The function SignAdaptor represents the cryptographic operation to create an adaptor signature. To redeem the signature, we use the secret λ to adapt σ_A, producing the final signature σ = Adapt(σ_A, λ).

In this formulation:

  • λ ∈ Zq (the scalar field of the curve)

  • A, G ∈ E(Fq) (points on the elliptic curve)

  • m ∈ {0,1}^256 (256-bit hash output)

  • σ_A, σ are elements of the signature space

To summarize: from the Bitcoin chain’s point of view, the resulting signature is a normal Schnorr signature. However, the scheme transforms the signing process to output a special adapter signature into a which a secret can later be revealed during signing. This adapter signature will be used later on to allow trustless loan repayment. This technique leverages what are known in Bitcoin parlance as Scriptless Scripts.

The Lending Contract also needs to compute the interest and liquidation price based on the current price and pre-allocate funds for this loan, representing it as the Loan Request LR_JSON:

{
	"borrower":"bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297",
	"maturityTime": "2025-10-10T10:10:10z",
	"hashLock": "465b1a66c9f386308e8c75acef9201f3f577811da09fc90ad",
	"borrowAmount": "20000",
	"vaultAddress": "bc1p6r4u4qlajya6feu337gtngksgeyf4nf0mf4q35gtcj5v0ja9m00q3eagh3",
	"Oracles": ["Oracle 1", "Oracle 2", "Oracle 3"],
	"currentPrice": "50000.00",
	"collateralAmount": "1",
	"createAt": "2024-10-10T10:10:10z"
}

If the Borrower agrees to the terms, they can send the BTC collateral to the Collateral Vault. Once confirmed on Side Chain, the Borrower ****outputs and signs CETs for a Bitcoin Discreet Log Contract, exchanging them for counter-signing with the DCA. The borrower also creates an adaptor signature over the above LR_JSON contract message.

In code, the adapter signature generation process is as follows:

let adaptor_point = secret.base_point_mul();
let message = sha265(lr_json);
let adaptor_signature = sign_adaptor(seckey, message, nonce_seed, adaptor_point);
let redeem_signature = adaptor_signature.adapt(b"loan_secret");

The Borrower then submits the CETs, the adaptor signature and the redeem_signature to Lending Contract on the Side Chain to claim a loan assets such as USDC.

If the adaptor signature is verified, the loan_secret can be revealed from the redeem_signature. If its hash matches the one provided in the Loan Request, the Borrower can claim the loan that was previously allocated to them.

// Lending Contract
let verified = verify(borrower_pubkey, adaptor_signature, message, adaptor_point);
assert_eq(sha256(b"loan_secret"), hashLock)
let revealed_secret = adaptor_signature.adapt(redeem_signature)
if sha256(revealed_secret) === <hashLock>  {
	 // send USDC to the borrower
}

At this point, collateral is locked in the Collateral Vault, and the Borrower has in turn received the loan. The Borrower may repay at any point before Maturity Time.

Last updated