Closed zorba80 closed 3 years ago
why rex need fund to deposit token, can we just call inline token transfer from user EOS balance when buy rex ?
Fund is used not only in buyrex but also in all actions that modify user's balance. It is also convenient for refunds and delayed sellrex orders which might be executed in actions pushed by another user.
Is anyone at Block One or anyone else at all who has worked on REX willing to go on the record either here in this issue or on the REX pull request and say in unambiguous terms whether this issue is in scope or out of scope to be addressed in REX:
It is possible for someone intent on voting for 1 BP to gain access to REX by creating a new account, making that new account a proxy, voting for 1 BP with that proxy account and then delegate their vote to that proxy account.
Yes, it is possible. However, we are leaning towards leaving the design as it currently is.
Thank you for clearing up the current stance on gaming access to REX via a proxy @zorba80
For my own understanding I'm trying to succinctly summarize from the REX pool balances and Processing REX sell orders stories above how rewards are calculated when the sellrex
/ close_rex_order
actions are called.
REX pool balances advises that the REX current exchange price is calculated as total_lendable
/ total_rex
. It also says that the proceeds of ramfee and namebids are added to total_lendable
and so are the CPU and NET loan payments (from the REX rentcpu
and rentnet
actions I assume).
It would appear that the actual rewards / proceeds calculation is performed here: https://github.com/EOSIO/eosio.contracts/blob/rex-2/eosio.system/src/rex.cpp#L499-L503
To recap, I would say that the rewards calculated at close_rex_order
call time are a function of a point in time calculation based on the REX pool balance where runtime accumulated ram trading fees and premium account name bids are a part of the REX pool total_lendable
balance.
Would you agree that this is a fair and accurate summary of how rewards will be calculated for a user selling REX tokens with the REX feature as it stands today ?
@jjssoftware, yes this is an accurate summary.
many thanks @zorba80, very much appreciated
Yes, it is possible. However, we are leaning towards leaving the design as it currently is.
@zorba80
Why leave this "design" in? We have a cabal that controls many sock puppets and you make it easier for them if you leave this in.
Why leave this "design" in? We have a cabal that controls many sock puppets and you make it easier for them if you leave this in.
@bt9 please suggest an alternative, I have yet to hear a suggestion that would reasonably work. Note https://github.com/EOSIO/eosio.contracts/issues/91#issuecomment-429488402.
@gleehokie your link to https://github.com/EOSIO/eosio.contracts/issues/91#issuecomment-429488402 identifies the one and only change that can work to fix the REX proxy loophole; proxy accounts having the ability to vote for low BP counts is a general EOSIO platform weakness and it just so happens that REX further highlights this weakness because it undermines one of the original measures of success for REX in no uncertain terms: the goal of improving voting engagement.
Ignoring this issue with the hope that the bar to create a proxy account to game access to REX is a bar too high for most to follow and that the system as it stands is "good enough" is naive and an irresponsible stance in my opinion.
I honestly don't want to turn this issue into a governance discussion but there's no escaping the fact that EOSIO is a blockchain with governance. Platform base layer governance exists to support the business rules built into EOSIO code and in symbiotic fashion the business rules built into the EOSIO code support platform base layer governance.
It's at times like these when a gap is identified that undermines the ability for that symbiotic governance <-> platform relationship to successfully work, the responsible and reasonable thing to do is to close that gap to strengthen the platform overall.
If we were to talk about the nuts and bolts of what's really needed to close this gap, voter_info
needs a is_proxy_active
indicator to describe whether an account is an active proxy which would be managed by how many BPs a proxy votes for and other touch points on the proxy in the system_contract would assert and maintain this value.
This change would reasonably work if it was undertaken and it is also a responsible change when considering the overall health and well being of the platform.
The questions that remain unanswered are whether block one is wiling to concede that proxy accounts having the ability to vote for low BP counts is a general EOSIO platform weakness and whether block one is willing to address this gap with a code fix or not.
Why leave this "design" in? We have a cabal that controls many sock puppets and you make it easier for them if you leave this in.
@bt9 please suggest an alternative, I have yet to hear a suggestion that would reasonably work. Note #91 (comment).
I think the requirement to vote for a minimum of 21 producers in order to use REX should be removed. There should be a requirement to vote, but not for how many. Trying to control voter behavior is not good practice. Let me explain myself.
Currently, the requirement allegedly accomplishes 2 things: (1) (indisputable) creates an incentive for token holders to vote, so it is expected to increase overall voter participation. (2) (disputable) results in a better spread of votes between producer candidates.
(1) is accomplished without the requirement to vote for at least 21. All we need is just a requirement to vote.
The problem I see with (2) is that it is too easy to circumvent even without the proxy problem. Users can vote for irrelevant candidates (ones that have too few votes). It's very easy to create new candidates. Furthermore, this requirement creates an incentive for strategic voting.
All of this is not good IMO because when a system rule can be circumvented too easily, what happens is that honest users follow the rule and dishonest users circumvent it. So it can be said that the system gives an edge to dishonest users, which also means that it will attract dishonest users. Ideally, I think we want to build an environment that attracts more honest users.
This is just my opinion on the matter, and I understand it is debatable. However, if in the end we decide that voting for a minimum of 21 is a good system rule, why not implement it as a general requirement to voting, not just REX? To me, this seems like a patch that doesn't address the problem at its core.
This is just my opinion on the matter, and I understand it is debatable. However, if in the end we decide that voting for a minimum of 21 is a good system rule, why not implement it as a general requirement to voting, not just REX? To me, this seems like a patch that doesn't address the problem at its core.
What is the problem at its core then?
The questions that remain unanswered are whether block one is wiling to concede that proxy accounts having the ability to vote for low BP counts is a general EOSIO platform weakness and whether block one is willing to address this gap with a code fix or not.
@jjssoftware should users not be allowed to vote as they see fit? Please expand on why you think proxy accounts (in particular) voting for low BP counts is a problem.
@jjssoftware should users not be allowed to vote as they see fit? Please expand on why you think proxy accounts (in particular) voting for low BP counts is a problem.
I find your question perplexing @gleehokie:
Perhaps you need to have a word with @bytemaster Daniel Larimer to ask him why the original REX proposal stated:
In order to buy REX an account must set and maintain a voting proxy or approve at least 21 block producers.
https://medium.com/@bytemaster/proposal-for-eos-resource-renting-rent-distribution-9afe8fb3883a
If voting for at least 21 block producers in the context of REX makes no sense to you, have a think about crusading for that requirement to be completely removed. One thing is certain: in the context of REX, allowing a user to vote for i.e. 1 BP via a proxy and also be rewarded for doing so goes directly against whatever original goal this requirement has.
I can offer an opinion why I believe that voting for a low number of BPs poses potential problems; it is healthy account voting behaviour to vote for a wide spread of block producers rather than voting for a small number of block producers because voting for many BPs promotes diversity in BP specialty skills and geographical decentralization.
Putting REX to one side, allowing proxies to vote for i.e. 1 BP is a general platform voter engagement weakening problem because in the worst case scenario, it promotes BP centralization by concentrating / funneling the voting power of many accounts to 1 BP. REX simply highlights this weakness further by not only continuing to allow it, but REX will also reward accounts for doing it.
Seems like it would break down the security model of DPoS if its anything less than 21.
Prior to the proper functioning of a Bancor market, initial values for the pools at either side of a connector must be initialized. Generally, this can be accomplished in a few ways but after review the most promising are:
While the bidding process is potentially more accurate, it is also requires a far more complex launch ceremony. As such, initial development will not support this option. This leaves initial “virtual” balances as the preferred method of bootstrapping a new instantiation of the REX.
In order to provide better documentation to future REX operators, some analysis will occur such that general guidelines for determining initial “virtual” balances is available.
In concert with bootstrapping concerns, there are still outstanding features which will attempt to prevent a complete reset of the market except in the rare event of all owners deciding to sell their REX shares. This will likely take the form of a “minimum”ratio of balances in the Bancor pools under which various measures, like delaying withdrawals, will exist to maintain a stable market maker and prevent the market from returning abruptly to its initial state.
The current implementation in GitHub requires liquid tokens in an internal REX balance prior to processing a buyrex
action. This presents a strong incentive for active voters to unstake tokens, wait for the refund to process, and then buy into the REX. During this period, the voting influence of these tokens is removed from the elections and this runs counter to the one of the goals of the REX to increase voter participation.
As a result, prior to release, a path for participation in the REX will be added which maintains voter influence during the transition. The exact form of this interaction is in development and will be announced as soon as it satisfies the requirements stated above as well as the requirements of staked token management necessary to prevent resource exploits.
In order to prevent possible price manipulation, the concept of maturity is being added to REX purchases. This does not affect the rewards for buying REX but will act as a vesting period over which newly purchased REX cannot be sold. Once outside this time period the given REX tokens can be sold at will. The REX maturity period is now implemented and currently set to 4 days. This value was chosen such that it is longer than the normal resource unstaking period and provides the market adequate time to react. Feedback on the time period is welcome.
In earlier discussions, the deposit of fees generated from other system level functions was contentious and it was stated that there would be a toggle for those fees prior to release. After analysis, it was determined that the best practice was not to provide a soft-switch which would impose RAM and CPU overhead during chain operations. Instead, operators who wish to deploy the REX without those inputs will have clear instructions on how to remove the code, prior to compilation of the contract, so that the deployed contracts are as lean as possible. The code currently in GitHub has been modified to support this removal, if desired, as cleanly as possible.
One of the goals of the REX is to increase voter participation on a public EOSIO-based blockchain. To achieve this goal, an invariant was established such that participants in the REX needed to EITHER vote for at least 21 block producer candidates OR delegate their voting influence to a registered proxy.
Discussions in the interim have questioned whether this invariant was sufficient to affect a number of different nuanced states in the general voting game-theory. After analysis, the development team has concluded that the current rules are sufficient to at least affect voter apathy. By requiring participants to overcome the initial barriers of entry, the expectation is that the REX will increase voter participation.
Qualitative expectations, such as increasing informed-voter participation OR decreasing active voters with malicious intent, is beyond the scope of a software process such as the REX as the ability to judge these qualities in a voter’s participation is outside of the scope and mandate of the reference system contracts for public EOSIO-based blockchains.
The development team respectfully requests that further discussion on this very contentious topic focus on a more measurable goal of decreasing voter apathy.
Any progress on this? When release?
If I buy REX using staked SYS tokens, then sell and withdraw all of it. So I will get SYS tokens immediately or need to wait for 72 hours?
@wuyahuang When you buy REX, whether using staked or liquid SYS tokens, you need to wait for 4 days (counting from the end of the day UTC) before you can sell it.
@bitcoiners This has been implemented. It's now in the testing phase and deployed on testnets.
how does users can inquire that how many CPU/NET do they rent from REX? there is no api or something else,right?
only way inquire the table cpuloan use:
jeos get table eosio eosio cpuloan
but on testnet or main-net in the fututre,there will be many accounts info,how can you filter your appointed account info?
cleos -u https://jungle.eosio.cr:443 get table eosio eosio cpuloan --key-type 'name' --index '2' -L strarteosfee -U redtestpeng3
it can not filter any info, may you guys help me ,thank you.
./cleos --url https://jungle2.cryptolions.io get table eosio eosio cpuloan --index 3 --key-type name -L strarteosfee -U strarteosfee
Can I reduce or remove rex maturities for testing sellrex command?
You can set num_of_maturity_buckets = 0 in https://github.com/EOSIO/eosio.contracts/blob/e3a33325826217c7ca1f33a0f8c16b725328e627/contracts/eosio.system/src/rex.cpp#L795
REX Implementation
This issue describes the EOSIO resource exchange (REX) implementation details. For the mathematical details of the Bancor algorithm used in REX, please see this article. In the following, we use
SYS
to represent the core token of an EOSIO based blockchain.User REX funds
For REX related actions, a user needs to create a REX fund and deposit SYS tokens into the fund.
deposit
action, when called for the first time, creates arex_fund
record for the user and sets the balance to the passed SYS amount. Subsequentdeposit
calls add the passed amount to rex_fund'sbalance
field. An inline tokentransfer
from user's SYS balance is executed. All REX expenses and proceeds are taken out of or added torex_fund
, with one exception being the actionunstaketorex
which allows buying REX with staked tokens.withdraw
action allows a user to take SYS tokens out ofrex_fund
. An inline tokentransfer
to user's SYS balance is executed.REX pool balances
REX pool represents the global state of the REX system. It comprises multiple balances:
total_lendable
is the total SYS value of the REX pool. It's the sum of all payments coming from buying REX actions, all CPU and Network loan fees, and RAM trading fees and name auction proceeds (if these system fees are channeled to REX).total_rex
represents the total number of REX tokens. It is incremented (decremented) upon buying (selling) REX. At any point in time, the value of a REX token is given bytotal_lendable/total_rex
. CPU and Network loan payments are added tototal_lendable
thus increasing the value of a REX token and providing more SYS tokens for renting, and similarly for the system fees mentioned above.total_unlent
represents the portion oftotal_lendable
that is available for renting, whereastotal_lent
represents portion tied in outstanding loans. By definition,total_lendable = total_unlent + total_lent
.total_rent
is a virtual balance. The initial value of this balance must be strictly positive. This initial value is determined based on an estimate of the expected SYS to be available shortly after deployment, so that renting costs are similar to other markets. The balancestotal_rent
andtotal_unlent
are the two connectors of the Bancor algorithm which determines CPU and Network renting price. The details are available here.Buying REX with liquid tokens
As the name suggests, the action
buyrex
allows a user to buy REX tokens in exchange for a provided number of SYS tokens (let's call itpayment
). It is the action that allows a users lend their SYS tokens. The number of issued REX tokens is calculated such that the ratiototal_lendable/total_rex
is the same before and after the action is executed. That is, this action leaves the value of a REX token unchanged. A voting requirement is imposed inbuyrex
: a user must have voted for a proxy or at least 21 producers.payment
is added to user's vote stake, and votes of corresponding producers are updated. SYS tokens used for the purchase are taken out of user'srex_fund
.Buying REX with staked tokens
A user can buy REX using staked tokens, without the need for unstaking to liquid tokens first, via
unstaketorex
action. The action takes as input the staked tokens owner account name (owner
), the account name to whom the tokens have been previously staked (receiver
), the amount to be unstaked from Network bandwidth (from_net
), and the amount to be unstaked from CPU bandwidth (from_cpu
). The amount of REX tokens rewarded in return forfrom_net + from_cpu
is calculated the same way as inbuyrex
. Same voting requirement also applies.owner
vote weight is updated to its current value, andfrom_net
andfrom_cpu
are subtracted from the resource limits ofreceiver
.REX maturities
A delay is imposed on selling REX tokens after they're purchased. Tokens bought cannot be sold until
4 days
after end of the day using UTC. Upon multiple purchases, tokens are accumulated into separate maturity buckets represented byrex_maturities
field of owner'srex_balance
. These buckets hold the amounts that can be sold within less than a day, 2 days, ..., 5 days. The amount of matured REX tokens that can be sold immediately is stored inmatured_rex
field ofrex_balance
. Note that this delay is imposed in order to give the renting market time to react. The actionconsolidate
allows the owner to consolidate all maturity buckets (not including REX tokens in the savings bucket described below) and matured REX into one bucket with maturity date of 4 days after the end of the day.REX savings bucket
In addition to maturity buckets described above, a REX owner can utilize a special bucket which we call the "savings bucket". REX held in this bucket does not mature and cannot be sold directly. Users can move already purchased REX from other buckets to their savings bucket at will using the action
mvtosavings
. This action moves REX out from the user's buckets as necessary starting with the bucket with furthest maturity date. In order to sell REX in the savings bucket, the user must first explicitly move tokens out of it using the actionmvfrsavings
which can be executed at any time. Themvfrsavings
action moves REX from the savings bucket to a bucket with a maturity date that is 4 days after the end of the day.Selling REX
sellrex
allows user to sell a given number of REX tokens in exchange for SYS. This is equivalent to unlending SYS tokens. If enough SYS tokens are available intotal_unlent
, the order is processed; otherwise the order is queued until the condition is satisfied. Sell order price is determined at processing time and not order creation time, assuming the two are different. The owner's vote stake is updated to current value of REX tokens held after the order is filled. Using actioncnclrexorder
, an owner can cancel a queued order any time before it's filled. The proceeds of selling REX are added to owner'srex_fund
.Processing REX sell orders
When a
sellrex
order can't be filled, it is added to a queue. That is, arex_order
record is created. Its fields areowner
which is the unique primary key,rex_requested
,order_time
,proceeds
,stake_change
, andis_open
. Initially we setrex_requested
to REX tokens to be sold,is_open = true
,proceeds = 0.0000 SYS
,stake_change = 0.0000 SYS
, andorder_time = current_time_point()
. When arex_order
is filled (functionfill_rex_order
), which can happen because some action provides enough unlent SYS tokens, we setis_open = false
, setproceeds
to the current exchange price ofrex_requested
, and calculate the change in vote stake and save it tostake_change
. We also update owner's REX balance,rex_balance -= rex_requested
, and setvote_stake
to current value ofrex_balance
.rex_pool
balances are updated accordingly. The order is then moved to the end of the queue. This is achieved by using a secondary key that is a function oforder_time
andis_open
. The rest ofrex_order
processing has to be executed in an action pushed byowner
. That involves transferingproceeds
to owner'srex_fund
, updating owner's vote weight by addingstake_change
(can be positive or negative) to vote stake (fieldstaked
invoter_info
), and then deleting the order. That is done by calling functionupdate_rex_account
which also updates the votes of corresponding producers. An owner can have only one openrex_order
. If the owner pushes a secondsellrex
action that can not be filled immediately, the requested REX tokens are added to therex_requested
field of the already existing order.REX loans
A user can rent CPU and Network resources on behalf of a
receiver
account usingrentcpu
andrentnet
actions in exchange for a specified SYSpayment
. These actions create arex_loan
record incpuloan
andnetloan
tables, respectively. The number of SYS tokens to be added toreceiver
CPU or Network resources (staked tokens denoted bytotal_staked
field of rex_loan) is calculated frompayment
using the current market price determined by Bancor algorithm. The two connectors of the algorithm aretotal_unlent
andtotal_rent
. Calculatedtotal_staked
is transferred fromtotal_unlent
tototal_lent
, andpayment
is added tototal_rent
. After the loan is created,payment
is added to REX pooltotal_lendable
andtotal_unlent
thus increasing value of REX token and increasing SYS tokens available for renting. Loan duration is 30 days. At the end of the duration, staked tokens (total_staked
) are subtracted fromreceiver
resource limits.total_staked
is moved back fromtotal_lent
tototal_unlent
, andtotal_rent
is updated accordingly using Bancor equation.Loan automatic renewal
In
rentnet
andrentcpu
, a user can provide an additional amount of SYS tokens that are added to the loan'sbalance
field. At expiration, a loan is renewed if it has enough funds, i.e.balance >= payment
, otherwise the loan is closed and the user is refunded any tokens remaining in the loan's balance. If a loan is renewed,total_staked
is recalculated using current market price andreceiver
resource limits are updated to reflect that. REX pool balances are updated as well. A loan owner can fund a loan, identified byloan_num
, usingfundcpuloan
orfundnetloan
. The owner can also withdraw from a loan's balance usingdefcpuloan
ordefnetloan
.REX maintenance
In most REX actions, the function
runrex
is called. It processes a fixed number (set to 2) of unfilled REX sell orders, expired Network loans, and expired CPU loans. Processing REX orders and loans is described above. Any account can callrunrex
directly by pushing therexexec
action which takes as input the maximum number (max
) of orders, Network loans, and CPU loans to be processed. REX sell orders are given higher priority than loans. Which means that no new loans are created and no existing loans are renewed ifrex_order
queue is not empty. The actionupdaterex
updates an owner's vote stake to the current SYS value of their REX balance. It also updates the vote weights of producers that the owner has voted for. The actioncloserex
deletes an owner's records from REX tables and frees the used RAM. If the owner has a non-zero REX balance, the action fails; otherwise, the owner'srex_balance
entry is deleted. If the owner has no outstanding loans and a zerorex_fund
balance,rex_fund
entry is deleted.Voting requirements
In order to buy REX, an account must have voted for at least 21 producers or delegated their vote to a proxy. As long as an account holds any REX tokens, the condition must be satisfied.