parallel-finance / parallel

A decentralized lending & staking protocol built on top of the Polkadot ecosystem.
https://parallel.fi
GNU General Public License v3.0
119 stars 35 forks source link

Design fast_unstake #1331

Closed GopherJ closed 2 years ago

GopherJ commented 2 years ago

Option 1:

fn fast_unstake(liquid_amount: BalanceOf<T>, min_stake_amount: BalanceOf<T>)

fee should be around 0.6% + penalty 0.1%

GopherJ commented 2 years ago
  1. instant
  2. fee
  3. capital
GopherJ commented 2 years ago

Fast unstake using MatchingPool.total_stake_amount.free

Fast unstake using MM

  1. loans need to expose mint, collateral_asset, borrow, repay_borrow_all & repay_borrow, redeem
  2. loans need to expose get_account_liquidity so that staking knows how many can we still borrow
  3. staking need to mint as much as possible so that we can borrow

TBD

GopherJ commented 2 years ago
  1. collateral sKSM
  2. mint, collateral_asset, borrow => emode => borrow(100%)
  3. pay to unstaker
  4. wait 7 || 28
  5. withdraw_unbonded
  6. repay_borrow_all, redeem
GopherJ commented 2 years ago

MM

Helper function

  1. do_mint(supplier, asset_id, amount)
  2. do_borrow(borrower, asset_id, amount)
  3. do_collateral_asset(supplier, asset_id, enable: bool) => LS will need to handle DuplicatedOperation error
  4. do_repay_borrow(borrower, asset_id, amount)
  5. do_redeem(supplier, asset_id, amount)
  6. get_current_borrow_balance(borrower, asset_id)
  7. get_market_status(asset_id)

Operation

  1. add <DOT|KSM>/U market
  2. set collateral_factor as (1 - FastUnstakeFee) eg. FastUnstakeFee = (1.45 ** (28/365) - 1)
  3. set borrow_cap to 0
  4. feed the same price with DOT/KSM

Frontend

  1. hide <DOT|KSM>/U

LS

Config

LoansPalletId: Get\<PalletId>

Helper functions

Calls

unstake(Origin, liquid_amoun: BalanceOf, mode: MM | Matching | AMM)

amount = liquid_amount * exchangeRate * (1 - FastUnstakeFee)
unlock_amount = liquid_amount * exchangeRate
mint_amount = unlock_amount / collateral_factor
repay_amount = ?

Note:

amount < repay_amount < unlock_amount
  1. check if fast unstake, if yes then the following steps
  2. add unlock_amount to matching_pool.totalUnstakeAmount
  3. append unlock_amount to unlockings, key is LoansPalletId
  4. burn liquid_amount s<DOT|KSM> mint mint_amount <DOT|KSM>/U into module account
  5. mint unlock_amount <DOT|KSM>/U` in loans
  6. collateral_asset <DOT|KSM>/U` in loans and check error to avoid reverting
  7. borrow amount and pay to unstaker

claim_for

  1. check if unstaker is LoansPaletId, if yes then repay repay_amount then redeem mint_amount <DOT|KSM>/U and burn it

Difficulty

  1. how to calculate repay_amount in advance to avoid TooMuchRepay
yrong commented 2 years ago

yes, a little bit difficult to calc repay_amount. we may need some storage for( for whom at which block borrow how much DOT with DOT/U) and not mixed up with dot debt from other collaterals.

maybe we can derivate a special borrower account from some tuple structure like (borrower,block_number,dot_u_asset_id,amount) which is unique and diffrent from normal account and then repay_amount could be calculated with current current_borrow_balance without change