diff --git a/contracts/contracts/token/OUSD.sol b/contracts/contracts/token/OUSD.sol index b3508a2497..38ea2fd787 100644 --- a/contracts/contracts/token/OUSD.sol +++ b/contracts/contracts/token/OUSD.sol @@ -404,31 +404,32 @@ contract OUSD is Initializable, InitializableERC20Detailed, Governable { } bool isNonRebasingAccount = _isNonRebasingAccount(_account); + // creditAmount is rounded down, so may remove fewer credits uint256 creditAmount = _amount.mulTruncate(_creditsPerToken(_account)); uint256 currentCredits = _creditBalances[_account]; - // Remove the credits, burning rounding errors - if ( - currentCredits == creditAmount || currentCredits - 1 == creditAmount - ) { - // Handle dust from rounding + + if (_amount == balanceOf(_account)) { + // Remove all account credits, burning rounding dust _creditBalances[_account] = 0; } else if (currentCredits > creditAmount) { - _creditBalances[_account] = _creditBalances[_account].sub( - creditAmount - ); + _creditBalances[_account] -= creditAmount; } else { revert("Remove exceeds balance"); } // Remove from the credit tallies and non-rebasing supply if (isNonRebasingAccount) { - nonRebasingSupply = nonRebasingSupply.sub(_amount); + nonRebasingSupply -= _amount; } else { - _rebasingCredits = _rebasingCredits.sub(creditAmount); + // Given that creditAmount could be rounded down, this could leave + // the contract with slightly more rebasing credits. This is the + // best side to round to, since this slows rebasing rather than + // speed it up + _rebasingCredits -= creditAmount; } - _totalSupply = _totalSupply.sub(_amount); + _totalSupply -= _amount; emit Transfer(_account, address(0), _amount); } diff --git a/contracts/test/vault/redeem.js b/contracts/test/vault/redeem.js index 4dbfba75d7..86fa042c2e 100644 --- a/contracts/test/vault/redeem.js +++ b/contracts/test/vault/redeem.js @@ -431,9 +431,7 @@ describe("Vault Redeem", function () { await dai.connect(anna).approve(vault.address, newDaiBalance); await vault.connect(anna).mint(dai.address, newDaiBalance, 0); await vault.connect(anna).redeemAll(0); - // FIXME - this is failing as a balance of 1 is being returned instead of 0 - // Tracking issue https://github.com/OriginProtocol/origin-dollar/issues/1495 - // await expect(anna).has.a.balanceOf("0.00", ousd); + await expect(anna).has.a.balanceOf("0.00", ousd); }); it("Should respect minimum unit amount argument in redeem", async () => {