Rings is an implementation of MTG and a parachain of Mixin network.
- The user transfers a payment(UTXO) that carries business data to the Mixin network.
- Rings syncs the outputs(UTXO) by parsing the business data(in output.memo)
- Rings dispatchs the business action(included in business data) and processes each action(supply, borrow...)
In MTG system, There are two main roles, one is Payee, and the another is cashier, All business logic is implemented based on these two roles.
-
Payeereceiving the outputs(transactions), decoding the business data fromOutput.Memo, dispatchingactions
-
Supply, Suppose users supply the underlying tokenETHand gain the equity tokencETH
-
Pledge, Suppose users pledge the equity tokencETH, meains that users should paycETHto the Rings system
-
Unpledge, Suppose users unpledge the equity tokencETH, meains that users should pay some gasCNBand will get the equity tokencETHback
-
Redeem, Suppose users redeem the underlying tokenETHfrom the system, means that users should pay equity tokencETHand whill get the quivalent underlying tokenETHback
-
Borrow, Suppose users need to borrow the underlying tokenUSDT, means that users should pay some gasCNBand will gain the expected underlying tokenUSDT
-
Repay, Suppose users repayUSDT, means that users payUSDTand the users' debt will be reduced
-
quick_pledge, Suppose users supply the underlying tokenETHand no equity tokencETHreturns to users
-
qick_redeem, Suppose users redeemETH, users only pay some gasCNB, and will get the underlying tokenETHback
-
quick_borrow, Suppose users can supplyETHorcETHand can borrowUSDTdirectory
-
Liquidation, Suppose User A has PledgedETHand BorrowedUSDT, once The liquidity of user A's account less than or equal zero, it can be liquidated by other users
-
Proposal actions, all governance work produces effects through proposal voting, the current proposals include these:marketfor creating market or updating marketopen-marketfor opening marketclose-marketfor closing marketallowlistwhether to allow liquidationadd-oracle-signeradd the price oracle signer that provides market pricerm-oracle-signerremove the price oracle signerwithdrawwithdraw the reserves from the market
---
|-cmd
|-config
|-deploy
|-docs
|-core
|-pkg
|-service
|-store
|-worker
|-handler
|-Dockerfile
|-Makefile
|-main.go
- cmd command entry, including start api server and worker and governance tools
- config default config directory
- docs project documents
- core directory of project's models
- pkg project packages that can be exported
- service directory of business codes
- store data repository(data may be stored in database or redis or memory cache)
- worker directory for jobs that processing data in background
- handler just for exported apis
- Dockerfile for deployment
- deploy store configs and tools of deployment
- main.go
- Makefile
# Fixed value : 1603382400
genesis: 1603382400
# time localtion
location: Asia/Shanghai
# data base config
db:
dialect: mysql
host: ~
read_host: ~
port: 3306
user: ~
password: ~
database: ~
location: Asia%2FShanghai
Debug: true
# mixin dapp config
dapp:
num: 7000103159
client_id: ~
session_id: ~
client_secret: ~
pin_token: ~
pin: ""
private_key: ~
# nodes group config
group:
# private key shared by all nodes, that generated by the command: ./compound keys --cipher ed25519
private_key: ~
# The private key used by the current node for user data signing
sign_key: ~
# administratories of thie node
admins:
- ~
- ~
- ~
# Node member
members:
- client_id: ~
# The public key used by the current node to verify the signature
verify_key: ~
threshold: 2
vote:
asset: 965e5c6e-434c-3fa9-b780-c50f43cd955c
amount: 0.00000001
Rest APIs exported for application layer, including:
/markets/all //response all markets
/transactions //response compound transactions
/price-requests // for price oracle calling
- cashier Processes the pending transfers. prepare for transfering a transaction to Mixin network.
- syncer Syncs the outputs(UTXO) from Mixin network.
- txsender Transfers raw transaction to Mixin network.
- spentsync syncs and updates the transfer state.
- priceoracle Fetches a price and put the price on the chain.
- payee processes outputs and dispatches business actions.
- borrow handles the borrow action event.
- supply handles the supply action event.
- pledge handles the pledge action event.
- unpledge handles the unpledge action event.
- redeem handles the redeem action event.
- repay handles the repay action event.
- liquidation handles the liquidation action event
- proposal handles and dispatches the proposal actions, include: adding market, updating market, closing or opening market, adding or removing allowlist, withdraw
- price handles the price protocal action event.
Close the market when the price of a certain market is abnormal.
- When the price of a market is maliciously attacked, managers have the right to execute the
close-marketorder and apply for a closed-market vote. If the request is approved, the market will be closed. - Trades are prohibited in closed markets.
- However, as long as there are closed markets, liquidation of all markets will be prohibited, because liquidation will affect the liquidity of all market accounts of users.
-
Interest rate model is The core implementation of compound protocol.
-
Borrow balance user borrow balance contains borrow principal and borrow interest.
balance = borrow.principal * market.borrow_index / borrow.interest_index -
Accrue interest Accruing interest only occurs when there is a behavior that causes changes in market transaction data, such as supply, borrow, pledge, unpledge, redeem, repay, price updating. And Only calculated once in the same block.
blockNumberPrior := market.BlockNumber
blockNum, e := s.blockSrv.GetBlock(ctx, time)
if e != nil {
return e
}
blockDelta := blockNum - blockNumberPrior
if blockDelta > 0 {
borrowRate, e := s.curBorrowRatePerBlockInternal(ctx, market)
if e != nil {
return e
}
if market.BorrowIndex.LessThanOrEqual(decimal.Zero) {
market.BorrowIndex = borrowRate
}
timesBorrowRate := borrowRate.Mul(decimal.NewFromInt(blockDelta))
interestAccumulated := market.TotalBorrows.Mul(timesBorrowRate)
totalBorrowsNew := interestAccumulated.Add(market.TotalBorrows)
totalReservesNew := interestAccumulated.Mul(market.ReserveFactor).Add(market.Reserves)
borrowIndexNew := market.BorrowIndex.Add(timesBorrowRate.Mul(market.BorrowIndex))
market.BlockNumber = blockNum
market.TotalBorrows = totalBorrowsNew.Truncate(16)
market.Reserves = totalReservesNew.Truncate(16)
market.BorrowIndex = borrowIndexNew.Truncate(16)
}



