Skip to content

Instantly share code, notes, and snippets.

@graemecode
Last active August 31, 2018 08:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save graemecode/82021e2a4d131d969e6836762270d1a8 to your computer and use it in GitHub Desktop.
Save graemecode/82021e2a4d131d969e6836762270d1a8 to your computer and use it in GitHub Desktop.
Part 4/4 in a series on collateralizing ERC721s for loans on Dharma Protocol
/*********************
* Setup Dharma.js *
*********************/
// Instantiate Dharma
const dharma = new Dharma();
/*****************
* Repay a Loan *
*****************/
const DEBTOR_ADDRESS = "0x601e6e7711b9e3b1b20e1e8016038a32dfc86ddd";
const MAX_GAS = 4712388;
const TX_DEFAULTS = {
from: DEBTOR_ADDRESS,
gas: MAX_GAS,
};
const servicingApi = dharma.servicing;
// Retrieve debt agreements for the given debtor.
console.log(`Retrieving debts for ${DEBTOR_ADDRESS}...`);
servicingApi.getDebtsAsync(DEBTOR_ADDRESS).then(async (debts) => {
// We should have at least one debt to repay.
if (debts.length === 0) {
throw new Error("No debts were found!");
}
// Take the issuance hash for the first debt.
const issuanceHash = debts[0];
console.log(`Getting information for debt with issuance hash ${issuanceHash}`);
// Find what the principal token is for this debt.
const debtEntry = await servicingApi.getDebtRegistryEntry(issuanceHash);
const adapter = dharma.adapters.erc721CollateralizedSimpleInterestLoan;
const debtOrder = await adapter.fromDebtRegistryEntry(debtEntry);
const principalTokenSymbol = debtOrder.principalTokenSymbol;
const principalTokenAttributes = await dharma.token.getTokenAttributesBySymbol(
principalTokenSymbol
);
const principalTokenAddress = principalTokenAttributes.address;
// Find out how much we need to repay for this debt.
console.log(`Finding amount to repay for debt.`);
const amountToRepay = await servicingApi.getTotalExpectedRepayment(issuanceHash);
console.log(`Expected repayment: ${amountToRepay.toString()} ${principalTokenSymbol}`);
// Make a repayment.
console.log("Please sign the transaction to make a full repayment");
let txHash = await servicingApi.makeRepayment(
issuanceHash,
amountToRepay,
principalTokenAddress,
TX_DEFAULTS
);
console.log("Waiting for transaction to be mined (may take a while)...");
await dharma.blockchain.awaitTransactionMinedAsync(txHash);
// Find the new amount to repay.
console.log(`Transaction mined.`);
const amountRepaid = await servicingApi.getValueRepaid(issuanceHash);
if ((amountToRepay.minus(amountRepaid)).greaterThan(0)) {
throw new Error(
`Something went wrong and an amount is still outstanding:
${amountToRepay} ${principalTokenSymbol}`,
);
}
/***********************
* Return Collateral *
**********************/
// The collateral should now be returnable.
const isReturnable = await adapter.canReturnCollateral(issuanceHash);
if (!isReturnable) {
throw new Error("Something went and the collateral is not returnable yet.");
}
console.log("The collateral is now returnable. " +
"Please sign the transaction to reclaim your ERC721 collateral");
txHash = await adapter.returnCollateralAsync(issuanceHash, TX_DEFAULTS);
// Wait fort he transaction to be mined.
console.log("Waiting for transaction to be mined (may take a while)...");
await dharma.blockchain.awaitTransactionMinedAsync(txHash);
// Check to see if the collateral was indeed returned.
const collateralTokenId = debtOrder.tokenReference;
console.log("Checking owner of collateral token...");
const collateralToken = await dharma.contracts.loadMintableERC721ContractAsync();
const tokenOwner = await collateralToken.ownerOf.callAsync(collateralTokenId);
if (tokenOwner !== DEBTOR_ADDRESS) {
throw new Error(
`Something went wrong and the debtor is not yet the owner of the collateral token!
The current owner is ${tokenOwner}`,
);
}
console.log("The collateral has been returned to the debtor!");
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment