---
# System prepended metadata

title: Sequence Diagrams

---

# Dutch Auction Sequence Diagrams

- Logic derived from E2E tests mock dutch auction function: https://github.com/figuremarkets/democratized-prime-smart-contract/pull/25/files#diff-4b449d39383cb9fc2df11358f03e1b2a006240fc86a447e9ae27bc4121f9fdf8R394-R696

## 1. Start Auction

- 1 Block needed to broadcast the SetAuctionStatus(InProgress)
- Probably 1 Block needed to consume the completed/successful TxHash

```mermaid
sequenceDiagram
    actor C as AsyncJobScheduler
    participant LS as Lending Service
    participant SC as Demo Prime Pool Smart contract
    participant ES as Provenance  EventStream
    participant DB as Lending Service DB

    C->>LS: START: If current time > auction end time, <br> then Start Dutch Auction
    LS->>SC: Wasm Exec SetAuctionStatus(InProgress)
    SC->>SC: Update AuctionStatus
    ES->>LS: Consume Tx Hash & verify successful

    LS->>DB: Mark Dutch auction as InProgress

```

## 2. Calculate & Allocate Lender Interest for the previous period

```mermaid
sequenceDiagram
    participant LS as Lending Service
    participant SC as Demo Prime Pool Smart contract
    participant ES as Provenance  EventStream
    participant DB as Lending Service DB

    LS->>LS: START: SetAuctionStatus(InProgress) is Marked COMPLETE

		LS->>DB: Trigger offer update calc stored procedure

    DB->>DB: Query ALL active Borrows for the pool
    DB->>DB: Query ALL Borrow Repayments for the pool
    DB->>DB: Query ALL outstanding Offers for the pool
    DB->>DB: calculateOfferUtilizationCheckpoint(offers, borrows, repayments). <br> Sort Offers by (rate,sequence) for old offers, and (sequence) for intra-period created offers
    loop For each offer (in DB stored procedure
        DB->>DB: calculatePeriodInterestAccrual(offer)
        DB->>DB: calculatePeriodInterestDustAccrual(offer)
        DB->>DB: calculateNewCumulativeBalances(offer) <br> (principal & interest)
    end

    loop For each BatchOf100(offers)
        LS->>DB: Queue AuctionUpdateLenderOffers(offer_updates) Tx
    end

    loop For each AuctionUpdateLenderOffers(offer_updates) Tx
        LS->>DB: Pull Tx broadcast data
        LS->>SC: Broadcast Wasm Execute AuctionUpdateLenderOffers(offer_updates)
        SC->>ES: Publish Completion Tx data <br> (TxHash/TxEvents)
        ES->>LS: Consume TxHash(es)
        LS->>DB: Persist lender update batch TxHash(es). Mark as COMPLETE
        LS->>DB: Update OfferRecords with new amounts (TODO: how to efficiently link the interest accrual as a transfer to an Offer in DB)
    end

    LS->>SC: Broadcast AuctionResetIntraPeriodOffers <br> (To clear contract intra-period offer storage for the next period)

```

## 3. Auction offer exits

```mermaid
sequenceDiagram
    participant LS as Lending Service
    participant SC as Demo Prime Pool Smart contract
    participant ES as Provenance  EventStream
    participant DB as Lending Service DB

    LS->>LS: START: AuctionResetIntraPeriodOffers is Marked COMPLETE

    LS->>DB: Query ALL outstanding Offers for the pool
    DB->>LS: Return ALL outstanding Offers for the pool (consumed from EventStream)

    LS->>LS: calculateOfferUtilizationCheckpoint(offers, borrows, repayments). <br> Sort Offers by (rate,sequence) for old offers, and (sequence) for intra-period created offers

    loop For Each offer
        LS->>LS: Filter for offer.exitHeight != null <br> (offer exit has been requested) and push into offersToExit (List)
        LS->>LS: Sort offersToExit by offer.exitHeight
    end

    LS->>SC: Query GetState() @ latest block height
    SC->>LS: Return Auction/Balances/ContractState

    loop For Each offerToExit
        LS->>LS: calculateExitableAmount(offerToExit, state.balances)
        LS->>LS: updateOfferReceivable(offerToExit, exitableAmount)
        LS->>LS: Push new receivable to offerExits
    end

    loop For each BatchOf100(offerExits)
        LS->>DB: Queue AuctionExitOffers(offerExits) Tx
    end

    loop For each AuctionExitOffers(offerExits) Tx
        LS->>DB: Pull Tx broadcast data
        LS->>SC: Broadcast Wasm Execute AuctionExitOffers(offerExits)
        SC->>ES: Publish Completion Tx data <br> (TxHash/TxEvents)
        ES->>LS: Consume TxHash(es)
        LS->>DB: Persist lender update batch TxHash(es). Mark as COMPLETE
        LS->>DB: Update OfferRecords with new amounts (TODO: how to efficiently link the interest accrual as a transfer to an Offer in DB)
    end

```

