Skip to content

Commit 31b699e

Browse files
committed
integ test for Lending Protocol with IOU
1 parent 388553d commit 31b699e

File tree

1 file changed

+204
-0
lines changed

1 file changed

+204
-0
lines changed

tests/integration/transactions/test_lending_protocol.py

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,21 @@
1010
from xrpl.core.keypairs.main import sign
1111
from xrpl.models import (
1212
AccountObjects,
13+
AccountSet,
14+
AccountSetAsfFlag,
1315
LoanBrokerSet,
1416
LoanDelete,
1517
LoanManage,
1618
LoanPay,
1719
LoanSet,
20+
Payment,
1821
Transaction,
22+
TrustSet,
1923
VaultCreate,
2024
VaultDeposit,
2125
)
26+
from xrpl.models.amounts import IssuedCurrencyAmount
27+
from xrpl.models.currencies.issued_currency import IssuedCurrency
2228
from xrpl.models.currencies.xrp import XRP
2329
from xrpl.models.requests.account_objects import AccountObjectType
2430
from xrpl.models.response import ResponseStatus
@@ -166,3 +172,201 @@ async def test_lending_protocol_lifecycle(self, client):
166172
response = await sign_and_reliable_submission_async(tx, borrower_wallet, client)
167173
self.assertEqual(response.status, ResponseStatus.SUCCESS)
168174
self.assertEqual(response.result["engine_result"], "tesSUCCESS")
175+
176+
@test_async_and_sync(
177+
globals(), ["xrpl.transaction.autofill_and_sign", "xrpl.transaction.submit"]
178+
)
179+
async def test_lending_protocol_lifecycle_with_iou_asset(self, client):
180+
loan_issuer = Wallet.create()
181+
await fund_wallet_async(loan_issuer)
182+
183+
depositor_wallet = Wallet.create()
184+
await fund_wallet_async(depositor_wallet)
185+
borrower_wallet = Wallet.create()
186+
await fund_wallet_async(borrower_wallet)
187+
188+
# Step-0: Set up the relevant flags on the loan_issuer account -- This is
189+
# a pre-requisite for a Vault to hold the Issued Currency Asset
190+
response = await sign_and_reliable_submission_async(
191+
AccountSet(
192+
account=loan_issuer.classic_address,
193+
set_flag=AccountSetAsfFlag.ASF_DEFAULT_RIPPLE,
194+
),
195+
loan_issuer,
196+
)
197+
self.assertTrue(response.is_successful())
198+
self.assertEqual(response.result["engine_result"], "tesSUCCESS")
199+
200+
# Step 0.1: Set up trustlines required for the transferring the IOU token
201+
tx = TrustSet(
202+
account=depositor_wallet.address,
203+
limit_amount=IssuedCurrencyAmount(
204+
currency="USD", issuer=loan_issuer.address, value="1000"
205+
),
206+
)
207+
response = await sign_and_reliable_submission_async(
208+
tx, depositor_wallet, client
209+
)
210+
self.assertEqual(response.status, ResponseStatus.SUCCESS)
211+
self.assertEqual(response.result["engine_result"], "tesSUCCESS")
212+
213+
tx = TrustSet(
214+
account=borrower_wallet.address,
215+
limit_amount=IssuedCurrencyAmount(
216+
currency="USD", issuer=loan_issuer.address, value="1000"
217+
),
218+
)
219+
response = await sign_and_reliable_submission_async(tx, borrower_wallet, client)
220+
self.assertEqual(response.status, ResponseStatus.SUCCESS)
221+
self.assertEqual(response.result["engine_result"], "tesSUCCESS")
222+
223+
# Step 0.2: Transfer the `USD` IOU to depositor_wallet and borrower_wallet
224+
tx = Payment(
225+
account=loan_issuer.address,
226+
destination=depositor_wallet.address,
227+
amount=IssuedCurrencyAmount(
228+
currency="USD", issuer=loan_issuer.address, value="1000"
229+
),
230+
)
231+
response = await sign_and_reliable_submission_async(tx, loan_issuer, client)
232+
self.assertEqual(response.status, ResponseStatus.SUCCESS)
233+
self.assertEqual(response.result["engine_result"], "tesSUCCESS")
234+
235+
tx = Payment(
236+
account=loan_issuer.address,
237+
destination=borrower_wallet.address,
238+
amount=IssuedCurrencyAmount(
239+
currency="USD", issuer=loan_issuer.address, value="1000"
240+
),
241+
)
242+
response = await sign_and_reliable_submission_async(tx, loan_issuer, client)
243+
self.assertEqual(response.status, ResponseStatus.SUCCESS)
244+
self.assertEqual(response.result["engine_result"], "tesSUCCESS")
245+
246+
# Step-1: Create a vault
247+
tx = VaultCreate(
248+
account=loan_issuer.address,
249+
asset=IssuedCurrency(currency="USD", issuer=loan_issuer.address),
250+
assets_maximum="1000",
251+
withdrawal_policy=WithdrawalPolicy.VAULT_STRATEGY_FIRST_COME_FIRST_SERVE,
252+
)
253+
response = await sign_and_reliable_submission_async(tx, loan_issuer, client)
254+
self.assertEqual(response.status, ResponseStatus.SUCCESS)
255+
self.assertEqual(response.result["engine_result"], "tesSUCCESS")
256+
257+
account_objects_response = await client.request(
258+
AccountObjects(account=loan_issuer.address, type=AccountObjectType.VAULT)
259+
)
260+
self.assertEqual(len(account_objects_response.result["account_objects"]), 1)
261+
VAULT_ID = account_objects_response.result["account_objects"][0]["index"]
262+
263+
# Step-2: Create a loan broker
264+
tx = LoanBrokerSet(
265+
account=loan_issuer.address,
266+
vault_id=VAULT_ID,
267+
)
268+
response = await sign_and_reliable_submission_async(tx, loan_issuer, client)
269+
self.assertEqual(response.status, ResponseStatus.SUCCESS)
270+
self.assertEqual(response.result["engine_result"], "tesSUCCESS")
271+
272+
# Step-2.1: Verify that the LoanBroker was successfully created
273+
response = await client.request(
274+
AccountObjects(
275+
account=loan_issuer.address, type=AccountObjectType.LOAN_BROKER
276+
)
277+
)
278+
self.assertEqual(len(response.result["account_objects"]), 1)
279+
LOAN_BROKER_ID = response.result["account_objects"][0]["index"]
280+
281+
# Step-3: Deposit funds into the vault
282+
tx = VaultDeposit(
283+
account=depositor_wallet.address,
284+
vault_id=VAULT_ID,
285+
amount=IssuedCurrencyAmount(
286+
currency="USD", issuer=loan_issuer.address, value="1000"
287+
),
288+
)
289+
response = await sign_and_reliable_submission_async(
290+
tx, depositor_wallet, client
291+
)
292+
self.assertEqual(response.status, ResponseStatus.SUCCESS)
293+
self.assertEqual(response.result["engine_result"], "tesSUCCESS")
294+
295+
# Step-5: The Loan Broker and Borrower create a Loan object with a LoanSet
296+
# transaction and the requested principal (excluding fees) is transered to
297+
# the Borrower.
298+
loan_issuer_signed_txn = await autofill_and_sign(
299+
LoanSet(
300+
account=loan_issuer.address,
301+
loan_broker_id=LOAN_BROKER_ID,
302+
principal_requested="100",
303+
counterparty=borrower_wallet.address,
304+
),
305+
client,
306+
loan_issuer,
307+
)
308+
309+
# borrower agrees to the terms of the loan
310+
borrower_txn_signature = sign(
311+
encode_for_signing(loan_issuer_signed_txn.to_xrpl()),
312+
borrower_wallet.private_key,
313+
)
314+
315+
loan_issuer_and_borrower_signature = loan_issuer_signed_txn.to_dict()
316+
loan_issuer_and_borrower_signature["counterparty_signature"] = (
317+
CounterpartySignature(
318+
signing_pub_key=borrower_wallet.public_key,
319+
txn_signature=borrower_txn_signature,
320+
)
321+
)
322+
323+
response = await submit(
324+
Transaction.from_dict(loan_issuer_and_borrower_signature),
325+
client,
326+
fail_hard=True,
327+
)
328+
329+
self.assertEqual(response.status, ResponseStatus.SUCCESS)
330+
self.assertEqual(response.result["engine_result"], "tesSUCCESS")
331+
332+
# Wait for the validation of the latest ledger
333+
await client.request(LEDGER_ACCEPT_REQUEST)
334+
335+
# fetch the Loan object
336+
response = await client.request(
337+
AccountObjects(account=borrower_wallet.address, type=AccountObjectType.LOAN)
338+
)
339+
self.assertEqual(len(response.result["account_objects"]), 1)
340+
LOAN_ID = response.result["account_objects"][0]["index"]
341+
342+
# Delete the Loan object
343+
tx = LoanDelete(
344+
account=loan_issuer.address,
345+
loan_id=LOAN_ID,
346+
)
347+
response = await sign_and_reliable_submission_async(tx, loan_issuer, client)
348+
self.assertEqual(response.status, ResponseStatus.SUCCESS)
349+
# Loan cannot be deleted until all the remaining payments are completed
350+
self.assertEqual(response.result["engine_result"], "tecHAS_OBLIGATIONS")
351+
352+
# Test the LoanManage transaction
353+
tx = LoanManage(
354+
account=loan_issuer.address,
355+
loan_id=LOAN_ID,
356+
flags=LoanManageFlag.TF_LOAN_IMPAIR,
357+
)
358+
response = await sign_and_reliable_submission_async(tx, loan_issuer, client)
359+
self.assertEqual(response.status, ResponseStatus.SUCCESS)
360+
self.assertEqual(response.result["engine_result"], "tesSUCCESS")
361+
362+
# Test the LoanPay transaction
363+
tx = LoanPay(
364+
account=borrower_wallet.address,
365+
loan_id=LOAN_ID,
366+
amount=IssuedCurrencyAmount(
367+
currency="USD", issuer=loan_issuer.address, value="100"
368+
),
369+
)
370+
response = await sign_and_reliable_submission_async(tx, borrower_wallet, client)
371+
self.assertEqual(response.status, ResponseStatus.SUCCESS)
372+
self.assertEqual(response.result["engine_result"], "tesSUCCESS")

0 commit comments

Comments
 (0)