The contract update for tokens is now deployed, and I wanted to give a break down for what happened.
The change was that stake balance reflects the active stake for determination of things like voting, or other contracts that are coming (e.g. mining), and before if you had to power down an amount that would be returned to you in multiple rounds (like Hive does once per week for 13 weeks), it would subtract the whole amount from the stake. Now the contract will only subtract what will be released in the next round.
Deployment Issues and Fix
Unfortunately, I missed a fairly obvious situation in hindsight where people were able to unstake the amount that was not subtracted repeatedly. The ironic part is that I had handled it properly for the delegate action, and just forgot to add it to the unstake action.
First thing was to close the hole by applying the validation to unstake. That was quickly added and deployed.
Then, we identified all unstake operations that took place since deployment and until we closed the hole, and forcefully canceled the unstake operation, via a one time contract update. This restored the stake balances to how they were before the unstake.
You can see the list of the unstakes that were cancelled here:
A quick comment about this contract update actions. There will be complaints about centralization, but I should like to remind people that this situation can occur on other smart contract platforms as well, as contracts are upgradeable in this way. All of the actions done during this time were following the rules of the sidechain.
So because of the update, if you are unstaking in multiple transactions, your stake balance will include some portion of those unstakes. Let's just do a simple example.
If I have 100 staked in LEO, and start unstaking 40 of it, I will have 90 staked LEO and 40 LEO pending unstake in the reported balances. LEO unstakes in 4 rounds, 1 week per round, so 1/4 would be subtracted immediately.
After one week, 10 LEO is released, and the next round starts. I then have 80 staked LEO, 10 liquid LEO, and 30 LEO pending unstake.
A separate table containing pending unstakes records details about the pending unstakes, showing how much the original unstake amount was, how many rounds are left, and how much is left to release.
At this time, the amount available to stake or delegate is 60 LEO, even though my balance reports 90.
The current state of API is not ideal, but to get the amount that you can unstake, you have to look through your pending unstakes and look at how much of your reported stake is locked in an existing unstake.
Also, I want to apologise for the inconvenience and confusion this has caused people. I understand that this is a jarring change, but I think it will allow a more consistent overall experience as far as stake goes. For example, if you are using the market maker contract with staking requirements, you can now benefit from this change as you can safely unstake (and then cancel later) your whole balance and still satisfy requirements with some of the stake that is powering down.
The stake reported also matches what scotbot uses, and can lead to further improvements in e.g. moving the voting contract, or implementing the new mining contract which was also released deployed. More information will come about mining in a future post.
Thanks all for your patience in this matter. Please let me know if you have further questions.