Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 12 from a total of 12 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Exercise Options | 13397366 | 1133 days ago | IN | 0 ETH | 0.00471222 | ||||
Exercise Options | 13346373 | 1141 days ago | IN | 0 ETH | 0.00579575 | ||||
Exercise Options | 13346144 | 1141 days ago | IN | 0 ETH | 0.00894706 | ||||
Exercise Options | 13218210 | 1161 days ago | IN | 0 ETH | 0.01834292 | ||||
Exercise Options | 13134132 | 1174 days ago | IN | 0 ETH | 0.03205993 | ||||
Mint | 13119344 | 1177 days ago | IN | 0 ETH | 0.00887168 | ||||
Mint | 13113955 | 1177 days ago | IN | 0 ETH | 0.00866067 | ||||
Mint | 13113955 | 1177 days ago | IN | 0 ETH | 0.00758732 | ||||
Mint | 13113596 | 1177 days ago | IN | 0 ETH | 0.00931691 | ||||
Mint | 13070854 | 1184 days ago | IN | 0 ETH | 0.00709951 | ||||
Mint | 13068033 | 1185 days ago | IN | 0 ETH | 0.00416191 | ||||
Mint | 13066876 | 1185 days ago | IN | 0 ETH | 0.00472694 |
Latest 3 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
13064377 | 1185 days ago | Contract Creation | 0 ETH | |||
13064377 | 1185 days ago | Contract Creation | 0 ETH | |||
13064377 | 1185 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Minimal Proxy Contract for 0x7fda84e52ff1d4c4e0241c5917485616fdcfcece
Contract Name:
BinaryOptionMarketMastercopy
Compiler Version
v0.5.16+commit.9c3226ce
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.5.16; // Inheritance import "./BinaryOptionMarket.sol"; contract BinaryOptionMarketMastercopy is BinaryOptionMarket { constructor() public MinimalProxyFactory() OwnedWithInit() { // Freeze mastercopy on deployment so it can never be initialized with real arguments initialized = true; } }
pragma solidity ^0.5.16; // Inheritance import "synthetix-2.43.1/contracts/MinimalProxyFactory.sol"; import "./OwnedWithInit.sol"; import "./interfaces/IBinaryOptionMarket.sol"; import "./interfaces/IOracleInstance.sol"; // Libraries import "synthetix-2.43.1/contracts/SafeDecimalMath.sol"; // Internal references import "./BinaryOptionMarketManager.sol"; import "./BinaryOption.sol"; import "synthetix-2.43.1/contracts/interfaces/IExchangeRates.sol"; import "synthetix-2.43.1/contracts/interfaces/IERC20.sol"; import "synthetix-2.43.1/contracts/interfaces/IAddressResolver.sol"; contract BinaryOptionMarket is MinimalProxyFactory, OwnedWithInit, IBinaryOptionMarket { /* ========== LIBRARIES ========== */ using SafeMath for uint; using SafeDecimalMath for uint; /* ========== TYPES ========== */ struct Options { BinaryOption long; BinaryOption short; } struct Times { uint maturity; uint expiry; } struct OracleDetails { bytes32 key; uint strikePrice; uint finalPrice; bool customMarket; address iOracleInstanceAddress; } /* ========== STATE VARIABLES ========== */ Options public options; Times public times; OracleDetails public oracleDetails; BinaryOptionMarketManager.Fees public fees; IAddressResolver public resolver; IOracleInstance public iOracleInstance; bool public customMarket; // `deposited` tracks the sum of all deposits minus the withheld fees. // This must explicitly be kept, in case tokens are transferred to the contract directly. uint public deposited; uint public accumulatedFees; uint public initialMint; address public creator; bool public resolved; uint internal _feeMultiplier; /* ---------- Address Resolver Configuration ---------- */ bytes32 internal constant CONTRACT_EXRATES = "ExchangeRates"; bytes32 internal constant CONTRACT_SYNTHSUSD = "SynthsUSD"; /* ========== CONSTRUCTOR ========== */ bool public initialized = false; function initialize( address _owner, address _binaryOptionMastercopy, IAddressResolver _resolver, address _creator, bytes32 _oracleKey, uint _strikePrice, uint[2] calldata _times, // [maturity, expiry] uint _deposit, // sUSD deposit uint[2] calldata _fees, // [poolFee, creatorFee] bool _customMarket, address _iOracleInstanceAddress ) external { require(!initialized, "Binary Option Market already initialized"); initialized = true; initOwner(_owner); resolver = _resolver; creator = _creator; oracleDetails = OracleDetails(_oracleKey, _strikePrice, 0, _customMarket, _iOracleInstanceAddress); customMarket = _customMarket; iOracleInstance = IOracleInstance(_iOracleInstanceAddress); times = Times(_times[0], _times[1]); deposited = _deposit; initialMint = _deposit; (uint poolFee, uint creatorFee) = (_fees[0], _fees[1]); fees = BinaryOptionMarketManager.Fees(poolFee, creatorFee); _feeMultiplier = SafeDecimalMath.unit().sub(poolFee.add(creatorFee)); // Instantiate the options themselves options.long = BinaryOption(_cloneAsMinimalProxy(_binaryOptionMastercopy, "Could not create a Binary Option")); options.short = BinaryOption(_cloneAsMinimalProxy(_binaryOptionMastercopy, "Could not create a Binary Option")); // abi.encodePacked("sLONG: ", _oracleKey) // consider naming the option: sLongBTC>[email protected] options.long.initialize("Binary Option Long", "sLONG"); options.short.initialize("Binary Option Short", "sSHORT"); _mint(creator, initialMint); // Note: the ERC20 base contract does not have a constructor, so we do not have to worry // about initializing its state separately } /* ---------- External Contracts ---------- */ function _exchangeRates() internal view returns (IExchangeRates) { return IExchangeRates(resolver.requireAndGetAddress(CONTRACT_EXRATES, "ExchangeRates contract not found")); } function _sUSD() internal view returns (IERC20) { return IERC20(resolver.requireAndGetAddress(CONTRACT_SYNTHSUSD, "SynthsUSD contract not found")); } function _manager() internal view returns (BinaryOptionMarketManager) { return BinaryOptionMarketManager(owner); } /* ---------- Phases ---------- */ function _matured() internal view returns (bool) { return times.maturity < block.timestamp; } function _expired() internal view returns (bool) { return resolved && (times.expiry < block.timestamp || deposited == 0); } function phase() external view returns (Phase) { if (!_matured()) { return Phase.Trading; } if (!_expired()) { return Phase.Maturity; } return Phase.Expiry; } /* ---------- Market Resolution ---------- */ function _oraclePriceAndTimestamp() internal view returns (uint price, uint updatedAt) { return _exchangeRates().rateAndUpdatedTime(oracleDetails.key); } function oraclePriceAndTimestamp() external view returns (uint price, uint updatedAt) { return _oraclePriceAndTimestamp(); } function _isFreshPriceUpdateTime(uint timestamp) internal view returns (bool) { (uint maxOraclePriceAge, , ) = _manager().durations(); return (times.maturity.sub(maxOraclePriceAge)) <= timestamp; } function canResolve() public view returns (bool) { if (customMarket) { return !resolved && _matured() && iOracleInstance.resolvable(); } else { (, uint updatedAt) = _oraclePriceAndTimestamp(); return !resolved && _matured() && _isFreshPriceUpdateTime(updatedAt); } } function _result() internal view returns (Side) { if (customMarket) { return iOracleInstance.getOutcome() ? Side.Long : Side.Short; } else { uint price; if (resolved) { price = oracleDetails.finalPrice; } else { (price, ) = _oraclePriceAndTimestamp(); } return oracleDetails.strikePrice <= price ? Side.Long : Side.Short; } } function result() external view returns (Side) { return _result(); } /* ---------- Option Balances and Mints ---------- */ function _balancesOf(address account) internal view returns (uint long, uint short) { return (options.long.balanceOf(account), options.short.balanceOf(account)); } function balancesOf(address account) external view returns (uint long, uint short) { return _balancesOf(account); } function totalSupplies() external view returns (uint long, uint short) { return (options.long.totalSupply(), options.short.totalSupply()); } /* ---------- Utilities ---------- */ function _incrementDeposited(uint value) internal returns (uint _deposited) { _deposited = deposited.add(value); deposited = _deposited; _manager().incrementTotalDeposited(value); } function _decrementDeposited(uint value) internal returns (uint _deposited) { _deposited = deposited.sub(value); deposited = _deposited; _manager().decrementTotalDeposited(value); } function _requireManagerNotPaused() internal view { require(!_manager().paused(), "This action cannot be performed while the contract is paused"); } function requireUnpaused() external view { _requireManagerNotPaused(); } /* ========== MUTATIVE FUNCTIONS ========== */ /* ---------- Minting ---------- */ function mint(uint value) external duringMinting { if (value == 0) { return; } uint valueAfterFees = value.multiplyDecimalRound(_feeMultiplier); uint deductedFees = value.sub(valueAfterFees); accumulatedFees = accumulatedFees.add(deductedFees); _mint(msg.sender, valueAfterFees); _incrementDeposited(value); _manager().transferSusdTo(msg.sender, address(this), value); } function _mint(address minter, uint amount) internal { options.long.mint(minter, amount); options.short.mint(minter, amount); emit Mint(Side.Long, minter, amount); emit Mint(Side.Short, minter, amount); } /* ---------- Custom oracle configuration ---------- */ function setIOracleInstance(address _address) external onlyOwner {} /* ---------- Market Resolution ---------- */ function resolve() external onlyOwner afterMaturity managerNotPaused { require(canResolve(), "Can not resolve market"); (uint price, uint updatedAt) = _oraclePriceAndTimestamp(); if (!customMarket) { oracleDetails.finalPrice = price; } resolved = true; // Now remit any collected fees. // Since the constructor enforces that creatorFee + poolFee < 1, the balance // in the contract will be sufficient to cover these transfers. IERC20 sUSD = _sUSD(); uint totalFeesRatio = fees.poolFee.add(fees.creatorFee); uint poolFeesRatio = fees.poolFee.divideDecimalRound(totalFeesRatio); uint poolFees = poolFeesRatio.multiplyDecimalRound(accumulatedFees); uint creatorFees = accumulatedFees.sub(poolFees); _decrementDeposited(creatorFees.add(poolFees)); sUSD.transfer(_manager().feeAddress(), poolFees); sUSD.transfer(creator, creatorFees); emit MarketResolved(_result(), price, updatedAt, deposited, poolFees, creatorFees); } /* ---------- Claiming and Exercising Options ---------- */ function exerciseOptions() external afterMaturity returns (uint) { // The market must be resolved if it has not been. // the first one to exercise pays the gas fees. Might be worth splitting it up. if (!resolved) { _manager().resolveMarket(address(this)); } // If the account holds no options, revert. (uint longBalance, uint shortBalance) = _balancesOf(msg.sender); require(longBalance != 0 || shortBalance != 0, "Nothing to exercise"); // Each option only needs to be exercised if the account holds any of it. if (longBalance != 0) { options.long.exercise(msg.sender); } if (shortBalance != 0) { options.short.exercise(msg.sender); } // Only pay out the side that won. uint payout = (_result() == Side.Long) ? longBalance : shortBalance; emit OptionsExercised(msg.sender, payout); if (payout != 0) { _decrementDeposited(payout); _sUSD().transfer(msg.sender, payout); } return payout; } /* ---------- Market Expiry ---------- */ function _selfDestruct(address payable beneficiary) internal { uint _deposited = deposited; if (_deposited != 0) { _decrementDeposited(_deposited); } // Transfer the balance rather than the deposit value in case there are any synths left over // from direct transfers. IERC20 sUSD = _sUSD(); uint balance = sUSD.balanceOf(address(this)); if (balance != 0) { sUSD.transfer(beneficiary, balance); } // Destroy the option tokens before destroying the market itself. options.long.expire(beneficiary); options.short.expire(beneficiary); selfdestruct(beneficiary); } function expire(address payable beneficiary) external onlyOwner { require(_expired(), "Unexpired options remaining"); _selfDestruct(beneficiary); } /* ========== MODIFIERS ========== */ modifier duringMinting() { require(!_matured(), "Minting inactive"); _; } modifier afterMaturity() { require(_matured(), "Not yet mature"); _; } modifier managerNotPaused() { _requireManagerNotPaused(); _; } /* ========== EVENTS ========== */ event Mint(Side side, address indexed account, uint value); event MarketResolved( Side result, uint oraclePrice, uint oracleTimestamp, uint deposited, uint poolFees, uint creatorFees ); event OptionsExercised(address indexed account, uint value); }
pragma solidity ^0.5.16; // https://docs.synthetix.io/contracts/source/contracts/minimalproxyfactory contract MinimalProxyFactory { function _cloneAsMinimalProxy(address _base, string memory _revertMsg) internal returns (address clone) { bytes memory createData = _generateMinimalProxyCreateData(_base); assembly { clone := create( 0, // no value add(createData, 0x20), // data 55 // data is always 55 bytes (10 constructor + 45 code) ) } // If CREATE fails for some reason, address(0) is returned require(clone != address(0), _revertMsg); } function _generateMinimalProxyCreateData(address _base) internal pure returns (bytes memory) { return abi.encodePacked( //---- constructor ----- bytes10(0x3d602d80600a3d3981f3), //---- proxy code ----- bytes10(0x363d3d373d3d3d363d73), _base, bytes15(0x5af43d82803e903d91602b57fd5bf3) ); } }
pragma solidity ^0.5.16; contract OwnedWithInit { address public owner; address public nominatedOwner; constructor() public {} function initOwner(address _owner) internal { require(owner == address(0), "Init can only be called when owner is 0"); owner = _owner; emit OwnerChanged(address(0), _owner); } function nominateNewOwner(address _owner) external onlyOwner { nominatedOwner = _owner; emit OwnerNominated(_owner); } function acceptOwnership() external { require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership"); emit OwnerChanged(owner, nominatedOwner); owner = nominatedOwner; nominatedOwner = address(0); } modifier onlyOwner { _onlyOwner(); _; } function _onlyOwner() private view { require(msg.sender == owner, "Only the contract owner may perform this action"); } event OwnerNominated(address newOwner); event OwnerChanged(address oldOwner, address newOwner); }
pragma solidity >=0.4.24; import "../interfaces/IBinaryOptionMarketManager.sol"; import "../interfaces/IBinaryOption.sol"; interface IBinaryOptionMarket { /* ========== TYPES ========== */ enum Phase {Trading, Maturity, Expiry} enum Side {Long, Short} /* ========== VIEWS / VARIABLES ========== */ function options() external view returns (IBinaryOption long, IBinaryOption short); function times() external view returns ( uint maturity, uint destructino ); function oracleDetails() external view returns ( bytes32 key, uint strikePrice, uint finalPrice ); function fees() external view returns ( uint poolFee, uint creatorFee ); function deposited() external view returns (uint); function accumulatedFees() external view returns (uint); function creator() external view returns (address); function resolved() external view returns (bool); function phase() external view returns (Phase); function oraclePriceAndTimestamp() external view returns (uint price, uint updatedAt); function canResolve() external view returns (bool); function result() external view returns (Side); function balancesOf(address account) external view returns (uint long, uint short); function totalSupplies() external view returns (uint long, uint short); /* ========== MUTATIVE FUNCTIONS ========== */ function mint(uint value) external; function exerciseOptions() external returns (uint); }
pragma solidity >=0.4.24; import "../interfaces/IBinaryOptionMarket.sol"; interface IOracleInstance { /* ========== VIEWS / VARIABLES ========== */ function getOutcome() external view returns (bool); function resolvable() external view returns (bool); function targetName() external view returns (string memory); function targetOutcome() external view returns (string memory); function eventName() external view returns (string memory); /* ========== MUTATIVE FUNCTIONS ========== */ }
pragma solidity ^0.5.16; // Libraries import "openzeppelin-solidity-2.3.0/contracts/math/SafeMath.sol"; // https://docs.synthetix.io/contracts/source/libraries/safedecimalmath library SafeDecimalMath { using SafeMath for uint; /* Number of decimal places in the representations. */ uint8 public constant decimals = 18; uint8 public constant highPrecisionDecimals = 27; /* The number representing 1.0. */ uint public constant UNIT = 10**uint(decimals); /* The number representing 1.0 for higher fidelity numbers. */ uint public constant PRECISE_UNIT = 10**uint(highPrecisionDecimals); uint private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR = 10**uint(highPrecisionDecimals - decimals); /** * @return Provides an interface to UNIT. */ function unit() external pure returns (uint) { return UNIT; } /** * @return Provides an interface to PRECISE_UNIT. */ function preciseUnit() external pure returns (uint) { return PRECISE_UNIT; } /** * @return The result of multiplying x and y, interpreting the operands as fixed-point * decimals. * * @dev A unit factor is divided out after the product of x and y is evaluated, * so that product must be less than 2**256. As this is an integer division, * the internal division always rounds down. This helps save on gas. Rounding * is more expensive on gas. */ function multiplyDecimal(uint x, uint y) internal pure returns (uint) { /* Divide by UNIT to remove the extra factor introduced by the product. */ return x.mul(y) / UNIT; } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of the specified precision unit. * * @dev The operands should be in the form of a the specified unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function _multiplyDecimalRound( uint x, uint y, uint precisionUnit ) private pure returns (uint) { /* Divide by UNIT to remove the extra factor introduced by the product. */ uint quotientTimesTen = x.mul(y) / (precisionUnit / 10); if (quotientTimesTen % 10 >= 5) { quotientTimesTen += 10; } return quotientTimesTen / 10; } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of a precise unit. * * @dev The operands should be in the precise unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function multiplyDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) { return _multiplyDecimalRound(x, y, PRECISE_UNIT); } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of a standard unit. * * @dev The operands should be in the standard unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function multiplyDecimalRound(uint x, uint y) internal pure returns (uint) { return _multiplyDecimalRound(x, y, UNIT); } /** * @return The result of safely dividing x and y. The return value is a high * precision decimal. * * @dev y is divided after the product of x and the standard precision unit * is evaluated, so the product of x and UNIT must be less than 2**256. As * this is an integer division, the result is always rounded down. * This helps save on gas. Rounding is more expensive on gas. */ function divideDecimal(uint x, uint y) internal pure returns (uint) { /* Reintroduce the UNIT factor that will be divided out by y. */ return x.mul(UNIT).div(y); } /** * @return The result of safely dividing x and y. The return value is as a rounded * decimal in the precision unit specified in the parameter. * * @dev y is divided after the product of x and the specified precision unit * is evaluated, so the product of x and the specified precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function _divideDecimalRound( uint x, uint y, uint precisionUnit ) private pure returns (uint) { uint resultTimesTen = x.mul(precisionUnit * 10).div(y); if (resultTimesTen % 10 >= 5) { resultTimesTen += 10; } return resultTimesTen / 10; } /** * @return The result of safely dividing x and y. The return value is as a rounded * standard precision decimal. * * @dev y is divided after the product of x and the standard precision unit * is evaluated, so the product of x and the standard precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function divideDecimalRound(uint x, uint y) internal pure returns (uint) { return _divideDecimalRound(x, y, UNIT); } /** * @return The result of safely dividing x and y. The return value is as a rounded * high precision decimal. * * @dev y is divided after the product of x and the high precision unit * is evaluated, so the product of x and the high precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function divideDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) { return _divideDecimalRound(x, y, PRECISE_UNIT); } /** * @dev Convert a standard decimal representation to a high precision one. */ function decimalToPreciseDecimal(uint i) internal pure returns (uint) { return i.mul(UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR); } /** * @dev Convert a high precision decimal to a standard decimal representation. */ function preciseDecimalToDecimal(uint i) internal pure returns (uint) { uint quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10); if (quotientTimesTen % 10 >= 5) { quotientTimesTen += 10; } return quotientTimesTen / 10; } }
pragma solidity ^0.5.16; // Inheritance import "./interfaces/IBinaryOptionMarketManager.sol"; import "synthetix-2.43.1/contracts/Owned.sol"; import "synthetix-2.43.1/contracts/Pausable.sol"; // Libraries import "synthetix-2.43.1/contracts/AddressSetLib.sol"; import "synthetix-2.43.1/contracts/SafeDecimalMath.sol"; // Internal references import "./BinaryOptionMarketFactory.sol"; import "./BinaryOptionMarket.sol"; import "./BinaryOption.sol"; import "./interfaces/IBinaryOptionMarket.sol"; import "synthetix-2.43.1/contracts/interfaces/IExchangeRates.sol"; import "synthetix-2.43.1/contracts/interfaces/IERC20.sol"; import "synthetix-2.43.1/contracts/interfaces/IAddressResolver.sol"; contract BinaryOptionMarketManager is Owned, Pausable, IBinaryOptionMarketManager { /* ========== LIBRARIES ========== */ using SafeMath for uint; using AddressSetLib for AddressSetLib.AddressSet; /* ========== TYPES ========== */ struct Fees { uint poolFee; uint creatorFee; } struct Durations { uint maxOraclePriceAge; uint expiryDuration; uint maxTimeToMaturity; } /* ========== STATE VARIABLES ========== */ address public feeAddress; Fees public fees; Durations public durations; uint public capitalRequirement; bool public marketCreationEnabled = true; bool public customMarketCreationEnabled = false; uint public totalDeposited; AddressSetLib.AddressSet internal _activeMarkets; AddressSetLib.AddressSet internal _maturedMarkets; BinaryOptionMarketManager internal _migratingManager; IAddressResolver public resolver; address public binaryOptionMarketFactory; /* ---------- Address Resolver Configuration ---------- */ bytes32 internal constant CONTRACT_SYNTHSUSD = "SynthsUSD"; bytes32 internal constant CONTRACT_EXRATES = "ExchangeRates"; /* ========== CONSTRUCTOR ========== */ constructor( address _owner, IAddressResolver _resolver, uint _maxOraclePriceAge, uint _expiryDuration, uint _maxTimeToMaturity, uint _creatorCapitalRequirement, uint _poolFee, uint _creatorFee, address _feeAddress ) public Owned(_owner) Pausable() { resolver = _resolver; // Temporarily change the owner so that the setters don't revert. owner = msg.sender; setFeeAddress(_feeAddress); setExpiryDuration(_expiryDuration); setMaxOraclePriceAge(_maxOraclePriceAge); setMaxTimeToMaturity(_maxTimeToMaturity); setCreatorCapitalRequirement(_creatorCapitalRequirement); setPoolFee(_poolFee); setCreatorFee(_creatorFee); owner = _owner; } /* ========== SETTERS ========== */ function setBinaryOptionsMarketFactory(address _binaryOptionMarketFactory) external onlyOwner { binaryOptionMarketFactory = _binaryOptionMarketFactory; } function setFeeAddress(address _feeAddress) public onlyOwner { feeAddress = _feeAddress; } /* ========== VIEWS ========== */ /* ---------- Related Contracts ---------- */ function _sUSD() internal view returns (IERC20) { return IERC20(resolver.requireAndGetAddress(CONTRACT_SYNTHSUSD, "Synth sUSD contract not found")); } function _exchangeRates() internal view returns (IExchangeRates) { return IExchangeRates(resolver.requireAndGetAddress(CONTRACT_EXRATES, "ExchangeRates contract not found")); } /* ---------- Market Information ---------- */ function _isKnownMarket(address candidate) internal view returns (bool) { return _activeMarkets.contains(candidate) || _maturedMarkets.contains(candidate); } function numActiveMarkets() external view returns (uint) { return _activeMarkets.elements.length; } function activeMarkets(uint index, uint pageSize) external view returns (address[] memory) { return _activeMarkets.getPage(index, pageSize); } function numMaturedMarkets() external view returns (uint) { return _maturedMarkets.elements.length; } function maturedMarkets(uint index, uint pageSize) external view returns (address[] memory) { return _maturedMarkets.getPage(index, pageSize); } function _isValidKey(bytes32 oracleKey) internal view returns (bool) { IExchangeRates exchangeRates = _exchangeRates(); // If it has a rate, then it's possibly a valid key if (exchangeRates.rateForCurrency(oracleKey) != 0) { // But not sUSD if (oracleKey == "sUSD") { return false; } // and not inverse rates (uint entryPoint, , , , ) = exchangeRates.inversePricing(oracleKey); if (entryPoint != 0) { return false; } return true; } return false; } /* ========== MUTATIVE FUNCTIONS ========== */ /* ---------- Setters ---------- */ function setMaxOraclePriceAge(uint _maxOraclePriceAge) public onlyOwner { durations.maxOraclePriceAge = _maxOraclePriceAge; emit MaxOraclePriceAgeUpdated(_maxOraclePriceAge); } function setExpiryDuration(uint _expiryDuration) public onlyOwner { durations.expiryDuration = _expiryDuration; emit ExpiryDurationUpdated(_expiryDuration); } function setMaxTimeToMaturity(uint _maxTimeToMaturity) public onlyOwner { durations.maxTimeToMaturity = _maxTimeToMaturity; emit MaxTimeToMaturityUpdated(_maxTimeToMaturity); } function setPoolFee(uint _poolFee) public onlyOwner { uint totalFee = _poolFee + fees.creatorFee; require(totalFee < SafeDecimalMath.unit(), "Total fee must be less than 100%."); require(0 < totalFee, "Total fee must be nonzero."); fees.poolFee = _poolFee; emit PoolFeeUpdated(_poolFee); } function setCreatorFee(uint _creatorFee) public onlyOwner { uint totalFee = _creatorFee + fees.poolFee; require(totalFee < SafeDecimalMath.unit(), "Total fee must be less than 100%."); require(0 < totalFee, "Total fee must be nonzero."); fees.creatorFee = _creatorFee; emit CreatorFeeUpdated(_creatorFee); } function setCreatorCapitalRequirement(uint _creatorCapitalRequirement) public onlyOwner { capitalRequirement = _creatorCapitalRequirement; emit CreatorCapitalRequirementUpdated(_creatorCapitalRequirement); } /* ---------- Deposit Management ---------- */ function incrementTotalDeposited(uint delta) external onlyActiveMarkets notPaused { totalDeposited = totalDeposited.add(delta); } function decrementTotalDeposited(uint delta) external onlyKnownMarkets notPaused { // NOTE: As individual market debt is not tracked here, the underlying markets // need to be careful never to subtract more debt than they added. // This can't be enforced without additional state/communication overhead. totalDeposited = totalDeposited.sub(delta); } /* ---------- Market Lifecycle ---------- */ function createMarket( bytes32 oracleKey, uint strikePrice, uint maturity, uint initialMint, // initial sUSD to mint options for, bool customMarket, address customOracle ) external notPaused returns ( IBinaryOptionMarket // no support for returning BinaryOptionMarket polymorphically given the interface ) { require(marketCreationEnabled, "Market creation is disabled"); if (!customMarket) { require(_isValidKey(oracleKey), "Invalid key"); } else { if (!customMarketCreationEnabled) { require(owner == msg.sender, "Only owner can create custom markets"); } require(address(0) != customOracle, "Invalid custom oracle"); } require(maturity <= block.timestamp + durations.maxTimeToMaturity, "Maturity too far in the future"); uint expiry = maturity.add(durations.expiryDuration); require(block.timestamp < maturity, "Maturity has to be in the future"); // We also require maturity < expiry. But there is no need to check this. // Fees being in range are checked in the setters. // The market itself validates the capital and skew requirements. require(capitalRequirement <= initialMint, "Insufficient capital"); BinaryOptionMarket market = BinaryOptionMarketFactory(binaryOptionMarketFactory).createMarket( msg.sender, resolver, oracleKey, strikePrice, [maturity, expiry], initialMint, [fees.poolFee, fees.creatorFee], customMarket, customOracle ); _activeMarkets.add(address(market)); // The debt can't be incremented in the new market's constructor because until construction is complete, // the manager doesn't know its address in order to grant it permission. totalDeposited = totalDeposited.add(initialMint); _sUSD().transferFrom(msg.sender, address(market), initialMint); (BinaryOption long, BinaryOption short) = market.options(); emit MarketCreated( address(market), msg.sender, oracleKey, strikePrice, maturity, expiry, address(long), address(short), customMarket, customOracle ); return market; } function transferSusdTo( address sender, address receiver, uint amount ) external { //only to be called by markets themselves require(_isKnownMarket(address(msg.sender)), "Market unknown."); _sUSD().transferFrom(sender, receiver, amount); } function resolveMarket(address market) external { require(_activeMarkets.contains(market), "Not an active market"); BinaryOptionMarket(market).resolve(); _activeMarkets.remove(market); _maturedMarkets.add(market); } function expireMarkets(address[] calldata markets) external notPaused onlyOwner { for (uint i = 0; i < markets.length; i++) { address market = markets[i]; require(_isKnownMarket(address(market)), "Market unknown."); // The market itself handles decrementing the total deposits. BinaryOptionMarket(market).expire(msg.sender); // Note that we required that the market is known, which guarantees // its index is defined and that the list of markets is not empty. _maturedMarkets.remove(market); emit MarketExpired(market); } } function setMarketCreationEnabled(bool enabled) public onlyOwner { if (enabled != marketCreationEnabled) { marketCreationEnabled = enabled; emit MarketCreationEnabledUpdated(enabled); } } function setCustomMarketCreationEnabled(bool enabled) public onlyOwner { customMarketCreationEnabled = enabled; } function setMigratingManager(BinaryOptionMarketManager manager) public onlyOwner { _migratingManager = manager; } function migrateMarkets( BinaryOptionMarketManager receivingManager, bool active, BinaryOptionMarket[] calldata marketsToMigrate ) external onlyOwner { require(address(receivingManager) != address(this), "Can't migrate to self"); uint _numMarkets = marketsToMigrate.length; if (_numMarkets == 0) { return; } AddressSetLib.AddressSet storage markets = active ? _activeMarkets : _maturedMarkets; uint runningDepositTotal; for (uint i; i < _numMarkets; i++) { BinaryOptionMarket market = marketsToMigrate[i]; require(_isKnownMarket(address(market)), "Market unknown."); // Remove it from our list and deposit total. markets.remove(address(market)); runningDepositTotal = runningDepositTotal.add(market.deposited()); // Prepare to transfer ownership to the new manager. market.nominateNewOwner(address(receivingManager)); } // Deduct the total deposits of the migrated markets. totalDeposited = totalDeposited.sub(runningDepositTotal); emit MarketsMigrated(receivingManager, marketsToMigrate); // Now actually transfer the markets over to the new manager. receivingManager.receiveMarkets(active, marketsToMigrate); } function receiveMarkets(bool active, BinaryOptionMarket[] calldata marketsToReceive) external { require(msg.sender == address(_migratingManager), "Only permitted for migrating manager."); uint _numMarkets = marketsToReceive.length; if (_numMarkets == 0) { return; } AddressSetLib.AddressSet storage markets = active ? _activeMarkets : _maturedMarkets; uint runningDepositTotal; for (uint i; i < _numMarkets; i++) { BinaryOptionMarket market = marketsToReceive[i]; require(!_isKnownMarket(address(market)), "Market already known."); market.acceptOwnership(); markets.add(address(market)); // Update the market with the new manager address, runningDepositTotal = runningDepositTotal.add(market.deposited()); } totalDeposited = totalDeposited.add(runningDepositTotal); emit MarketsReceived(_migratingManager, marketsToReceive); } /* ========== MODIFIERS ========== */ modifier onlyActiveMarkets() { require(_activeMarkets.contains(msg.sender), "Permitted only for active markets."); _; } modifier onlyKnownMarkets() { require(_isKnownMarket(msg.sender), "Permitted only for known markets."); _; } /* ========== EVENTS ========== */ event MarketCreated( address market, address indexed creator, bytes32 indexed oracleKey, uint strikePrice, uint maturityDate, uint expiryDate, address long, address short, bool customMarket, address customOracle ); event MarketExpired(address market); event MarketsMigrated(BinaryOptionMarketManager receivingManager, BinaryOptionMarket[] markets); event MarketsReceived(BinaryOptionMarketManager migratingManager, BinaryOptionMarket[] markets); event MarketCreationEnabledUpdated(bool enabled); event MaxOraclePriceAgeUpdated(uint duration); event ExpiryDurationUpdated(uint duration); event MaxTimeToMaturityUpdated(uint duration); event CreatorCapitalRequirementUpdated(uint value); event PoolFeeUpdated(uint fee); event CreatorFeeUpdated(uint fee); }
pragma solidity ^0.5.16; // Inheritance import "synthetix-2.43.1/contracts/interfaces/IERC20.sol"; import "./interfaces/IBinaryOption.sol"; // Libraries import "synthetix-2.43.1/contracts/SafeDecimalMath.sol"; // Internal references import "./BinaryOptionMarket.sol"; contract BinaryOption is IERC20, IBinaryOption { /* ========== LIBRARIES ========== */ using SafeMath for uint; using SafeDecimalMath for uint; /* ========== STATE VARIABLES ========== */ string public name; string public symbol; uint8 public constant decimals = 18; BinaryOptionMarket public market; mapping(address => uint) public balanceOf; uint public totalSupply; // The argument order is allowance[owner][spender] mapping(address => mapping(address => uint)) public allowance; // Enforce a 1 cent minimum amount uint internal constant _MINIMUM_AMOUNT = 1e16; /* ========== CONSTRUCTOR ========== */ bool public initialized = false; function initialize( string calldata _name, string calldata _symbol ) external { require(!initialized, "Binary Option Market already initialized"); initialized = true; name = _name; symbol = _symbol; market = BinaryOptionMarket(msg.sender); } /* ========== MUTATIVE FUNCTIONS ========== */ function _requireMinimumAmount(uint amount) internal pure returns (uint) { require(amount >= _MINIMUM_AMOUNT || amount == 0, "Balance < $0.01"); return amount; } function mint(address minter, uint amount) external onlyMarket { _requireMinimumAmount(amount); totalSupply = totalSupply.add(amount); balanceOf[minter] = balanceOf[minter].add(amount); // Increment rather than assigning since a transfer may have occurred. emit Transfer(address(0), minter, amount); emit Issued(minter, amount); } // This must only be invoked after maturity. function exercise(address claimant) external onlyMarket { uint balance = balanceOf[claimant]; if (balance == 0) { return; } balanceOf[claimant] = 0; totalSupply = totalSupply.sub(balance); emit Transfer(claimant, address(0), balance); emit Burned(claimant, balance); } // This must only be invoked after the exercise window is complete. // Note that any options which have not been exercised will linger. function expire(address payable beneficiary) external onlyMarket { selfdestruct(beneficiary); } /* ---------- ERC20 Functions ---------- */ function _transfer( address _from, address _to, uint _value ) internal returns (bool success) { market.requireUnpaused(); require(_to != address(0) && _to != address(this), "Invalid address"); uint fromBalance = balanceOf[_from]; require(_value <= fromBalance, "Insufficient balance"); balanceOf[_from] = fromBalance.sub(_value); balanceOf[_to] = balanceOf[_to].add(_value); emit Transfer(_from, _to, _value); return true; } function transfer(address _to, uint _value) external returns (bool success) { return _transfer(msg.sender, _to, _value); } function transferFrom( address _from, address _to, uint _value ) external returns (bool success) { uint fromAllowance = allowance[_from][msg.sender]; require(_value <= fromAllowance, "Insufficient allowance"); allowance[_from][msg.sender] = fromAllowance.sub(_value); return _transfer(_from, _to, _value); } function approve(address _spender, uint _value) external returns (bool success) { require(_spender != address(0)); allowance[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } /* ========== MODIFIERS ========== */ modifier onlyMarket() { require(msg.sender == address(market), "Only market allowed"); _; } /* ========== EVENTS ========== */ event Issued(address indexed account, uint value); event Burned(address indexed account, uint value); event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); }
pragma solidity >=0.4.24; // https://docs.synthetix.io/contracts/source/interfaces/iexchangerates interface IExchangeRates { // Structs struct RateAndUpdatedTime { uint216 rate; uint40 time; } struct InversePricing { uint entryPoint; uint upperLimit; uint lowerLimit; bool frozenAtUpperLimit; bool frozenAtLowerLimit; } // Views function aggregators(bytes32 currencyKey) external view returns (address); function aggregatorWarningFlags() external view returns (address); function anyRateIsInvalid(bytes32[] calldata currencyKeys) external view returns (bool); function canFreezeRate(bytes32 currencyKey) external view returns (bool); function currentRoundForRate(bytes32 currencyKey) external view returns (uint); function currenciesUsingAggregator(address aggregator) external view returns (bytes32[] memory); function effectiveValue( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external view returns (uint value); function effectiveValueAndRates( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external view returns ( uint value, uint sourceRate, uint destinationRate ); function effectiveValueAtRound( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, uint roundIdForSrc, uint roundIdForDest ) external view returns (uint value); function getCurrentRoundId(bytes32 currencyKey) external view returns (uint); function getLastRoundIdBeforeElapsedSecs( bytes32 currencyKey, uint startingRoundId, uint startingTimestamp, uint timediff ) external view returns (uint); function inversePricing(bytes32 currencyKey) external view returns ( uint entryPoint, uint upperLimit, uint lowerLimit, bool frozenAtUpperLimit, bool frozenAtLowerLimit ); function lastRateUpdateTimes(bytes32 currencyKey) external view returns (uint256); function oracle() external view returns (address); function rateAndTimestampAtRound(bytes32 currencyKey, uint roundId) external view returns (uint rate, uint time); function rateAndUpdatedTime(bytes32 currencyKey) external view returns (uint rate, uint time); function rateAndInvalid(bytes32 currencyKey) external view returns (uint rate, bool isInvalid); function rateForCurrency(bytes32 currencyKey) external view returns (uint); function rateIsFlagged(bytes32 currencyKey) external view returns (bool); function rateIsFrozen(bytes32 currencyKey) external view returns (bool); function rateIsInvalid(bytes32 currencyKey) external view returns (bool); function rateIsStale(bytes32 currencyKey) external view returns (bool); function rateStalePeriod() external view returns (uint); function ratesAndUpdatedTimeForCurrencyLastNRounds(bytes32 currencyKey, uint numRounds) external view returns (uint[] memory rates, uint[] memory times); function ratesAndInvalidForCurrencies(bytes32[] calldata currencyKeys) external view returns (uint[] memory rates, bool anyRateInvalid); function ratesForCurrencies(bytes32[] calldata currencyKeys) external view returns (uint[] memory); // Mutative functions function freezeRate(bytes32 currencyKey) external; }
pragma solidity >=0.4.24; // https://docs.synthetix.io/contracts/source/interfaces/ierc20 interface IERC20 { // ERC20 Optional Views function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); // Views function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); // Mutative functions function transfer(address to, uint value) external returns (bool); function approve(address spender, uint value) external returns (bool); function transferFrom( address from, address to, uint value ) external returns (bool); // Events event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); }
pragma solidity >=0.4.24; // https://docs.synthetix.io/contracts/source/interfaces/iaddressresolver interface IAddressResolver { function getAddress(bytes32 name) external view returns (address); function getSynth(bytes32 key) external view returns (address); function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address); }
pragma solidity >=0.4.24; import "../interfaces/IBinaryOptionMarket.sol"; interface IBinaryOptionMarketManager { /* ========== VIEWS / VARIABLES ========== */ function fees() external view returns (uint poolFee, uint creatorFee); function durations() external view returns ( uint maxOraclePriceAge, uint expiryDuration, uint maxTimeToMaturity ); function capitalRequirement() external view returns (uint); function marketCreationEnabled() external view returns (bool); function totalDeposited() external view returns (uint); function numActiveMarkets() external view returns (uint); function activeMarkets(uint index, uint pageSize) external view returns (address[] memory); function numMaturedMarkets() external view returns (uint); function maturedMarkets(uint index, uint pageSize) external view returns (address[] memory); /* ========== MUTATIVE FUNCTIONS ========== */ function createMarket( bytes32 oracleKey, uint strikePrice, uint maturity, uint initialMint, // initial sUSD to mint options for, bool customMarket, address customOracle ) external returns (IBinaryOptionMarket); function resolveMarket(address market) external; function expireMarkets(address[] calldata market) external; function transferSusdTo( address sender, address receiver, uint amount ) external; }
pragma solidity >=0.4.24; import "../interfaces/IBinaryOptionMarket.sol"; import "synthetix-2.43.1/contracts/interfaces/IERC20.sol"; interface IBinaryOption { /* ========== VIEWS / VARIABLES ========== */ function market() external view returns (IBinaryOptionMarket); function balanceOf(address account) external view returns (uint); function totalSupply() external view returns (uint); }
pragma solidity ^0.5.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } }
pragma solidity ^0.5.16; // https://docs.synthetix.io/contracts/source/contracts/owned contract Owned { address public owner; address public nominatedOwner; constructor(address _owner) public { require(_owner != address(0), "Owner address cannot be 0"); owner = _owner; emit OwnerChanged(address(0), _owner); } function nominateNewOwner(address _owner) external onlyOwner { nominatedOwner = _owner; emit OwnerNominated(_owner); } function acceptOwnership() external { require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership"); emit OwnerChanged(owner, nominatedOwner); owner = nominatedOwner; nominatedOwner = address(0); } modifier onlyOwner { _onlyOwner(); _; } function _onlyOwner() private view { require(msg.sender == owner, "Only the contract owner may perform this action"); } event OwnerNominated(address newOwner); event OwnerChanged(address oldOwner, address newOwner); }
pragma solidity ^0.5.16; // Inheritance import "./Owned.sol"; // https://docs.synthetix.io/contracts/source/contracts/pausable contract Pausable is Owned { uint public lastPauseTime; bool public paused; constructor() internal { // This contract is abstract, and thus cannot be instantiated directly require(owner != address(0), "Owner must be set"); // Paused will be false, and lastPauseTime will be 0 upon initialisation } /** * @notice Change the paused state of the contract * @dev Only the contract owner may call this. */ function setPaused(bool _paused) external onlyOwner { // Ensure we're actually changing the state before we do anything if (_paused == paused) { return; } // Set our paused state. paused = _paused; // If applicable, set the last pause time. if (paused) { lastPauseTime = now; } // Let everyone know that our pause state has changed. emit PauseChanged(paused); } event PauseChanged(bool isPaused); modifier notPaused { require(!paused, "This action cannot be performed while the contract is paused"); _; } }
pragma solidity ^0.5.16; // https://docs.synthetix.io/contracts/source/libraries/addresssetlib/ library AddressSetLib { struct AddressSet { address[] elements; mapping(address => uint) indices; } function contains(AddressSet storage set, address candidate) internal view returns (bool) { if (set.elements.length == 0) { return false; } uint index = set.indices[candidate]; return index != 0 || set.elements[0] == candidate; } function getPage( AddressSet storage set, uint index, uint pageSize ) internal view returns (address[] memory) { // NOTE: This implementation should be converted to slice operators if the compiler is updated to v0.6.0+ uint endIndex = index + pageSize; // The check below that endIndex <= index handles overflow. // If the page extends past the end of the list, truncate it. if (endIndex > set.elements.length) { endIndex = set.elements.length; } if (endIndex <= index) { return new address[](0); } uint n = endIndex - index; // We already checked for negative overflow. address[] memory page = new address[](n); for (uint i; i < n; i++) { page[i] = set.elements[i + index]; } return page; } function add(AddressSet storage set, address element) internal { // Adding to a set is an idempotent operation. if (!contains(set, element)) { set.indices[element] = set.elements.length; set.elements.push(element); } } function remove(AddressSet storage set, address element) internal { require(contains(set, element), "Element not in set."); // Replace the removed element with the last element of the list. uint index = set.indices[element]; uint lastIndex = set.elements.length - 1; // We required that element is in the list, so it is not empty. if (index != lastIndex) { // No need to shift the last element if it is the one we want to delete. address shiftedElement = set.elements[lastIndex]; set.elements[index] = shiftedElement; set.indices[shiftedElement] = index; } set.elements.pop(); delete set.indices[element]; } }
pragma solidity ^0.5.16; // Inheritance import "synthetix-2.43.1/contracts/MinimalProxyFactory.sol"; import "synthetix-2.43.1/contracts/Owned.sol"; // Internal references import "./BinaryOptionMarket.sol"; import "synthetix-2.43.1/contracts/interfaces/IAddressResolver.sol"; contract BinaryOptionMarketFactory is MinimalProxyFactory, Owned { /* ========== STATE VARIABLES ========== */ address public binaryOptionMarketManager; address public binaryOptionMarketMastercopy; address public binaryOptionMastercopy; /* ========== CONSTRUCTOR ========== */ constructor(address _owner) public MinimalProxyFactory() Owned(_owner) {} /* ========== MUTATIVE FUNCTIONS ========== */ function createMarket( address creator, IAddressResolver _resolver, bytes32 oracleKey, uint strikePrice, uint[2] calldata times, // [maturity, expiry] uint initialMint, uint[2] calldata fees, // [poolFee, creatorFee] bool customMarket, address customOracle ) external returns (BinaryOptionMarket) { require(binaryOptionMarketManager == msg.sender, "Only permitted by the manager."); BinaryOptionMarket bom = BinaryOptionMarket( _cloneAsMinimalProxy(binaryOptionMarketMastercopy, "Could not create a Binary Option Market") ); bom.initialize( binaryOptionMarketManager, binaryOptionMastercopy, _resolver, creator, oracleKey, strikePrice, times, initialMint, fees, customMarket, customOracle ); return bom; } /* ========== SETTERS ========== */ function setBinaryOptionMarketManager(address _binaryOptionMarketManager) external onlyOwner { binaryOptionMarketManager = _binaryOptionMarketManager; emit BinaryOptionMarketManagerChanged(_binaryOptionMarketManager); } function setBinaryOptionMarketMastercopy(address _binaryOptionMarketMastercopy) external onlyOwner { binaryOptionMarketMastercopy = _binaryOptionMarketMastercopy; emit BinaryOptionMarketMastercopyChanged(_binaryOptionMarketMastercopy); } function setBinaryOptionMastercopy(address _binaryOptionMastercopy) external onlyOwner { binaryOptionMastercopy = _binaryOptionMastercopy; emit BinaryOptionMastercopyChanged(_binaryOptionMastercopy); } event BinaryOptionMarketManagerChanged(address _binaryOptionMarketManager); event BinaryOptionMarketMastercopyChanged(address _binaryOptionMarketMastercopy); event BinaryOptionMastercopyChanged(address _binaryOptionMastercopy); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": { "synthetix-2.43.1/contracts/SafeDecimalMath.sol": { "SafeDecimalMath": "0x84d626b2bb4d0f064067e4bf80fce7055d8f3e7b" } } }
[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum IBinaryOptionMarket.Side","name":"result","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"oraclePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oracleTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"deposited","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"poolFees","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"creatorFees","type":"uint256"}],"name":"MarketResolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum IBinaryOptionMarket.Side","name":"side","type":"uint8"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"OptionsExercised","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"accumulatedFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balancesOf","outputs":[{"internalType":"uint256","name":"long","type":"uint256"},{"internalType":"uint256","name":"short","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"canResolve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"creator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"customMarket","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"deposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"exerciseOptions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address payable","name":"beneficiary","type":"address"}],"name":"expire","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"fees","outputs":[{"internalType":"uint256","name":"poolFee","type":"uint256"},{"internalType":"uint256","name":"creatorFee","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"iOracleInstance","outputs":[{"internalType":"contract IOracleInstance","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"initialMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_binaryOptionMastercopy","type":"address"},{"internalType":"contract IAddressResolver","name":"_resolver","type":"address"},{"internalType":"address","name":"_creator","type":"address"},{"internalType":"bytes32","name":"_oracleKey","type":"bytes32"},{"internalType":"uint256","name":"_strikePrice","type":"uint256"},{"internalType":"uint256[2]","name":"_times","type":"uint256[2]"},{"internalType":"uint256","name":"_deposit","type":"uint256"},{"internalType":"uint256[2]","name":"_fees","type":"uint256[2]"},{"internalType":"bool","name":"_customMarket","type":"bool"},{"internalType":"address","name":"_iOracleInstanceAddress","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"options","outputs":[{"internalType":"contract BinaryOption","name":"long","type":"address"},{"internalType":"contract BinaryOption","name":"short","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oracleDetails","outputs":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"uint256","name":"strikePrice","type":"uint256"},{"internalType":"uint256","name":"finalPrice","type":"uint256"},{"internalType":"bool","name":"customMarket","type":"bool"},{"internalType":"address","name":"iOracleInstanceAddress","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oraclePriceAndTimestamp","outputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"phase","outputs":[{"internalType":"enum IBinaryOptionMarket.Phase","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"requireUnpaused","outputs":[],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"resolve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"resolved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"resolver","outputs":[{"internalType":"contract IAddressResolver","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"result","outputs":[{"internalType":"enum IBinaryOptionMarket.Side","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setIOracleInstance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"times","outputs":[{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupplies","outputs":[{"internalType":"uint256","name":"long","type":"uint256"},{"internalType":"uint256","name":"short","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.