-
Notifications
You must be signed in to change notification settings - Fork 609
SIP-182 Wrapper Factory #1489
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SIP-182 Wrapper Factory #1489
Changes from all commits
6059132
c7f9a84
4fc47ec
64dc546
b2c5571
55fc210
5369678
56a9c72
fc5e171
7460d21
d61d750
72c1249
fc6167d
4d3ed73
1e7c4b2
586818d
db11994
3fe239e
5a23fc2
8aa3ff9
9d1a5e8
0d70923
34c2b7b
19c8bc4
d8e71b8
68fd43e
89389aa
3057c1a
4d04cd4
fac5931
d65f99b
f2fbc13
e160741
d147d8a
7017dd0
9192ea5
4f6e1b6
2b76dca
1f2847e
d41faf2
077b0e8
61a0fad
447401c
1fc0b87
66e944e
f52432a
5ddb558
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,7 @@ import "./interfaces/ISystemStatus.sol"; | |
| import "./interfaces/IERC20.sol"; | ||
| import "./interfaces/ICollateralManager.sol"; | ||
| import "./interfaces/IEtherWrapper.sol"; | ||
| import "./interfaces/IWrapperFactory.sol"; | ||
|
|
||
| // | ||
| // The debt cache (SIP-91) caches the global debt and the debt of each synth in the system. | ||
|
|
@@ -37,6 +38,7 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache { | |
|
|
||
| uint internal _cachedDebt; | ||
| mapping(bytes32 => uint) internal _cachedSynthDebt; | ||
| mapping(bytes32 => uint) internal _excludedIssuedDebt; | ||
| uint internal _cacheTimestamp; | ||
| bool internal _cacheInvalid = true; | ||
|
|
||
|
|
@@ -53,20 +55,22 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache { | |
| bytes32 private constant CONTRACT_SYSTEMSTATUS = "SystemStatus"; | ||
| bytes32 private constant CONTRACT_COLLATERALMANAGER = "CollateralManager"; | ||
| bytes32 private constant CONTRACT_ETHER_WRAPPER = "EtherWrapper"; | ||
| bytes32 private constant CONTRACT_WRAPPER_FACTORY = "WrapperFactory"; | ||
|
|
||
| constructor(address _owner, address _resolver) public Owned(_owner) MixinSystemSettings(_resolver) {} | ||
|
|
||
| /* ========== VIEWS ========== */ | ||
|
|
||
| function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { | ||
| bytes32[] memory existingAddresses = MixinSystemSettings.resolverAddressesRequired(); | ||
| bytes32[] memory newAddresses = new bytes32[](6); | ||
| bytes32[] memory newAddresses = new bytes32[](7); | ||
| newAddresses[0] = CONTRACT_ISSUER; | ||
| newAddresses[1] = CONTRACT_EXCHANGER; | ||
| newAddresses[2] = CONTRACT_EXRATES; | ||
| newAddresses[3] = CONTRACT_SYSTEMSTATUS; | ||
| newAddresses[4] = CONTRACT_COLLATERALMANAGER; | ||
| newAddresses[5] = CONTRACT_ETHER_WRAPPER; | ||
| newAddresses[5] = CONTRACT_WRAPPER_FACTORY; | ||
| newAddresses[6] = CONTRACT_ETHER_WRAPPER; | ||
| addresses = combineArrays(existingAddresses, newAddresses); | ||
| } | ||
|
|
||
|
|
@@ -94,6 +98,10 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache { | |
| return IEtherWrapper(requireAndGetAddress(CONTRACT_ETHER_WRAPPER)); | ||
| } | ||
|
|
||
| function wrapperFactory() internal view returns (IWrapperFactory) { | ||
| return IWrapperFactory(requireAndGetAddress(CONTRACT_WRAPPER_FACTORY)); | ||
| } | ||
|
|
||
| function debtSnapshotStaleTime() external view returns (uint) { | ||
| return getDebtSnapshotStaleTime(); | ||
| } | ||
|
|
@@ -125,7 +133,6 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache { | |
| return _cacheStale(_cacheTimestamp); | ||
| } | ||
|
|
||
| // Returns the USD-denominated supply of each synth in `currencyKeys`, according to `rates`. | ||
| function _issuedSynthValues(bytes32[] memory currencyKeys, uint[] memory rates) | ||
| internal | ||
| view | ||
|
|
@@ -156,11 +163,11 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache { | |
| { | ||
| (uint[] memory rates, bool isInvalid) = exchangeRates().ratesAndInvalidForCurrencies(currencyKeys); | ||
| uint[] memory values = _issuedSynthValues(currencyKeys, rates); | ||
| (uint excludedDebt, bool isAnyNonSnxDebtRateInvalid) = _totalNonSnxBackedDebt(); | ||
| return (values, excludedDebt, isInvalid || isAnyNonSnxDebtRateInvalid); | ||
| (uint excludedDebt, bool isAnyNonSnxDebtRateInvalid) = _totalNonSnxBackedDebt(currencyKeys, rates, isInvalid); | ||
|
|
||
| return (values, excludedDebt, isAnyNonSnxDebtRateInvalid); | ||
| } | ||
|
|
||
| // Returns the USD-denominated supply of each synth in `currencyKeys`, using current exchange rates. | ||
| function currentSynthDebts(bytes32[] calldata currencyKeys) | ||
| external | ||
| view | ||
|
|
@@ -186,24 +193,44 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache { | |
| return _cachedSynthDebts(currencyKeys); | ||
| } | ||
|
|
||
| function _totalNonSnxBackedDebt() internal view returns (uint excludedDebt, bool isInvalid) { | ||
| function _excludedIssuedDebts(bytes32[] memory currencyKeys) internal view returns (uint[] memory) { | ||
| uint numKeys = currencyKeys.length; | ||
| uint[] memory debts = new uint[](numKeys); | ||
| for (uint i = 0; i < numKeys; i++) { | ||
| debts[i] = _excludedIssuedDebt[currencyKeys[i]]; | ||
| } | ||
| return debts; | ||
| } | ||
|
|
||
| function excludedIssuedDebts(bytes32[] calldata currencyKeys) external view returns (uint[] memory excludedDebts) { | ||
| return _excludedIssuedDebts(currencyKeys); | ||
| } | ||
|
|
||
| // Returns the total sUSD debt backed by non-SNX collateral, excluding debts recorded with _excludedIssuedDebt | ||
| function totalNonSnxBackedDebt() external view returns (uint excludedDebt, bool isInvalid) { | ||
| bytes32[] memory currencyKeys = issuer().availableCurrencyKeys(); | ||
| (uint[] memory rates, bool ratesAreInvalid) = exchangeRates().ratesAndInvalidForCurrencies(currencyKeys); | ||
|
|
||
| return _totalNonSnxBackedDebt(currencyKeys, rates, ratesAreInvalid); | ||
| } | ||
|
|
||
| function _totalNonSnxBackedDebt(bytes32[] memory currencyKeys, uint[] memory rates, bool ratesAreInvalid) internal view returns (uint excludedDebt, bool isInvalid) { | ||
| // Calculate excluded debt. | ||
| // 1. MultiCollateral long debt + short debt. | ||
| (uint longValue, bool anyTotalLongRateIsInvalid) = collateralManager().totalLong(); | ||
| (uint shortValue, bool anyTotalShortRateIsInvalid) = collateralManager().totalShort(); | ||
| isInvalid = anyTotalLongRateIsInvalid || anyTotalShortRateIsInvalid; | ||
| isInvalid = ratesAreInvalid || anyTotalLongRateIsInvalid || anyTotalShortRateIsInvalid; | ||
| excludedDebt = longValue.add(shortValue); | ||
|
|
||
| // 2. EtherWrapper. | ||
| // Subtract sETH and sUSD issued by EtherWrapper. | ||
| excludedDebt = excludedDebt.add(etherWrapper().totalIssuedSynths()); | ||
|
|
||
| return (excludedDebt, isInvalid); | ||
| } | ||
| for (uint i = 0; i < currencyKeys.length; i++) { | ||
| excludedDebt = excludedDebt.add(_excludedIssuedDebt[currencyKeys[i]].multiplyDecimalRound(rates[i])); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dbeal-eth Why not track and update the delta for I don't see where else the individual This is what is currently used to store the excluded debt value |
||
| } | ||
|
|
||
| // Returns the total sUSD debt backed by non-SNX collateral. | ||
| function totalNonSnxBackedDebt() external view returns (uint excludedDebt, bool isInvalid) { | ||
| return _totalNonSnxBackedDebt(); | ||
| return (excludedDebt, isInvalid); | ||
| } | ||
|
|
||
| function _currentDebt() internal view returns (uint debt, bool anyRateIsInvalid) { | ||
|
|
@@ -212,7 +239,7 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache { | |
|
|
||
| // Sum all issued synth values based on their supply. | ||
| uint[] memory values = _issuedSynthValues(currencyKeys, rates); | ||
| (uint excludedDebt, bool isAnyNonSnxDebtRateInvalid) = _totalNonSnxBackedDebt(); | ||
| (uint excludedDebt, bool isAnyNonSnxDebtRateInvalid) = _totalNonSnxBackedDebt(currencyKeys, rates, isInvalid); | ||
|
|
||
| uint numValues = values.length; | ||
| uint total; | ||
|
|
@@ -221,10 +248,9 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache { | |
| } | ||
| total = total < excludedDebt ? 0 : total.sub(excludedDebt); | ||
|
|
||
| return (total, isInvalid || isAnyNonSnxDebtRateInvalid); | ||
| return (total, isAnyNonSnxDebtRateInvalid); | ||
| } | ||
|
|
||
| // Returns the current debt of the system, excluding non-SNX backed debt (eg. EtherWrapper). | ||
| function currentDebt() external view returns (uint debt, bool anyRateIsInvalid) { | ||
| return _currentDebt(); | ||
| } | ||
|
|
@@ -260,6 +286,8 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache { | |
|
|
||
| function takeDebtSnapshot() external {} | ||
|
|
||
| function recordExcludedDebtChange(bytes32 currencyKey, int256 delta) external {} | ||
|
|
||
| /* ========== MODIFIERS ========== */ | ||
|
|
||
| function _requireSystemActiveIfNotOwner() internal view { | ||
|
|
@@ -290,4 +318,18 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache { | |
| _onlyIssuerOrExchanger(); | ||
| _; | ||
| } | ||
|
|
||
| function _onlyDebtIssuer() internal view { | ||
| bool isWrapper = wrapperFactory().isWrapper(msg.sender); | ||
|
|
||
| // owner included for debugging and fixing in emergency situation | ||
| bool isOwner = msg.sender == owner; | ||
|
|
||
| require(isOwner || isWrapper, "Only debt issuers may call this"); | ||
| } | ||
|
|
||
| modifier onlyDebtIssuer() { | ||
| _onlyDebtIssuer(); | ||
| _; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,6 +70,14 @@ contract DebtCache is BaseDebtCache { | |
| _updateDebtCacheValidity(currentlyInvalid); | ||
| } | ||
|
|
||
| function recordExcludedDebtChange(bytes32 currencyKey, int256 delta) external onlyDebtIssuer { | ||
| int256 newExcludedDebt = int256(_excludedIssuedDebt[currencyKey]) + delta; | ||
|
|
||
| require(newExcludedDebt >= 0, "Excluded debt cannot become negative"); | ||
|
|
||
| _excludedIssuedDebt[currencyKey] = uint(newExcludedDebt); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dbeal-eth Do we want to update the debt cache
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. after discussion this will be reviewed and replaced if necessary before mainnet later this week
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As comment above, consider updating a single value to roll up |
||
| } | ||
|
|
||
| function updateCachedsUSDDebt(int amount) external onlyIssuer { | ||
| uint delta = SafeDecimalMath.abs(amount); | ||
| if (amount > 0) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.