Skip to content

Commit eba2f83

Browse files
authored
Reduce redeem gas costs by 719K/$319 by removing unnecessary totalValues() (#588)
Massively reduce redeem gas costs by removing duplicated total value calculations
1 parent 8caf066 commit eba2f83

3 files changed

Lines changed: 30 additions & 17 deletions

File tree

contracts/contracts/mocks/MockVault.sol

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ pragma solidity 0.5.11;
22

33
import { VaultCore } from "../vault/VaultCore.sol";
44
import { VaultInitializer } from "../vault/VaultInitializer.sol";
5+
import "../utils/Helpers.sol";
56

67
contract MockVault is VaultCore, VaultInitializer {
78
uint256 storedTotalValue;
@@ -18,6 +19,21 @@ contract MockVault is VaultCore, VaultInitializer {
1819
return storedTotalValue;
1920
}
2021

22+
function _checkBalance(address _asset)
23+
internal
24+
view
25+
returns (uint256 balance)
26+
{
27+
// Avoids rounding errors by returning the total value
28+
// in a single currency
29+
if (allAssets[0] == _asset) {
30+
uint256 decimals = Helpers.getDecimals(_asset);
31+
return storedTotalValue.scaleBy(int8(decimals - 18));
32+
} else {
33+
return 0;
34+
}
35+
}
36+
2137
function setMaxSupplyDiff(uint256 _maxSupplyDiff) external onlyGovernor {
2238
maxSupplyDiff = _maxSupplyDiff;
2339
}

contracts/contracts/vault/VaultCore.sol

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,6 @@ contract VaultCore is VaultStorage {
159159
whenNotCapitalPaused
160160
nonReentrant
161161
{
162-
if (_amount > rebaseThreshold && !rebasePaused) {
163-
_rebase();
164-
}
165162
_redeem(_amount, _minimumUnitAmount);
166163
}
167164

@@ -173,14 +170,18 @@ contract VaultCore is VaultStorage {
173170
function _redeem(uint256 _amount, uint256 _minimumUnitAmount) internal {
174171
require(_amount > 0, "Amount must be greater than 0");
175172

176-
uint256 _totalSupply = oUSD.totalSupply();
177-
uint256 _backingValue = _totalValue();
173+
// Calculate redemption outputs
174+
(
175+
uint256[] memory outputs,
176+
uint256 _backingValue
177+
) = _calculateRedeemOutputs(_amount);
178178

179+
// Check that OUSD is backed by enough assets
180+
uint256 _totalSupply = oUSD.totalSupply();
179181
if (maxSupplyDiff > 0) {
180182
// Allow a max difference of maxSupplyDiff% between
181183
// backing assets value and OUSD total supply
182184
uint256 diff = _totalSupply.divPrecisely(_backingValue);
183-
184185
require(
185186
(diff > 1e18 ? diff.sub(1e18) : uint256(1e18).sub(diff)) <=
186187
maxSupplyDiff,
@@ -190,8 +191,6 @@ contract VaultCore is VaultStorage {
190191

191192
emit Redeem(msg.sender, _amount);
192193

193-
// Calculate redemption outputs
194-
uint256[] memory outputs = _calculateRedeemOutputs(_amount);
195194
// Send outputs
196195
for (uint256 i = 0; i < allAssets.length; i++) {
197196
if (outputs[i] == 0) continue;
@@ -248,11 +247,6 @@ contract VaultCore is VaultStorage {
248247
whenNotCapitalPaused
249248
nonReentrant
250249
{
251-
// Unfortunately we have to do balanceOf twice, the rebase may change
252-
// the account balance
253-
if (oUSD.balanceOf(msg.sender) > rebaseThreshold && !rebasePaused) {
254-
_rebase();
255-
}
256250
_redeem(oUSD.balanceOf(msg.sender), _minimumUnitAmount);
257251
}
258252

@@ -513,7 +507,11 @@ contract VaultCore is VaultStorage {
513507
view
514508
returns (uint256[] memory)
515509
{
516-
return _calculateRedeemOutputs(_amount);
510+
(
511+
uint256[] memory outputs,
512+
uint256 totalValue
513+
) = _calculateRedeemOutputs(_amount);
514+
return outputs;
517515
}
518516

519517
/**
@@ -524,7 +522,7 @@ contract VaultCore is VaultStorage {
524522
function _calculateRedeemOutputs(uint256 _amount)
525523
internal
526524
view
527-
returns (uint256[] memory outputs)
525+
returns (uint256[] memory outputs, uint256 totalBalance)
528526
{
529527
// We always give out coins in proportion to how many we have,
530528
// Now if all coins were the same value, this math would easy,
@@ -559,7 +557,6 @@ contract VaultCore is VaultStorage {
559557
uint256[] memory assetPrices = _getAssetPrices(true);
560558
uint256[] memory assetBalances = new uint256[](assetCount);
561559
uint256[] memory assetDecimals = new uint256[](assetCount);
562-
uint256 totalBalance = 0;
563560
uint256 totalOutputRatio = 0;
564561
outputs = new uint256[](assetCount);
565562

contracts/slither.db.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)