Skip to content

Commit

Permalink
Adding SIP-6 and SIP-7 improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
hav-noms authored and jjgonecrypto committed Jul 15, 2019
1 parent 80eafc7 commit 8cab352
Show file tree
Hide file tree
Showing 13 changed files with 4,490 additions and 3,652 deletions.
19 changes: 19 additions & 0 deletions contracts/ExchangeRates.sol
Expand Up @@ -55,6 +55,9 @@ contract ExchangeRates is SelfDestructible {
// How long will the contract assume the rate of any asset is correct
uint public rateStalePeriod = 3 hours;

// Lock exchanges until price update complete
bool public priceUpdateLock = false;

// Each participating currency in the XDR basket is represented as a currency key with
// equal weighting.
// There are 5 participating currencies, so we'll declare that clearly.
Expand Down Expand Up @@ -177,6 +180,11 @@ contract ExchangeRates is SelfDestructible {
// Now update our XDR rate.
updateXDRRate(timeSent);
// If locked during a priceupdate then reset it
if (priceUpdateLock) {
priceUpdateLock = false;
}
return true;
}
Expand Down Expand Up @@ -293,6 +301,17 @@ contract ExchangeRates is SelfDestructible {
emit RateStalePeriodUpdated(rateStalePeriod);
}

/**
* @notice Set the the locked state for a priceUpdate call
* @param _priceUpdateLock lock boolean flag
*/
function setPriceUpdateLock(bool _priceUpdateLock)
external
onlyOracle
{
priceUpdateLock = _priceUpdateLock;
}

/**
* @notice Set an inverse price up for the currency key
* @param currencyKey The currency to update
Expand Down
86 changes: 67 additions & 19 deletions contracts/Synthetix.sol
Expand Up @@ -148,9 +148,13 @@ contract Synthetix is ExternStateToken {
SynthetixState public synthetixState;
SupplySchedule public supplySchedule;

bool private protectionCircuit = false;

string constant TOKEN_NAME = "Synthetix Network Token";
string constant TOKEN_SYMBOL = "SNX";
uint8 constant DECIMALS = 18;
bool public exchangeEnabled = true;

// ========== CONSTRUCTOR ==========

/**
Expand Down Expand Up @@ -189,6 +193,20 @@ contract Synthetix is ExternStateToken {
exchangeRates = _exchangeRates;
}

function setProtectionCircuit(bool _protectionCircuitIsActivated)
external
onlyOracle
{
protectionCircuit = _protectionCircuitIsActivated;
}

function setExchangeEnabled(bool _exchangeEnabled)
external
optionalProxy_onlyOwner
{
exchangeEnabled = _exchangeEnabled;
}

/**
* @notice Add an associated Synth contract to the Synthetix system
* @dev Only the contract owner may call this.
Expand Down Expand Up @@ -256,16 +274,9 @@ contract Synthetix is ExternStateToken {
function effectiveValue(bytes4 sourceCurrencyKey, uint sourceAmount, bytes4 destinationCurrencyKey)
public
view
rateNotStale(sourceCurrencyKey)
rateNotStale(destinationCurrencyKey)
returns (uint)
{
// If there's no change in the currency, then just return the amount they gave us
if (sourceCurrencyKey == destinationCurrencyKey) return sourceAmount;

// Calculate the effective value by going from source -> USD -> destination
return sourceAmount.multiplyDecimalRound(exchangeRates.rateForCurrency(sourceCurrencyKey))
.divideDecimalRound(exchangeRates.rateForCurrency(destinationCurrencyKey));
return exchangeRates.effectiveValue(sourceCurrencyKey, sourceAmount, destinationCurrencyKey);
}

/**
Expand Down Expand Up @@ -301,7 +312,7 @@ contract Synthetix is ExternStateToken {
* @notice Returns the currencyKeys of availableSynths for rate checking
*/
function availableCurrencyKeys()
internal
public
view
returns (bytes4[])
{
Expand Down Expand Up @@ -395,7 +406,7 @@ contract Synthetix is ExternStateToken {
* @param sourceCurrencyKey The source currency you wish to exchange from
* @param sourceAmount The amount, specified in UNIT of source currency you wish to exchange
* @param destinationCurrencyKey The destination currency you wish to obtain.
* @param destinationAddress Where the result should go. If this is address(0) then it sends back to the message sender.
* @param destinationAddress Deprecated. Will always send to messageSender
* @return Boolean that indicates whether the transfer succeeded or failed.
*/
function exchange(bytes4 sourceCurrencyKey, uint sourceAmount, bytes4 destinationCurrencyKey, address destinationAddress)
Expand All @@ -407,15 +418,24 @@ contract Synthetix is ExternStateToken {
require(sourceCurrencyKey != destinationCurrencyKey, "Exchange must use different synths");
require(sourceAmount > 0, "Zero amount");

// Pass it along, defaulting to the sender as the recipient.
return _internalExchange(
messageSender,
sourceCurrencyKey,
sourceAmount,
destinationCurrencyKey,
destinationAddress == address(0) ? messageSender : destinationAddress,
true // Charge fee on the exchange
);
// If protectionCircuit is true then we burn the synths through _internalLiquidation()
if (protectionCircuit) {
return _internalLiquidation(
messageSender,
sourceCurrencyKey,
sourceAmount
);
} else {
// Pass it along, defaulting to the sender as the recipient.
return _internalExchange(
messageSender,
sourceCurrencyKey,
sourceAmount,
destinationCurrencyKey,
messageSender,
true // Charge fee on the exchange
);
}
}

/**
Expand Down Expand Up @@ -516,6 +536,8 @@ contract Synthetix is ExternStateToken {
notFeeAddress(from)
returns (bool)
{
require(exchangeEnabled, "Exchanging is disabled");
require(!exchangeRates.priceUpdateLock(), "Price update lock");
require(destinationAddress != address(0), "Zero destination");
require(destinationAddress != address(this), "Synthetix is invalid destination");
require(destinationAddress != address(proxy), "Proxy is invalid destination");
Expand Down Expand Up @@ -560,6 +582,26 @@ contract Synthetix is ExternStateToken {
return true;
}

/**
* @notice Function that burns the amount sent during an exchange in case the protection circuit is activated
* @param from The address to move synth from
* @param sourceCurrencyKey source currency from.
* @param sourceAmount The amount, specified in UNIT of source currency.
* @return Boolean that indicates whether the transfer succeeded or failed.
*/
function _internalLiquidation(
address from,
bytes4 sourceCurrencyKey,
uint sourceAmount
)
internal
returns (bool)
{
// Burn the source amount
synths[sourceCurrencyKey].burn(from, sourceAmount);
return true;
}

/**
* @notice Function that registers new synth as they are isseud. Calculate delta to append to synthetixState.
* @dev Only internal calls from synthetix address.
Expand Down Expand Up @@ -972,6 +1014,12 @@ contract Synthetix is ExternStateToken {
_;
}

modifier onlyOracle
{
require(msg.sender == exchangeRates.oracle(), "Only the oracle can perform this action");
_;
}

// ========== EVENTS ==========
/* solium-disable */
event SynthExchange(address indexed account, bytes4 fromCurrencyKey, uint256 fromAmount, bytes4 toCurrencyKey, uint256 toAmount, address toAddress);
Expand Down

0 comments on commit 8cab352

Please sign in to comment.