@@ -457,7 +457,7 @@ contract OUSD is Initializable, InitializableERC20Detailed, Governable {
457457 function _isNonRebasingAccount (address _account ) internal returns (bool ) {
458458 bool isContract = Address.isContract (_account);
459459 if (isContract && rebaseState[_account] == RebaseOptions.NotSet) {
460- _ensureRebasingMigration (_account);
460+ _ensureMigrationToNonRebasing (_account);
461461 }
462462 return nonRebasingCreditsPerToken[_account] > 0 ;
463463 }
@@ -466,30 +466,33 @@ contract OUSD is Initializable, InitializableERC20Detailed, Governable {
466466 * @dev Ensures internal account for rebasing and non-rebasing credits and
467467 * supply is updated following deployment of frozen yield change.
468468 */
469- function _ensureRebasingMigration (address _account ) internal {
470- if (nonRebasingCreditsPerToken[_account] == 0 ) {
471- if (_creditBalances[_account] == 0 ) {
472- // Since there is no existing balance, we can directly set to
473- // high resolution, and do not have to do any other bookkeeping
474- nonRebasingCreditsPerToken[_account] = 1e27 ;
475- } else {
476- // Migrate the existing account:
477- // It is important that balanceOf not be called inside updating
478- // account data, since it will give wrong answers if it does
479- // not have all an account's data in a consistent state. This
480- // isn't a problem in the current implimentation, since we only
481- // need to update nonRebasingCreditsPerToken.
482- // Set fixed credits per token for this account
483- nonRebasingCreditsPerToken[_account] = _rebasingCreditsPerToken;
484-
485- // Update global totals:
486- // Update non rebasing supply
487- nonRebasingSupply = nonRebasingSupply.add (balanceOf (_account));
488- // Update credit tallies
489- _rebasingCredits = _rebasingCredits.sub (
490- _creditBalances[_account]
491- );
492- }
469+ function _ensureMigrationToNonRebasing (address _account ) internal {
470+ if (nonRebasingCreditsPerToken[_account] != 0 ) {
471+ return ; // Account already is non-rebasing
472+ }
473+ if (_creditBalances[_account] == 0 ) {
474+ // Since there is no existing balance, we can directly set to
475+ // high resolution, and do not have to do any other bookkeeping
476+ nonRebasingCreditsPerToken[_account] = 1e27 ;
477+ } else {
478+ // Get old values, so we can use them unaffected by changes
479+ uint256 oldBalance = balanceOf (_account);
480+ uint256 oldCredits = _creditBalances[_account];
481+
482+ // Atomicly update account information:
483+ // It is important that balanceOf not be called inside updating
484+ // account data, since it will give wrong answers if it does
485+ // not have all an account's data in a consistent state.
486+ nonRebasingCreditsPerToken[_account] = 1e27 ;
487+ // difference between the 1e18 balance and the new 1e27 resolution
488+ _creditBalances[_account] = oldBalance * 1e9 ;
489+
490+ // Verify perfect acccount accounting update
491+ require (oldBalance == balanceOf (_account), "Balances do not match " );
492+
493+ // Update global totals:
494+ nonRebasingSupply = nonRebasingSupply.add (oldBalance);
495+ _rebasingCredits = _rebasingCredits.sub (oldCredits);
493496 }
494497 }
495498
@@ -516,7 +519,6 @@ contract OUSD is Initializable, InitializableERC20Detailed, Governable {
516519 _creditBalances[msg .sender ] = newCreditBalance;
517520 // Mark explicitly opted out of rebasing
518521 rebaseState[msg .sender ] = RebaseOptions.OptIn;
519-
520522
521523 // Update global totals:
522524 // Decrease non rebasing supply
@@ -532,19 +534,9 @@ contract OUSD is Initializable, InitializableERC20Detailed, Governable {
532534 function rebaseOptOut () public nonReentrant {
533535 require (! _isNonRebasingAccount (msg .sender ), "Account has not opted in " );
534536
535- // Atomicly update this account
536- // Important that no internal calls happen during this.
537- // Set fixed credits per token
538- nonRebasingCreditsPerToken[msg .sender ] = _rebasingCreditsPerToken;
539- // Mark explicitly opted out of rebasing
540- rebaseState[msg .sender ] = RebaseOptions.OptOut;
537+ _ensureMigrationToNonRebasing (msg .sender );
541538
542- // Update global totals:
543- // Increase non rebasing supply
544- nonRebasingSupply = nonRebasingSupply.add (balanceOf (msg .sender ));
545- // Decrease rebasing credits, total supply remains unchanged so no
546- // adjustment necessary
547- _rebasingCredits = _rebasingCredits.sub (_creditBalances[msg .sender ]);
539+ rebaseState[msg .sender ] = RebaseOptions.OptOut;
548540 }
549541
550542 /**
0 commit comments