Skip to content

Commit

Permalink
Add oracle to bsv-20 loan.
Browse files Browse the repository at this point in the history
  • Loading branch information
msinkec committed Nov 24, 2023
1 parent 4e1956f commit b9db604
Showing 1 changed file with 31 additions and 9 deletions.
40 changes: 31 additions & 9 deletions src/contracts/bsv20Loan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@ import { BSV20V2 } from 'scrypt-ord'
import {
assert,
ByteString,
byteString2Int,
hash256,
method,
prop,
PubKey,
pubKey2Addr,
sha256,
Sha256,
Sig,
SmartContract,
toByteString,
slice,
Utils,
} from 'scrypt-ts'
import { RabinPubKey, RabinSig, RabinVerifier } from 'scrypt-ts-lib'

export class Bsv20Loan extends BSV20V2 {
@prop()
Expand All @@ -26,7 +25,7 @@ export class Bsv20Loan extends BSV20V2 {
@prop()
tokenAmt: bigint

// Fixed interest rate of the load.
// Fixed interest rate of the loan.
// 1 = 1%
@prop()
interestRate: bigint
Expand All @@ -44,6 +43,9 @@ export class Bsv20Loan extends BSV20V2 {
@prop(true)
taken: boolean

@prop()
oraclePubKey: RabinPubKey

constructor(
id: ByteString,
sym: ByteString,
Expand All @@ -54,7 +56,8 @@ export class Bsv20Loan extends BSV20V2 {
tokenAmt: bigint,
interestRate: bigint,
collateral: bigint,
deadline: bigint
deadline: bigint,
oraclePubKey: RabinPubKey
) {
super(id, sym, max, dec)
this.init(...arguments)
Expand All @@ -66,10 +69,11 @@ export class Bsv20Loan extends BSV20V2 {
this.collateral = collateral
this.deadline = deadline
this.taken = false
this.oraclePubKey = oraclePubKey
}

@method()
public takeLoan() {
public borrow() {
// Check loan isn't taken yet.
assert(this.taken == false, 'loan already taken')
this.taken = true
Expand All @@ -88,12 +92,30 @@ export class Bsv20Loan extends BSV20V2 {
}

@method()
public repay() {
public repay(oracleMsg: ByteString, oracleSig: RabinSig) {
// Check loan is already taken.
assert(this.taken == true, 'loan not taken yet')

// Pay lender back the principal token amount plus interest.
// Check oracle signature.
assert(
RabinVerifier.verifySig(oracleMsg, oracleSig, this.oraclePubKey),
'oracle sig verify failed'
)

// Check that we're unlocking the UTXO specified in the oracles message.
assert(
slice(this.prevouts, 0n, 36n) == slice(oracleMsg, 0n, 36n),
'first input is not spending specified ordinal UTXO'
)

// Get token amount held by the UTXO from oracle message.
const utxoTokenAmt = byteString2Int(slice(oracleMsg, 36n, 44n))

// Check token amount is correct.
const interest = (this.tokenAmt * this.interestRate) / 100n
assert(utxoTokenAmt == this.tokenAmt + interest, 'invalid token amount')

// Pay lender back the principal token amount plus interest.
let outputs = BSV20V2.buildTransferOutput(
pubKey2Addr(this.lender),
this.id,
Expand Down

0 comments on commit b9db604

Please sign in to comment.