Dharma lending - loan terms, repayment and collateral
Dharma lending originally used tokenized loan agreements on Ethereum whose smart contract terms defined repayment amounts and deadlines. Funding established the agreement, while accepted payments increased its repayment record. Dharma retired its consumer wallet in 2022, so the original lending design belongs to the project's earlier history.
Last updated:
In the original system, an order's funding deadline and the issued loan's repayment schedule governed different actions.
Order expiry limited new loan funding
A signed Debt Order remained a borrowing request until the original contracts successfully filled it. Expiry, cancellation or a contract pause could block that funding action. Required authorizations and sufficient lender funds also mattered.
Order expiry and loan maturity had separate purposes. Expiry limited funding; maturity belonged to an issued loan's repayment terms. Signing alone created neither a repayment history nor evidence that principal had reached the borrower.
Loan terms and repayment records
The principal was the amount specified in the borrowing terms, while a Terms Contract supplied the rules governing repayment. Its encoded parameters specified details such as the repayment token, interest and duration, so one contract could administer multiple agreements with separate balances and deadlines. The contract address identified the logic; the parameters supplied the values for that particular agreement.
Each agreement ID connected a particular loan to its entry in the DebtRegistry. That entry held the Terms Contract address and parameters, together with the issuance timestamp. The identifier linked the loan to its rules; repayment progress required the separate amount credited to that agreement.
getExpectedRepaymentValue returned the cumulative amount due by a chosen timestamp. getValueRepaidToDate reported the cumulative amount that the contract had credited. For a simple-interest agreement, comparing those values in the principal token's integer units exposed any repayment shortfall at that time. The amount due so far and the final maturity total answered different questions.
Funding fees affected the amounts that changed hands before repayments began. In the original DebtKernel, the borrower received the order's principal minus any debtor fee. The lender supplied the principal plus any creditor fee. Relayer and underwriter fees came from those contributions. The amount received therefore could differ from the principal specified in the borrowing terms.
How did the original contract calculate what was due?
SimpleInterestTermsContract calculated a principal-plus-interest target, then apportioned expected repayment across the time units of a loan with positive duration. The encoded principal and interest parameter determined that target. At or before issuance, the contract returned an expected repayment amount of zero.
During the term, the expected cumulative amount advanced as whole amortization units elapsed. An amortization unit was the interval used to divide the repayment schedule. A partial repayment increased the credited total without changing that schedule.
Term length combined a chosen time unit with the number of those units, and the issuance timestamp anchored that duration. The end timestamp therefore came from the funded agreement, not the date when somebody first drafted its order. At the end of a positive term, its expected total equaled the full target.
These rules applied to SimpleInterestTermsContract and its collateralized extension. The generic Terms Contract interface allowed other repayment logic. A loan that used another implementation required that implementation's expected-payment calculation.
Payments followed the debt token's recorded owner
The DebtToken contract updated the DebtRegistry's beneficiary when ownership transferred. Its ERC-721 token represented the right to receive repayments from the associated loan. The RepaymentRouter read that beneficiary for the agreement ID and directed accepted payments there. A transfer changed the recipient without resetting the agreement's credited repayment total or creating a new repayment schedule.
A direct token transfer to an old lender's address did not invoke the router's repayment registration. A token-transfer receipt and the Terms Contract's credited total described different records. The debt token's owner also could differ from the original lender.
Collateral release followed the credited repayment total
The original Collateralizer required recorded repayments to cover the full amount expected at the loan's term end before returning collateral. Calling returnCollateral on an unpaused Collateralizer returned assets to their recorded provider, provided it still held that agreement's collateral. Calling seizeCollateral required credited repayments to be below the amount due at the current timestamp minus the agreed grace period. The unpaused contract then sent eligible, still-locked collateral to the current beneficiary. These conditions belonged to this implementation; custom Terms Contracts could define other arrangements. An unsecured agreement had no pledged collateral to recover.
Why could a repayment leave the loan record unchanged?
The original RepaymentRouter could return zero and log an error without reverting the enclosing transaction. Its insufficient-balance-or-allowance check ran before repayment registration. A successful transaction status alone therefore did not establish that the loan had received a payment. In a hypothetical attempt under those contracts, an issued agreement existed and the payer held enough of the required token to cover the payment. Only the proxy's transfer allowance fell short. Increasing that allowance before retrying addressed this cause; repeating the payment request without changing permission did not. This remedy did not resolve a wrong repayment token or a paused router.
- Read the agreement ID and its credited repayment total before another attempt.
- Confirm that the Terms Contract allowed the chosen ERC-20 repayment token and that the payer balance covered the intended payment.
- Allow for gas on the approval and repayment transactions; cost depended on computation and price per gas unit.
- Authorize the TokenTransferProxy for the required payment amount before retrying the repayment.
- Inspect LogRepayment and reread the agreement's cumulative repayment total afterward.
Successful credit increased the repayment total by the accepted token amount. A repeated allowance error left that total unchanged. Gas covered transaction execution and did not count toward principal or interest.
Things people ask about Dharma lending
Could another address repay a Dharma loan on the borrower's behalf?
The original RepaymentRouter allowed the transaction sender to pay an existing agreement even when that sender was not the borrower. It took tokens from the payer's balance, subject to sufficient transfer allowance and the Terms Contract's acceptance. The payment credited the specified agreement; it did not change which borrower belonged to that loan.
Did early repayment reduce interest in the original simple-interest agreement?
Early repayment did not automatically reduce the interest calculated by SimpleInterestTermsContract. Its maturity target came from the encoded principal and interest parameter. Payments accumulated against that target. This rule applied to the original simple-interest implementation; another Terms Contract could have specified different repayment rules.
Were monthly Dharma repayment periods tied to calendar months?
The original SimpleInterestTermsContract treated a month as a fixed 30-day duration. Its repayment timing combined that duration with the agreement's issuance timestamp. Calendar-month boundaries did not determine its monthly repayment periods, which mattered when reconstructing a historical due date.
Which details of a Dharma loan were publicly visible?
The loan's on-chain records exposed addresses, terms and repayment activity. The DebtRegistry linked an agreement ID to its contract parameters and beneficiary. Repayment events identified the payer, recipient, token and amount. These records let observers examine a loan's activity, although an address alone did not supply a person's legal identity.
Did a Dharma underwriter automatically guarantee the borrower's payments?
An underwriting signature attested to a risk rating and the specified lending terms; it did not itself guarantee the borrower's repayments. The original underwriting role involved assessing default risk and servicing the loan. Its fee and recorded rating did not create pledged collateral.
Could cancelling a Debt Order erase a loan that had already been funded?
Cancelling a Debt Order blocked a future fill and did not erase an already issued agreement. The original DebtKernel checked the cancellation flag when considering funding. The issued loan's registry entry and Terms Contract separately governed its obligations. Cancelling the request therefore did not register repayment or reverse the earlier principal transfer.