EOS REX security series: Playing with REX from the source code (II) (Released in 2019)
Knowledge about REX
Let’s review the following basic functions together:
1. Deposit: Change EOS to SEOS, also called reserve fund.
2. Withdraw: exchange SEOS back to EOS.
3. Buyrex: Deduct the corresponding share from the user’s reserve fund, which can be used to buy rex.
4. Sellrex: sell the REX that has been locked, and put the principal together with the proceeds into the user’s reserve account.
5. Unstaketorex: buy rex with the resources in the mortgage.
This article will focus on the details of two functions.
sellrex function
The implementation of the calculation details of processing the user’s lease of EOS resources to generate income is all in the sellrex function. The following is the specific implementation of the sellrex function.
First put aside the runrex function, which does not belong to the scope of this discussion.
The sellrex process is as follows:
1. After a series of checks, get the number of unlocked rex, and call fill_rex_order to get the user’s sell order.
2. The sell order carries the completion status of the order. This is a flag, which is divided into two statuses: success and failure. When the status is failure, enter the if condition above.
2.1. The order status is successful
When the order status is successful, the value of current_order.proceed is greater than 0. At this time, the income from selling rex will be transferred to the user’s reserve account through update_rex_account. Users can directly withdraw cash or continue to the next round of purchases.
2.2. The order status is failed
For example, when you go to a store to order a product, if the product is out of stock, the store will send you an order, which records who you are, how many products you want to buy, when you buy them, and other information. Just make up the goods for you. The same is true for REX. When a user sells rex, the user’s order will be suspended temporarily because the funds in the rex_pool are not enough to pay the user’s principal + income. This is the IOU issued by REX to you. When REX has sufficient funds, it will pay you back the money. When the sellrex fails, the IOU records the following information:
(1) Users who sell rex.
(2) The amount of rex to sell (recorded in the rex_requested field).
(3) The user’s income is 0 at this time, because rex has not been sold, and the income does not exist.
(4) Mortgage status, this mortgage status is due to the corresponding ticket rights that will be generated according to the quantity purchased during the buyrex.
(5) The time when this IOU was created.
The above is the complete explanation of sellrex, but there is still a question, why is there insufficient funds, and how to determine insufficient funds? These secrets are all inside fill_rex_order. The following is a detailed analysis of the fill_rex_order function.
fill_rex_order function
See what this function does starting at line 11:
1. First obtain the value of unlent_lower_bound, that is, the minimum amount of unlented EOS in the rex_pool. This field is equal to the total amount of resources borrowed by the user from rex_pool, in EOS.
2. Calculate the value of available_unlent. This value may be negative. Why? Suppose a scenario where you are an investment manager and you have a lot of investors’ money, and then you take out the investors’ money for lending to collect interest, then how much money do you have at this time? The answer is naturally: investor’s money — lending funds + lending income. REX is equivalent to this investment manager. Users can exchange a small amount of cost (EOS) for a large amount of loans (resources). At this time, the funds in REX’s fund pool become: user funds — rental amount + rental income . According to the previous description, the funds used for renting resources are always less than the funds rented out by the REX platform, that is to say, when the resources are continuously leased, the funds in the rex_pool are always decreasing (the system revenue is not discussed here) . If you think about this, you can understand why the value of available_unlent is negative. When the rented funds are greater than the current funds + income in rex_pool, this value will be negative.
3. Determine whether the income obtained by the rex sold by the user is less than the remaining funds in the rex_pool, which is equivalent to the investor wanting to return his own money. There are two situations at this time:
3.1. If the funds are insufficient, the order will be suspended. At this time, an IOU will be created by the sellrex function, which is the reason for the order failure.
3.2. If it is enough, subtract the funds recovered by the user from the rex_pool fund pool, update the relevant table fields, update the user’s rex_balance account, and deduct the corresponding rex unlock amount.
REX security analysis
In the original version of the rex contract, there is no check( pending_sell_order.amount <= bitr->matured_rex, “insufficient funds for current and scheduled orders”). What will this cause? We know that when the funds in the fund pool are not enough to pay for the sell order, all steps under the if judgment will be skipped, and the order will be suspended directly by the sellrex function. When it is insufficient, you can sell rex all the time, superimpose the rex amount of the pending order, until the fund pool has enough funds to pay, sell more rex than buy rex. However, this operation will still fail to sell, because when the user rex_balance is finally changed, due to the overflow detection that comes with the asset structure, it cannot be sold successfully. But this will make this order a bad debt. In this case, because there is an outstanding sellrex order, the entire REX system will stop functioning. What is the specific reason? The answer will be revealed in the next article.
REX is a huge system, so this article only roughly analyzes the basic functions of each function, and introduces the core income part of REX. If there are any errors in the article, please share with us. At the same time, this article is only for technical reference and does not constitute any investment advice. Investors should make rational investments on the basis of fully understanding the relevant risks.
About SlowMist
SlowMist is a blockchain security firm established in January 2018. The firm was started by a team with over ten years of network security experience to become a global force. Our goal is to make the blockchain ecosystem as secure as possible for everyone. We are now a renowned international blockchain security firm that has worked on various well-known projects such as Huobi, OKX, Binance, imToken, Crypto.com, Amber Group, Klaytn, EOS, 1inch, PancakeSwap, TUSD, Alpaca Finance, MultiChain, O3Swap, etc.
Website:
https://www.slowmist.com
Twitter:
https://twitter.com/SlowMist_Team
Github:
https://github.com/slowmist/