- TODO exitHeight → exitSequence

## 4. Get Offer Utilization checkpoint + Auction Rate for next period

```mermaid
sequenceDiagram
    participant LS as Lending Service
    participant SC as Demo Prime Pool Smart contract
    participant ES as Provenance EventStream
    participant DB as Lending Service DB

    LS->>LS: START: AuctionExitOffers is Marked COMPLETE

    LS->>DB: Query get ALL outstanding/active offers for the pool
    DB->>LS: Return ALL outstanding/active offers for the pool

    LS->>SC: Query GetState() @ latest block height
    SC->>LS: Return Auction/Balances/ContractState
    LS->>LS: calculateTotalBorrowerUtilization(state.balances) <br> (borrower_payable + borrower_int_payable)

    LS->>LS: calculateOfferUtilizationCheckpoint(totalBorrowerUtilization, offers)
    LS->>LS: periodRate = rateOf(newOfferUtilizationCheckpoint)

```

- TODO How to handle rollback of bad offer exit amount in DB

## 5. Calculate & Update Borrower interest/fee accrual

```mermaid
sequenceDiagram
    participant LS as Lending Service
    participant SC as Demo Prime Pool Smart contract
    participant ES as Provenance EventStream
    participant DB as Lending Service DB

    LS->>LS: START next periodRate calculation completed

    loop For Each borrow
        LS->>LS: calculatePeriodInterestAccrual(borrow, periodRate)
        LS->>LS: calculatePeriodFeeAccrual(borrow, periodRate)
        LS->>LS: updateBorrowAccruals(borrow, periodInterest, periodFee)
    end

    loop For each BatchOf100(borrowerUpdates)
        LS->>DB: Queue AuctionUpdateBorrowLoans(borrowerUpdates) Tx
    end

    loop For each AuctionUpdateBorrowLoans(borrowerUpdates) Tx
        LS->>DB: Pull Tx broadcast data
        LS->>SC: Broadcast Wasm Execute AuctionUpdateBorrowLoans(borrowerUpdates)
        SC->>ES: Publish Completion Tx data <br> (TxHash/TxEvents)
        ES->>LS: Consume TxHash(es)
        LS->>DB: Persist borrower update batch TxHash(es). Mark as COMPLETE
        LS->>DB: Update BorrowRecords with new amounts (TODO: how to efficiently link the interest/fee accrual as a transfer to a Borrow in DB)
    end

```

## 6. Final step, update contract state (balances/auction/utilization checkpoint)

```mermaid
sequenceDiagram
    participant LS as Lending Service
    participant SC as Demo Prime Pool Smart contract
    participant ES as Provenance EventStream
    participant DB as Lending Service DB

    LS->>LS: START: All AuctionUpdateBorrowLoans completed

    LS->>DB: Query ALL active borrows for the pool
    DB->>LS: Return ALL active borrows for the pool

    LS->>DB: Query ALL active offers for the pool
    DB->>LS: Return ALL active offers for the pool

    LS->>SC: Query GetState() @ latest block height
    SC->>LS: Return Auction/Balances/ContractState

    LS->>LS: updateBalances(state.balances, borrows, offers)
    LS->>LS: updateAuctionForNewPeriod(state.auction) <br> (set auction.status=Pending, reset newBorrowIntAmt, etc.) <br> OR, reset all auction state for next period, and after updating State, we call SetAuctionStatus(Pending) after performing Sanity checks
    LS->>LS: Get updated_utilization_checkpoint from [4 Get Offer Utilization checkpoint + Auction Rate for next period]

    LS->>DB: Queue AuctionUpdateState(updated_balances, updated_auction, updated_utilization_checkpoint) Tx

    LS->>DB: Pull Tx broadcast data
    LS->>SC: Broadcast Wasm Execute AuctionUpdateState(updated_balances, updated_auction, updated_utilization_checkpoint)
    SC->>ES: Publish Completion Tx data <br> (TxHash/TxEvents)
    ES->>LS: Consume TxHash(es)
    LS->>DB: Persist TxHash(es). Mark Tx record as COMPLETE

```