Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
263 commits
Select commit Hold shift + click to select a range
bf90954
Closing positions.
zyzek Nov 18, 2020
9c2e04f
Fees
zyzek Nov 18, 2020
0f0ce3b
Funding progress.
zyzek Nov 18, 2020
b1031ba
More details manager interface.
zyzek Nov 19, 2020
ad5f172
Deployable
zyzek Nov 19, 2020
bd6e2ec
Deployable
zyzek Nov 19, 2020
a140113
Deploy futures data contract
zyzek Nov 19, 2020
6f34d1b
Deployable
zyzek Nov 19, 2020
4c293e0
Fix function name.
zyzek Nov 19, 2020
9126660
Fix deploy bug.
zyzek Nov 19, 2020
3afd68c
Catch zero divisions.
zyzek Nov 19, 2020
de4954b
Futures market data utility progress (et alii).
zyzek Nov 20, 2020
726d386
Improved order submission logic.
zyzek Nov 21, 2020
037b3e4
Improved order submission logic.
zyzek Nov 21, 2020
43184f3
Liquidations
zyzek Nov 24, 2020
da94933
Update notes.
zyzek Nov 24, 2020
aa67ed2
Update internal contract requirement logic for Synth issuance.
zyzek Nov 25, 2020
ab0d4c4
Funding rate fixes.
zyzek Nov 26, 2020
faf44bc
Test release to kovan.
zyzek Nov 26, 2020
3d49fb5
Publish kovan-futures.
zyzek Nov 27, 2020
116fa29
Futures release as mainline kovan release on this branch.
zyzek Nov 27, 2020
4af10a1
Proxify futures market manager.
zyzek Nov 27, 2020
9bd6d94
Fix funding computation.
zyzek Nov 27, 2020
a7336e2
Add proxies to futures markets.
zyzek Nov 29, 2020
3eb763d
Market details into a struct, finalise proxy update, fix data contract.
zyzek Nov 30, 2020
1ee74f5
New kovan deployment.
zyzek Nov 30, 2020
ac54041
Fix event emission in futures markets.
zyzek Nov 30, 2020
94c6c37
Redeploy with fixed event sigs.
zyzek Dec 1, 2020
e68079b
Funding rate fix.
zyzek Dec 2, 2020
f4363f7
Funding rate fix.
zyzek Dec 2, 2020
7f91d84
New futures testnet contracts.
zyzek Dec 2, 2020
68b338a
Redeploy
zyzek Dec 2, 2020
e6b2866
days keyword instead of _SECONDS_PER_DAY constant.
zyzek Apr 13, 2021
aaabce7
Comment and remove unnecessary cast
zyzek Apr 13, 2021
522e35c
Move require into conditional to save gas.
zyzek Apr 13, 2021
ab9f0b1
Ensure liquidation price is accurate with funding.
zyzek Apr 13, 2021
8fb5ac8
Fix docstring typo
zyzek Apr 13, 2021
ec9a2d7
Liquidation price properly reports invalidity.
zyzek Apr 13, 2021
13afd10
Test that setters work.
zyzek Apr 13, 2021
ae7bcd6
Remove .only
zyzek Apr 13, 2021
b0e033a
Correct PnL calculations
zyzek Apr 13, 2021
d407410
Current leverage function
zyzek Apr 13, 2021
2889ecd
Apply delta to entry margin sum while realising profits/funding.
zyzek Apr 13, 2021
6e008ab
Test setters, leverage, liquidation price functionality.
zyzek Apr 13, 2021
29c1450
Fix a couple of broken tests.
zyzek Apr 14, 2021
05b0245
Test that new orders cancel existing ones.
zyzek Apr 14, 2021
8398528
Test cleanup
zyzek Apr 14, 2021
bc178c6
Cleanup some TODOs
zyzek Apr 14, 2021
0c2ab05
Examine funding rate with differing leverage on each side of the market.
zyzek Apr 14, 2021
7f6c052
PnL tests
zyzek Apr 14, 2021
3b52ce7
Remaining margin test scaffolds elements.
zyzek Apr 14, 2021
d6d9130
Funding sequence length function
zyzek Apr 14, 2021
23374cb
Remaining margin and price invalidity tests.
zyzek Apr 14, 2021
45a89d0
More complete liquidation price test when excluding funding.
zyzek Apr 14, 2021
3b59778
Functionalise pricing logic in futures market + tests.
zyzek Apr 16, 2021
3eb79aa
Correct futures market side indication function.
zyzek Apr 19, 2021
40c8c5e
Resolve outstanding edge cases in the futures order fee function.
zyzek Apr 19, 2021
027432e
Futures fee function tests when submitting orders with existing posit…
zyzek Apr 19, 2021
19661f9
Fix typo
zyzek Apr 19, 2021
c8dfbc8
Resolve name clashes in futures market contract.
zyzek Apr 19, 2021
0e09a1c
Test that proportional skew is properly updated when market size/skew…
zyzek Apr 20, 2021
7ac2618
Max funding rate calculation test scaffolds.
zyzek Apr 20, 2021
0d70cd7
Futures market debt test section.
zyzek Apr 20, 2021
a17a32d
Do not realise margins within transactions (aggregate debt computatio…
zyzek Apr 20, 2021
0e69a2b
Fix broken aggregate debt test.
zyzek Apr 20, 2021
f2b3c83
Ensure closing a position cancels open orders.
zyzek Apr 21, 2021
9fda4a8
Pending field removed from orders.
zyzek Apr 21, 2021
f6b8f38
Market data contract fix-up post refactor.
zyzek Apr 21, 2021
ea97215
Funding sequence recomputation test scaffolding.
zyzek Apr 21, 2021
e3bda60
Margin -> uint, leverage -> int.
zyzek Apr 21, 2021
b94c07c
Skip incomplete tests.
zyzek Apr 23, 2021
5173a30
Refactor funding and leverage related details.
zyzek Apr 23, 2021
d98f729
Market debt accounts for funding rate.
zyzek Apr 23, 2021
74aa81f
Convert futures to two-stage order flow.
zyzek Apr 29, 2021
77df3f8
Remove some TODOs from futures contract.
zyzek Apr 29, 2021
8a2c9e6
Add some comments to futures market.
zyzek Apr 29, 2021
3460b55
Merge branch 'develop' into futures-implementation
zyzek Apr 30, 2021
09fce63
Bring into line with develop + more tests
zyzek Apr 30, 2021
ad13e87
Modify liquidationPrice function for efficiency.
zyzek May 1, 2021
2230ee6
FuturesMarket liquidation price now correctly accounts for changes in…
zyzek May 1, 2021
7e7995d
Further futures liquidation tests.
zyzek May 4, 2021
f9867cb
Note that funding setters should recompute funding first.
zyzek May 4, 2021
eeaae03
Funding rate tests
zyzek May 6, 2021
f9bee21
Max market size constraints
zyzek May 7, 2021
4f2fd41
Fix funding rate test.
zyzek May 11, 2021
b0ba978
Convert from a single exchange fee to maker/taker.
zyzek May 17, 2021
3d5c7bf
Futures operations block on liquidation (#1270)
zyzek May 20, 2021
0f001c1
Futures market management tests (#1273)
zyzek May 20, 2021
7d86bc1
Merge branch 'develop' into futures-implementation
zyzek May 25, 2021
d22baed
Fractional leverage test. (#1296)
zyzek May 27, 2021
64da116
Hook up futures to system debt. (#1294)
zyzek May 28, 2021
970bd4f
Merge develop into futures-implementation (#1326)
liamzebedee Jun 15, 2021
ed0434d
deploy FuturesMarketData (#1347)
liamzebedee Jun 21, 2021
585d5d4
Small explanatory comment.
zyzek Jun 21, 2021
738201c
Fix doc link in signed safe decimal math library.
zyzek Jun 21, 2021
500b827
Futures market debt correction is internal. (#1318)
zyzek Jun 22, 2021
409bf76
Futures record fees properly (#1317)
zyzek Jun 24, 2021
5bf7000
Implement FuturesMarketSettings contract for storing the market param…
i-stam Jun 29, 2021
36c9be1
Fix deployment bug (#1376)
i-stam Jun 29, 2021
6c9fc44
Add a test for funding recomputation on setting updates. (#1377)
zyzek Jun 29, 2021
789c2b1
Futures order fee charged from margin (#1314)
zyzek Jun 29, 2021
ce0359d
Export local-ovm environment from "synthetix" (#1356)
liamzebedee Jun 30, 2021
20ebe0e
Merge develop into futures-implementation (#1372)
liamzebedee Jul 1, 2021
4863b89
Fix up deployment. (#1391)
zyzek Jul 2, 2021
6f8d315
Fix deployment bug.
zyzek Jul 5, 2021
a4b8cbb
Futures merge develop (#1399)
liamzebedee Jul 12, 2021
a42f1ef
Internal canLiquidate function no longer takes price invalidity.
zyzek Jul 19, 2021
266d726
Clean up initial comments.
zyzek Jul 19, 2021
ab442a6
Complete futures market interface.
zyzek Jul 19, 2021
c3423dd
Futures Market Settings v2 (#1404)
liamzebedee Jul 20, 2021
04805b9
Futures closure fee (#1417)
zyzek Jul 22, 2021
d33f9b2
kovan-ovm-futures (refactored) (#1400)
liamzebedee Jul 23, 2021
996da91
Add confirmation and liquidation booleans to futures position data. (…
zyzek Jul 26, 2021
7b8e067
add missing chainlink feeds to kovan-ovm-futures
liamzebedee Jul 27, 2021
0f157d1
re-run deployment with correct network set
liamzebedee Jul 27, 2021
31814f1
Add global futures settings to data contract. (#1431)
zyzek Jul 28, 2021
e6daf35
Futures markets respect fee reclamation. (#1436)
zyzek Jul 29, 2021
9869a0c
Fix merge history for futures-implementation (#1445)
liamzebedee Aug 6, 2021
0805799
Merge commit 'fa291a7' into futures-implementation
liamzebedee Aug 6, 2021
a4d63d7
Futures order slippage (#1446)
liamzebedee Aug 12, 2021
82657a4
canConfirmOrder respects max market size constraints + error manageme…
zyzek Aug 13, 2021
8c43683
Futures: Market deployment and management scripts (#1440)
liamzebedee Aug 16, 2021
bcfb93a
Richer Futures position and margin events (#1456)
zyzek Aug 16, 2021
9746450
Futures documentation (#1460)
zyzek Aug 16, 2021
61678c5
Dead code cleanup. (#1462)
zyzek Aug 18, 2021
dcc3341
Position ID, PositionOpened, PositionClosed added (#1461)
0xclem Aug 18, 2021
dad617c
Futures spot trades (#1477)
zyzek Aug 25, 2021
2779e8b
Futures position details (#1479)
liamzebedee Aug 29, 2021
3fe88a0
Futures accessible margin (#1484)
zyzek Aug 30, 2021
6c60813
emit sizeDelta with PositionModified event (#1485)
liamzebedee Aug 31, 2021
2ffa1be
Deploy kovan-ovm-futures v0.4.0 (Alpha) (#1487)
liamzebedee Aug 31, 2021
b4a1636
Fix futures position id management + tests. (#1492)
zyzek Sep 5, 2021
52295d2
up maxMarketValue
liamzebedee Oct 6, 2021
d89d767
redeploy again
liamzebedee Oct 8, 2021
5529545
Futures: merge develop (#1547)
artdgn Oct 13, 2021
e84f365
Update proportional skew funding calculation to use maxMarketValue an…
jacko125 Oct 13, 2021
819b240
add verified details for some (not all) contracts
liamzebedee Oct 13, 2021
f89c50a
Merge branch 'futures-implementation' of github.com:Synthetixio/synth…
liamzebedee Oct 13, 2021
a414d11
only run if CollateralShort exists
liamzebedee Oct 14, 2021
dc6135e
* Move "sources" into "sips"
liamzebedee Oct 14, 2021
1d64411
fix: disable WETH deployment on L2
liamzebedee Oct 14, 2021
cd913dc
deploy kovan-ovm-futures v0.5.0
liamzebedee Oct 14, 2021
5f79db1
add whitelist for transfering externstateToken (#1565)
jacko125 Oct 14, 2021
f753dac
Merge branch 'futures-implementation' of github.com:Synthetixio/synth…
liamzebedee Oct 14, 2021
999c8be
prepare-deploy kovan-ovm-futures v0.5.1
liamzebedee Oct 14, 2021
f684c6f
prepare-deploy 0.5.2
liamzebedee Oct 14, 2021
fb2a960
prepare-deploy 0.5.3
liamzebedee Oct 14, 2021
3f94636
deploy 0.5.3
liamzebedee Oct 14, 2021
b82f662
revert changes
liamzebedee Oct 14, 2021
03e6d8c
Deploy kovan-ovm-futures v0.5.0 (#1566)
liamzebedee Oct 14, 2021
7e7d1f8
add missing deployments to config.json so verify picks them up
liamzebedee Oct 14, 2021
6beec5f
verified
liamzebedee Oct 14, 2021
d131f92
prepare-deploy 0.5.4
liamzebedee Oct 14, 2021
1ae1644
deploy SynthsETH and SynthsUSD
liamzebedee Oct 14, 2021
e9a9a4d
Merge branch 'futures-implementation' of github.com:Synthetixio/synth…
liamzebedee Oct 14, 2021
fabc4ed
Merge branch 'deploy-kovan-ovm-futures-v0.5.0' into futures-implement…
liamzebedee Oct 14, 2021
cae6895
futures listen to system and synth suspensions (#1530)
artdgn Oct 17, 2021
12f6419
Deploy kovan-ovm-futures v0.6.0 (#1570)
liamzebedee Oct 18, 2021
5d46eab
fix url's to etherscan
liamzebedee Oct 18, 2021
916b31c
* revert max market value to higher amount
liamzebedee Oct 19, 2021
095d193
Exchange rates circuit breaker refactor (#1540)
artdgn Oct 25, 2021
6a1f7ee
add missing data in position modified events (#1580)
artdgn Nov 2, 2021
8defb47
Futures rename parameters (#1595)
artdgn Nov 5, 2021
e9eb1cd
Deploy kovan-ovm-futures v0.7.0 (#1589)
liamzebedee Nov 10, 2021
0cef80c
Update ops node commit to working version in `develop`
liamzebedee Nov 15, 2021
7fe8e19
Helper script to distribute SNX/sUSD to accounts on kovan-futures-ovm…
liamzebedee Nov 16, 2021
5cdbb23
Futures liquidation fee update (#1594)
artdgn Nov 16, 2021
d7b8c12
adding market debt explanation comments
artdgn Nov 17, 2021
c2481ae
Futures next price mechanism (#1609)
artdgn Dec 9, 2021
ef412c9
Futures remove closure fee and rounding (#1610)
artdgn Dec 9, 2021
767229c
reduce storage variables sizes for gas savings (#1614)
artdgn Dec 9, 2021
a82fb87
refactor views into mixin to reduce clutter (#1615)
artdgn Dec 9, 2021
d5e9d3c
rename circuit breaker contracts (#1629)
artdgn Dec 9, 2021
70775ee
add tests for debt cache when markets
artdgn Dec 14, 2021
60f3525
Merge branch 'develop' of github.com:Synthetixio/synthetix into futur…
jacko125 Dec 22, 2021
543bdbe
Merge branch 'futures-implementation' of github.com:Synthetixio/synth…
jacko125 Dec 22, 2021
d94ea7c
Fix contracts compiling after merge
jacko125 Dec 22, 2021
80f573b
Merge branch 'develop' of github.com:Synthetixio/synthetix into futur…
jacko125 Dec 22, 2021
286a1af
Remove LimitedTransferSynth
jacko125 Dec 22, 2021
34f85cf
Merge branch 'develop' into futures-implementation
jacko125 Jan 9, 2022
42ab876
Merge branch 'develop' of github.com:Synthetixio/synthetix into futur…
jacko125 Jan 11, 2022
2dd44f8
Merge branch 'futures-implementation' of github.com:Synthetixio/synth…
jacko125 Jan 11, 2022
3230d49
Implement interface funcs for BaseDebtCache, EmptyCollateralManager, …
jacko125 Jan 13, 2022
92effdb
deploy futures to kovan-ovm-futures and update configuration scripts
jacko125 Jan 18, 2022
8ad2130
Merge branch 'develop' into futures-implementation
artdgn Jan 19, 2022
32693f7
fix shadowing in empty futures market
artdgn Jan 19, 2022
efc7e88
fix circuit breaker tests
artdgn Jan 19, 2022
62737a7
remove deprecated setLastExchangeRateForSynth
artdgn Jan 19, 2022
239d5ae
update fund local accounts script
jacko125 Jan 20, 2022
d4b9809
Merge branch 'futures-implementation' of github.com:Synthetixio/synth…
jacko125 Jan 20, 2022
115cbcf
fix atomic exchange circuit breaker tests
artdgn Jan 20, 2022
25c5d18
fix market settings and manager tests
artdgn Jan 20, 2022
7da2757
fix status script and fund local accounts
jacko125 Jan 20, 2022
0b4d8d6
Take debt snapshot before funding local accounts (#1657)
0xjocke Jan 21, 2022
0296bc4
Merge branch 'futures-implementation' of https://github.com/Synthetix…
artdgn Jan 21, 2022
d9351f0
fix aggregators usage in futures, setup fixes
artdgn Jan 21, 2022
7d1e2c3
fix futures market test setup
artdgn Jan 21, 2022
b64ab0b
fix futures market data tests
artdgn Jan 21, 2022
515338c
fix next price test setup
artdgn Jan 21, 2022
76b9529
fix system settings tests
artdgn Jan 21, 2022
63923c2
fix integration tests failing to setup markets
artdgn Jan 21, 2022
4e08eaf
fix market debt calculation during setup
artdgn Jan 21, 2022
edf9d33
verify deployment
jacko125 Jan 24, 2022
7f345b2
Merge branch 'futures-implementation' of github.com:Synthetixio/synth…
jacko125 Jan 24, 2022
10743f7
fix market settings tests
artdgn Jan 25, 2022
d9d342c
fix futures market tests
artdgn Jan 25, 2022
c34927d
Futures merge 184 (#1672)
artdgn Jan 28, 2022
fb28528
Merge branch 'develop' into futures-implementation
artdgn Jan 28, 2022
038b886
Merge remote-tracking branch 'origin/develop' into futures-implementa…
artdgn Jan 28, 2022
de1f090
fix breaker merge test
artdgn Jan 28, 2022
8d0f088
try fix dual itnegration tests
artdgn Jan 31, 2022
2103cd5
Merge branch 'develop' into futures-implementation
artdgn Jan 31, 2022
77780f7
Merge branch 'develop' into futures-implementation
artdgn Feb 1, 2022
64de1c2
another attempt to fix dual integration tests
artdgn Feb 1, 2022
9a4b8a7
Revert "another attempt to fix dual integration tests"
artdgn Feb 1, 2022
addfca8
Revert "try fix dual itnegration tests"
artdgn Feb 1, 2022
73c69f4
Futures dynamic fee (#1673)
artdgn Feb 4, 2022
6b8947e
Futures size reduction (#1682)
artdgn Feb 9, 2022
cba430d
address preliminary audit comments (#1691)
artdgn Feb 9, 2022
c3e257f
Futures pausing (#1692)
artdgn Feb 9, 2022
f88c9f3
Merge remote-tracking branch 'origin/develop' into futures-implementa…
artdgn Feb 9, 2022
560bb84
Merge remote-tracking branch 'origin/develop' into futures-implementa…
artdgn Feb 10, 2022
0fe33c3
Updating mainnet-ovm feeds to new chainlink OCR (#1645)
jjgonecrypto Feb 14, 2022
1a36106
add moar releases (#1698)
barrasso Feb 14, 2022
d0a43a6
Polaris release 2.61 to mainnet ovm (#1699)
barrasso Feb 14, 2022
9af19c8
Prepublish step
Feb 14, 2022
1ea400e
2.61.0
Feb 14, 2022
7dc18fa
Fixing ABI anomaly for kovan-ovm for exchangeWithVirtual
jjgonecrypto Feb 16, 2022
d525b6c
Fixing ABI anomaly for kovan-ovm for exchangeWithVirtual
jjgonecrypto Feb 16, 2022
d2f3a13
2.61.1
Feb 16, 2022
7f53a88
AIP-202 - Upgrade supply schedule to use target ratio inflation amoun…
jacko125 Feb 18, 2022
8e0d37a
Hamal release v2.62 mainnet (#1706)
jacko125 Feb 19, 2022
73eb472
Prepublish step
Feb 19, 2022
98cc38a
2.62.0
Feb 19, 2022
cfb30ff
Fixing lint
jjgonecrypto Feb 19, 2022
65a9c7e
Merge branch 'develop' into futures-implementation
artdgn Feb 24, 2022
456f81a
Merge branch 'develop' into futures-implementation
artdgn Feb 24, 2022
59731f0
deploy new futuresMarkets with dynamic fees to kovan-ovm-futures
jacko125 Feb 25, 2022
8f29d1e
verify
jacko125 Feb 25, 2022
6413b66
Merge branch 'develop' into futures-implementation
artdgn Mar 1, 2022
63fa3f1
address minor audit issues
artdgn Mar 1, 2022
b41a4eb
deploy systemStatus
jacko125 Mar 2, 2022
e975d81
Merge branch 'futures-implementation' of github.com:Synthetixio/synth…
jacko125 Mar 2, 2022
8ab725f
release exchangeRates
jacko125 Mar 2, 2022
7caa059
dual integration test fix attempt
artdgn Mar 3, 2022
f665639
Futures single market pausing (#1711)
artdgn Mar 8, 2022
60fe55d
Futures support multiple markets for same asset (#1713)
artdgn Mar 9, 2022
87c7d29
Futures volume source fee methods (#1714)
artdgn Mar 9, 2022
527ef56
update releases json
artdgn Mar 9, 2022
c7157b1
revert unrelated contract changes
artdgn Mar 9, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 21 additions & 15 deletions contracts/BaseDebtCache.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,8 @@ import "./interfaces/IERC20.sol";
import "./interfaces/ICollateralManager.sol";
import "./interfaces/IEtherWrapper.sol";
import "./interfaces/IWrapperFactory.sol";
import "./interfaces/IFuturesMarketManager.sol";

//
// The debt cache (SIP-91) caches the global debt and the debt of each synth in the system.
// Debt is denominated by the synth supply multiplied by its current exchange rate.
//
// The cache can be invalidated when an exchange rate changes, and thereafter must be
// updated by performing a debt snapshot, which recomputes the global debt sum using
// current synth supplies and exchange rates. This is performed usually by a snapshot keeper.
//
// Some synths are backed by non-SNX collateral, such as sETH being backed by ETH
// held in the EtherWrapper (SIP-112). This debt is called "excluded debt" and is
// excluded from the global debt in `_cachedDebt`.
//
// https://docs.synthetix.io/contracts/source/contracts/debtcache
contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache {
using SafeMath for uint;
Expand All @@ -55,6 +44,7 @@ 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_FUTURESMARKETMANAGER = "FuturesMarketManager";
bytes32 private constant CONTRACT_WRAPPER_FACTORY = "WrapperFactory";

constructor(address _owner, address _resolver) public Owned(_owner) MixinSystemSettings(_resolver) {}
Expand All @@ -63,14 +53,15 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache {

function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {
bytes32[] memory existingAddresses = MixinSystemSettings.resolverAddressesRequired();
bytes32[] memory newAddresses = new bytes32[](7);
bytes32[] memory newAddresses = new bytes32[](8);
newAddresses[0] = CONTRACT_ISSUER;
newAddresses[1] = CONTRACT_EXCHANGER;
newAddresses[2] = CONTRACT_EXRATES;
newAddresses[3] = CONTRACT_SYSTEMSTATUS;
newAddresses[4] = CONTRACT_COLLATERALMANAGER;
newAddresses[5] = CONTRACT_WRAPPER_FACTORY;
newAddresses[6] = CONTRACT_ETHER_WRAPPER;
newAddresses[7] = CONTRACT_FUTURESMARKETMANAGER;
addresses = combineArrays(existingAddresses, newAddresses);
}

Expand Down Expand Up @@ -98,6 +89,10 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache {
return IEtherWrapper(requireAndGetAddress(CONTRACT_ETHER_WRAPPER));
}

function futuresMarketManager() internal view returns (IFuturesMarketManager) {
return IFuturesMarketManager(requireAndGetAddress(CONTRACT_FUTURESMARKETMANAGER));
}

function wrapperFactory() internal view returns (IWrapperFactory) {
return IWrapperFactory(requireAndGetAddress(CONTRACT_WRAPPER_FACTORY));
}
Expand Down Expand Up @@ -157,22 +152,25 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache {
view
returns (
uint[] memory snxIssuedDebts,
uint _futuresDebt,
uint _excludedDebt,
bool anyRateIsInvalid
)
{
(uint[] memory rates, bool isInvalid) = exchangeRates().ratesAndInvalidForCurrencies(currencyKeys);
uint[] memory values = _issuedSynthValues(currencyKeys, rates);
(uint excludedDebt, bool isAnyNonSnxDebtRateInvalid) = _totalNonSnxBackedDebt(currencyKeys, rates, isInvalid);
(uint futuresDebt, bool futuresDebtIsInvalid) = futuresMarketManager().totalDebt();

return (values, excludedDebt, isAnyNonSnxDebtRateInvalid);
return (values, futuresDebt, excludedDebt, isInvalid || futuresDebtIsInvalid || isAnyNonSnxDebtRateInvalid);
}

function currentSynthDebts(bytes32[] calldata currencyKeys)
external
view
returns (
uint[] memory debtValues,
uint futuresDebt,
uint excludedDebt,
bool anyRateIsInvalid
)
Expand Down Expand Up @@ -252,9 +250,15 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache {
for (uint i; i < numValues; i++) {
total = total.add(values[i]);
}

// Add in the debt accounted for by futures
(uint futuresDebt, bool futuresDebtIsInvalid) = futuresMarketManager().totalDebt();
total = total.add(futuresDebt);

// Ensure that if the excluded non-SNX debt exceeds SNX-backed debt, no overflow occurs
total = total < excludedDebt ? 0 : total.sub(excludedDebt);

return (total, isAnyNonSnxDebtRateInvalid);
return (total, isInvalid || futuresDebtIsInvalid || isAnyNonSnxDebtRateInvalid);
}

function currentDebt() external view returns (uint debt, bool anyRateIsInvalid) {
Expand Down Expand Up @@ -294,6 +298,8 @@ contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache {

function recordExcludedDebtChange(bytes32 currencyKey, int256 delta) external {}

function updateCachedsUSDDebt(int amount) external {}

/* ========== MODIFIERS ========== */

function _requireSystemActiveIfNotOwner() internal view {
Expand Down
9 changes: 7 additions & 2 deletions contracts/DebtCache.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ contract DebtCache is BaseDebtCache {
constructor(address _owner, address _resolver) public BaseDebtCache(_owner, _resolver) {}

bytes32 internal constant EXCLUDED_DEBT_KEY = "EXCLUDED_DEBT";
bytes32 internal constant FUTURES_DEBT_KEY = "FUTURES_DEBT";

/* ========== MUTATIVE FUNCTIONS ========== */

Expand All @@ -26,15 +27,19 @@ contract DebtCache is BaseDebtCache {

function takeDebtSnapshot() external requireSystemActiveIfNotOwner {
bytes32[] memory currencyKeys = issuer().availableCurrencyKeys();
(uint[] memory values, uint excludedDebt, bool isInvalid) = _currentSynthDebts(currencyKeys);
(uint[] memory values, uint futuresDebt, uint excludedDebt, bool isInvalid) = _currentSynthDebts(currencyKeys);

// The total SNX-backed debt is the debt of futures markets plus the debt of circulating synths.
uint snxCollateralDebt = futuresDebt;
_cachedSynthDebt[FUTURES_DEBT_KEY] = futuresDebt;
uint numValues = values.length;
uint snxCollateralDebt;
for (uint i; i < numValues; i++) {
uint value = values[i];
snxCollateralDebt = snxCollateralDebt.add(value);
_cachedSynthDebt[currencyKeys[i]] = value;
}

// Subtract out the excluded non-SNX backed debt from our total
_cachedSynthDebt[EXCLUDED_DEBT_KEY] = excludedDebt;
uint newDebt = snxCollateralDebt.floorsub(excludedDebt);
_cachedDebt = newDebt;
Expand Down
39 changes: 39 additions & 0 deletions contracts/EmptyFuturesMarketManager.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
pragma solidity ^0.5.16;

// Empty contract for ether collateral placeholder for OVM
// https://docs.synthetix.io/contracts/source/contracts/emptyethercollateral

import "./interfaces/IFuturesMarketManager.sol";

contract EmptyFuturesMarketManager is IFuturesMarketManager {
function markets(uint index, uint pageSize) external view returns (address[] memory) {
index;
pageSize;
address[] memory _markets;
return _markets;
}

function numMarkets() external view returns (uint) {
return 0;
}

function allMarkets() external view returns (address[] memory) {
address[] memory _markets;
return _markets;
}

function marketForKey(bytes32 marketKey) external view returns (address) {
marketKey;
return address(0);
}

function marketsForKeys(bytes32[] calldata marketKeys) external view returns (address[] memory) {
marketKeys;
address[] memory _markets;
return _markets;
}

function totalDebt() external view returns (uint debt, bool isInvalid) {
return (0, false);
}
}
209 changes: 209 additions & 0 deletions contracts/ExchangeCircuitBreaker.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
pragma solidity ^0.5.16;

// Inheritance
import "./Owned.sol";
import "./MixinResolver.sol";
import "./MixinSystemSettings.sol";
import "./interfaces/IExchangeCircuitBreaker.sol";

// Libraries
import "./SafeDecimalMath.sol";

// Internal references
import "./interfaces/ISynth.sol";
import "./interfaces/IIssuer.sol";
import "./interfaces/ISystemStatus.sol";
import "./interfaces/IExchangeRates.sol";
import "./Proxyable.sol";

/**
* Compares current exchange rate to previous, and suspends a synth if the
* difference is outside of deviation bounds.
* Stores last "good" rate for each synth on each invocation.
* Inteded use is to use in combination with ExchangeRates on mutative exchange-like
* methods.
* Suspend functionality is public, resume functionality is controlled by owner.
*
* https://docs.synthetix.io/contracts/source/contracts/ExchangeCircuitBreaker
*/
contract ExchangeCircuitBreaker is Owned, MixinSystemSettings, IExchangeCircuitBreaker {
using SafeMath for uint;
using SafeDecimalMath for uint;

bytes32 public constant CONTRACT_NAME = "ExchangeCircuitBreaker";

// SIP-65: Decentralized circuit breaker
uint public constant CIRCUIT_BREAKER_SUSPENSION_REASON = 65;

// is internal to have lastExchangeRate getter in interface in solidity v0.5
// TODO: after upgrading solidity, switch to just public lastExchangeRate instead
// of maintaining this internal one
mapping(bytes32 => uint) internal _lastExchangeRate;

/* ========== ADDRESS RESOLVER CONFIGURATION ========== */

bytes32 private constant CONTRACT_SYSTEMSTATUS = "SystemStatus";
bytes32 private constant CONTRACT_EXRATES = "ExchangeRates";
bytes32 private constant CONTRACT_ISSUER = "Issuer";

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[](3);
newAddresses[0] = CONTRACT_SYSTEMSTATUS;
newAddresses[1] = CONTRACT_EXRATES;
newAddresses[2] = CONTRACT_ISSUER;
addresses = combineArrays(existingAddresses, newAddresses);
}

// Returns rate and its "invalid" state.
// Rate can be invalid either due to:
// 1. Returned as invalid from ExchangeRates - due to being stale, or flagged by oracle.
// 2, Out of deviation dounds w.r.t. to previously stored rate or if there is no
// valid stored rate, w.r.t. to previous 3 oracle rates.
function rateWithInvalid(bytes32 currencyKey) external view returns (uint, bool) {
(uint rate, bool invalid) = _exchangeRates().rateAndInvalid(currencyKey);
return (rate, invalid || _isRateOutOfBounds(currencyKey, rate));
}

function isDeviationAboveThreshold(uint base, uint comparison) external view returns (bool) {
return _isDeviationAboveThreshold(base, comparison);
}

function priceDeviationThresholdFactor() external view returns (uint) {
return getPriceDeviationThresholdFactor();
}

function lastExchangeRate(bytes32 currencyKey) external view returns (uint) {
return _lastExchangeRate[currencyKey];
}

function exchangeRates() public view returns (address) {
return requireAndGetAddress(CONTRACT_EXRATES);
}

/* ========== Internal views ========== */
function _exchangeRates() internal view returns (IExchangeRates) {
return IExchangeRates(requireAndGetAddress(CONTRACT_EXRATES));
}

function systemStatus() internal view returns (ISystemStatus) {
return ISystemStatus(requireAndGetAddress(CONTRACT_SYSTEMSTATUS));
}

function issuer() internal view returns (IIssuer) {
return IIssuer(requireAndGetAddress(CONTRACT_ISSUER));
}

/* ========== Mutating ========== */

/**
* Checks rate deviation from previous and its "invalid" oracle state (stale rate, of flagged by oracle).
* if it's valid and within deviation bounds, stores it and returns it and "false" (circuit not broken).
* If rate is invalid or outside of deviation bounds - doesn't store it, suspends the the synth, and returns
* last rate and "true" (circuit broken).
* Also, checks that system is not suspended currently, if it is - doesn't perform any checks, and
* returns last rate and "false" (not broken), to prevent synths suspensions during maintenance.
*/
function rateWithBreakCircuit(bytes32 currencyKey) external returns (uint lastValidRate, bool circuitBroken) {
// check system status
if (systemStatus().systemSuspended()) {
// if system is inactive this call has no effect, but will neither revert,
// nor persist new rate, nor suspend the synth - because the system is inactive.
// not reverting is needed for performing admin operations during system suspension
// e.g. purging synths that use some exchanging functionality
} else {
// get new rate and check oracle "invalid" state
(uint rate, bool invalid) = _exchangeRates().rateAndInvalid(currencyKey);
// check and suspend
if (invalid || _isRateOutOfBounds(currencyKey, rate)) {
// check synth exists, to prevent spamming settings for non existant synths
// gas savings: check here instead of every call, because synth existance is only
// important if we want to suspend it, and most regular calls don't need to incur
// the extra gas costs of another external call
require(issuer().synths(currencyKey) != ISynth(0), "No such synth");
systemStatus().suspendSynth(currencyKey, CIRCUIT_BREAKER_SUSPENSION_REASON);
circuitBroken = true;
} else {
// store the last passing rate
_lastExchangeRate[currencyKey] = rate;
}
}
return (_lastExchangeRate[currencyKey], circuitBroken);
}

/**
* SIP-139
* resets the stored value for _lastExchangeRate for multiple currencies to the latest rate
* can be used to un-suspend synths after a suspension happenned
* doesn't check deviations here, so believes that owner knows better
* emits LastRateOverriden
*/
function resetLastExchangeRate(bytes32[] calldata currencyKeys) external onlyOwner {
(uint[] memory rates, bool anyRateInvalid) = _exchangeRates().ratesAndInvalidForCurrencies(currencyKeys);

require(!anyRateInvalid, "Rates for given synths not valid");

for (uint i = 0; i < currencyKeys.length; i++) {
emit LastRateOverriden(currencyKeys[i], _lastExchangeRate[currencyKeys[i]], rates[i]);
_lastExchangeRate[currencyKeys[i]] = rates[i];
}
}

/* ========== INTERNAL FUNCTIONS ========== */

function _isDeviationAboveThreshold(uint base, uint comparison) internal view returns (bool) {
if (base == 0 || comparison == 0) {
return true;
}

uint factor;
if (comparison > base) {
factor = comparison.divideDecimal(base);
} else {
factor = base.divideDecimal(comparison);
}

return factor >= getPriceDeviationThresholdFactor();
}

/**
* Rate is invalid if:
* - is outside of deviation bounds relative to previous non-zero rate
* - (warm up case) if previous rate was 0 (init), gets last 4 rates from oracle, and checks
* if rate is outside of deviation w.r.t any of the 3 previous ones (excluding the last one).
*/
function _isRateOutOfBounds(bytes32 currencyKey, uint currentRate) internal view returns (bool) {
if (currentRate == 0) {
return true;
}

uint lastRateFromExchange = _lastExchangeRate[currencyKey];

if (lastRateFromExchange > 0) {
return _isDeviationAboveThreshold(lastRateFromExchange, currentRate);
}

// if no last exchange for this synth, then we need to look up last 3 rates (+1 for current rate)
(uint[] memory rates, ) = _exchangeRates().ratesAndUpdatedTimeForCurrencyLastNRounds(currencyKey, 4, 0);

// start at index 1 to ignore current rate
for (uint i = 1; i < rates.length; i++) {
// ignore any empty rates in the past (otherwise we will never be able to get validity)
if (rates[i] > 0 && _isDeviationAboveThreshold(rates[i], currentRate)) {
return true;
}
}

return false;
}

// ========== EVENTS ==========

// @notice signals that a the "last rate" was overriden by one of the admin methods
// with a value that didn't come direclty from the ExchangeRates.getRates methods
event LastRateOverriden(bytes32 currencyKey, uint256 previousRate, uint256 newRate);
}
2 changes: 1 addition & 1 deletion contracts/ExchangeRates.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import "./SafeDecimalMath.sol";
import "@chainlink/contracts-0.0.10/src/v0.5/interfaces/AggregatorV2V3Interface.sol";
// FlagsInterface from Chainlink addresses SIP-76
import "@chainlink/contracts-0.0.10/src/v0.5/interfaces/FlagsInterface.sol";
import "./interfaces/IExchanger.sol";
import "./interfaces/IExchangeCircuitBreaker.sol";

// https://docs.synthetix.io/contracts/source/contracts/exchangerates
contract ExchangeRates is Owned, MixinSystemSettings, IExchangeRates {
Expand Down
Loading