# 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
```