Closed lukestokes closed 4 years ago
The contract data always has supported saving the staked amount by a candidate via the locked_tokens
field on a candidate. Therefore I expect this issue is related more to the UI rather than the contract repo.
@dallasjohnson Sorry if I wasn't clear, I think the question was about if I have 10 liquid EOSDAC tokens and 100,000 staked tokens and I vote for a custodian, is my vote weight 10 or 100,010? Also, with that same 100,000 staked, if I transfer those 10 tokens out to a different account, am I still considered a member of the DAC with my staked tokens?
Ok, all votes are calculated based on the voting account balance. Staking is separated from you vote power. So if have 100000 liquid and 10 staked your vote power will be 100,000 not 100,010. On the second point you don’t need to stake to be a member of the dac and the only way to transfer those staked tokens is to unstake first so you have them back in your pool of 100,010 tokens. Then you can transfer wherever you like. Also keep in mind you cannot unstake until you have withdrawn as a candidate.
some candidates went out and bought exactly 35k tokens and then staked them to run for election, now they are no longer considered members until they get 0.0001 more eosdac tokens. i was thinking we could change the check for membership to include any tokens staked. voting might be more difficult
Afaik membership doesn’t care about your token balance you will just have no voting power. If anything it would be more useful to add the staked balance into someone’s vote power but that’s yet another table lookup on every transfer action so might bad for cpu usage.
I think we should move responsibility for staking to the token contract
Benefits are
Add the following actions to the token contract
stake(name account, asset quantity)
Will add an entry (or update existing one) to the stakes
table. Will send a stakeobsv
action to the custodian contract, or the vote weight contract if configured.
unstake(name account, asset quantity)
Will add an entry to the unstakes
table with the unstake time and amount set. Multiple entries are allowed per account. The unstake time is calculated based on the account's staketime
setting, if this is not set then it will fall back to the default time set in stakeconfig
. Will send a stakeobsv
action to the custodian contract, or the vote weight contract if configured.
staketime(name account, uint32_t unstake_time)
Will change the account's staketime
parameter in the staketimes
table. If the new value is less than the current value then the account must unstake all existing stakes (ie. the stake table must be empty for that user). If the value being set is less than the configured minimum value then it will fail. A deferred transaction will be sent to refund
.
stakeconfig(stake_config config, symbol token_symbol)
Updates the config which consists of staking_enabled
, default_time
, min_time
, action must have permission of authority account of DAC derived from the symbol.
refund(uint64_t unstake_id)
Will remove tokens from the unstaked
entry matching the unstake_id if the unstake time has passed. Then it will subtract those number of tokens from the stakes
table. This action can either be called by deferred transaction or manually if that fails.
Preventing staked transfers
If staking is enabled then the token contract will check staked balance when making a transfer and will assert if the amount being transferred is greater than the balance minus the amount staked.
Migration
eosDAC should install the new contract and enable staking with a 3 day unstake time. Then a new migratestake
action which will transfer the stakes back to the users along with a forcestake
action. This is a temporary action added to the token contract which will stake the tokens and require authority of the authority account.
@michaeljyeates Interesting idea and could help encapsulate more token related logic into one place. Just to clarify: with the stake
action you suggested that should add to an existing entry (if there is one) where would the stake release timestamp get saved then? Would that subsequent staking extend the initial stake timestamp out out for all staked tokens or would additional staked tokens adopt the initial stake timestamp (which may have already passed)?
It feels like if you can stake more than once then a ledger of stakes would be needed which would contain {"staker": "mrstaker", quantity": "5.0000 EOSDAC", "locked_until" : "6June2020" }
and then another simple table per user which could track the total staked amount used for vote_weight actions. which would be updated for each (un)stake action. Obviously this is pretty RAM hungry but each user may only have 1 entry for staking so it would most consuming for the required indices in the table to quickly access the required rows.
Yes, there is one stake entry per user and many potential unstake entries (but these will be short-lived)
Via Telegram
New staking design automatically takes care of this because all the balance is together in the token contract rather than being split across token and daccustodian contracts.