@@ -473,6 +473,44 @@ contract OUSD is Initializable, InitializableERC20Detailed, Governable {
473
473
return nonRebasingCreditsPerToken[_account] > 0 ;
474
474
}
475
475
476
+ /**
477
+ * @dev Ensures internal account for rebasing and non-rebasing credits and
478
+ * supply is updated following deployment of frozen yield change.
479
+ */
480
+ function _ensureMigrationToRebasing (address _account ) internal {
481
+ if (nonRebasingCreditsPerToken[_account] == 0 ) {
482
+ return ; // Account already is rebasing
483
+ }
484
+ // Precalculate old balance so that no partial
485
+ // account changes will affect it
486
+ uint256 oldBalance = balanceOf (msg .sender );
487
+
488
+ // Precalculate new credits, so that we avoid internal calls when
489
+ // atomically updating account.
490
+ // Convert balance into the same amount at the current exchange rate
491
+ uint256 newCreditBalance = _creditBalances[msg .sender ]
492
+ .mul (_rebasingCreditsPerToken)
493
+ .div (_creditsPerToken (msg .sender ));
494
+
495
+ // Atomicly update this account:
496
+ // Important that no internal calls happen during this.
497
+ // Remove pinned fixed credits per token
498
+ delete nonRebasingCreditsPerToken[msg .sender ];
499
+ // New credits
500
+ _creditBalances[msg .sender ] = newCreditBalance;
501
+
502
+ // Update global totals:
503
+ // Decrease non rebasing supply. We use the old balance, since that
504
+ // would have been the value that was originally used to adjust the
505
+ // nonRebasingSupply.
506
+ nonRebasingSupply = nonRebasingSupply.sub (oldBalance);
507
+ // Increase rebasing credits, totalSupply remains unchanged so no
508
+ // adjustment necessary
509
+ _rebasingCredits = _rebasingCredits.add (_creditBalances[msg .sender ]);
510
+
511
+ emit RebasingEnabled (msg .sender , oldBalance, _rebasingCreditsPerToken);
512
+ }
513
+
476
514
/**
477
515
* @dev Ensures internal account for rebasing and non-rebasing credits and
478
516
* supply is updated following deployment of frozen yield change.
@@ -529,36 +567,9 @@ contract OUSD is Initializable, InitializableERC20Detailed, Governable {
529
567
function rebaseOptIn () public nonReentrant {
530
568
require (_isNonRebasingAccount (msg .sender ), "Account has not opted out " );
531
569
532
- // Precalculate old balance so that no partial
533
- // account changes will affect it
534
- uint256 oldBalance = balanceOf (msg .sender );
535
-
536
- // Precalculate new credits, so that we avoid internal calls when
537
- // atomically updating account.
538
- // Convert balance into the same amount at the current exchange rate
539
- uint256 newCreditBalance = _creditBalances[msg .sender ]
540
- .mul (_rebasingCreditsPerToken)
541
- .div (_creditsPerToken (msg .sender ));
570
+ _ensureMigrationToRebasing (msg .sender );
542
571
543
- // Atomicly update this account:
544
- // Important that no internal calls happen during this.
545
- // Remove pinned fixed credits per token
546
- delete nonRebasingCreditsPerToken[msg .sender ];
547
- // New credits
548
- _creditBalances[msg .sender ] = newCreditBalance;
549
- // Mark explicitly opted in to rebasing
550
572
rebaseState[msg .sender ] = RebaseOptions.OptIn;
551
-
552
- // Update global totals:
553
- // Decrease non rebasing supply. We use the old balance, since that
554
- // would have been the value that was originally used to adjust the
555
- // nonRebasingSupply.
556
- nonRebasingSupply = nonRebasingSupply.sub (oldBalance);
557
- // Increase rebasing credits, totalSupply remains unchanged so no
558
- // adjustment necessary
559
- _rebasingCredits = _rebasingCredits.add (_creditBalances[msg .sender ]);
560
-
561
- emit RebasingEnabled (msg .sender , oldBalance, _rebasingCreditsPerToken);
562
573
}
563
574
564
575
/**
@@ -572,6 +583,22 @@ contract OUSD is Initializable, InitializableERC20Detailed, Governable {
572
583
rebaseState[msg .sender ] = RebaseOptions.OptOut;
573
584
}
574
585
586
+ /**
587
+ * @dev Governance action to allow a contract that does not support
588
+ * opting in to earn yield
589
+ */
590
+ function rebaseOptInByGovernance (address _account )
591
+ external
592
+ onlyGovernor
593
+ nonReentrant
594
+ {
595
+ require (_isNonRebasingAccount (_account), "Account has not opted out " );
596
+
597
+ _ensureMigrationToRebasing (_account);
598
+
599
+ rebaseState[_account] = RebaseOptions.OptIn;
600
+ }
601
+
575
602
/**
576
603
* @dev Modify the supply without minting new tokens. This uses a change in
577
604
* the exchange rate between "credits" and OUSD tokens to change balances.
0 commit comments