Skip to content

Commit f5a55a3

Browse files
committed
Use perfect rebasing
1 parent 134f0a3 commit f5a55a3

File tree

1 file changed

+30
-38
lines changed

1 file changed

+30
-38
lines changed

contracts/contracts/token/OUSD.sol

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)