When dealing with large numbers truncation (or rounding) is necessary to work within the size limits of integers and floats. In staking, we decided to only use truncation (versus rounding up) to avoid the situation where users, over time, might receive slightly more FIO or SRPs over time thus creating a possibility of having less FIO than expected. With truncation, the theory is that slightly less FIO might be issued over time, but the amount is negligible and the extra would accumulate in the staking pool.
But, truncation also introduces interesting edge cases where the numbers “do not add up.” For example, in cases where a user stakes and unstakes tokens without any intervening awards or fees being added to the pool, there is the possibility that the user will receive fewer tokens than they staked, even though, in theory, the ROE has not changed.
In the example below, different interim numbers have been truncated to show the impact on staking 10 tokens and unstaking 5 tokens. The cells highlighted in yellow have been truncated and in these use cases the user receives fewer than 5 FIO upon unstaking.
In our contract we have an assertion that (sufsclaimed >= unstakeamount) which, in the case below, fails.