My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
SynthetixBridgeToBase
Compiler Version
v0.5.16+commit.9c3226ce
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at optimistic.etherscan.io on 2022-03-17 */ /* ____ __ __ __ _ / __/__ __ ___ / /_ / / ___ / /_ (_)__ __ _\ \ / // // _ \/ __// _ \/ -_)/ __// / \ \ / /___/ \_, //_//_/\__//_//_/\__/ \__//_/ /_\_\ /___/ * Synthetix: SynthetixBridgeToBase.sol * * Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/SynthetixBridgeToBase.sol * Docs: https://docs.synthetix.io/contracts/SynthetixBridgeToBase * * Contract Dependencies: * - BaseSynthetixBridge * - IAddressResolver * - IBaseSynthetixBridge * - ISynthetixBridgeToBase * - MixinResolver * - MixinSystemSettings * - Owned * - iOVM_L2DepositedToken * Libraries: * - VestingEntries * * MIT License * =========== * * Copyright (c) 2022 Synthetix * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ 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); } // 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); } // https://docs.synthetix.io/contracts/source/interfaces/isynth interface ISynth { // Views function currencyKey() external view returns (bytes32); function transferableSynths(address account) external view returns (uint); // Mutative functions function transferAndSettle(address to, uint value) external returns (bool); function transferFromAndSettle( address from, address to, uint value ) external returns (bool); // Restricted: used internally to Synthetix function burn(address account, uint amount) external; function issue(address account, uint amount) external; } // https://docs.synthetix.io/contracts/source/interfaces/iissuer interface IIssuer { // Views function anySynthOrSNXRateIsInvalid() external view returns (bool anyRateInvalid); function availableCurrencyKeys() external view returns (bytes32[] memory); function availableSynthCount() external view returns (uint); function availableSynths(uint index) external view returns (ISynth); function canBurnSynths(address account) external view returns (bool); function collateral(address account) external view returns (uint); function collateralisationRatio(address issuer) external view returns (uint); function collateralisationRatioAndAnyRatesInvalid(address _issuer) external view returns (uint cratio, bool anyRateIsInvalid); function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint debtBalance); function issuanceRatio() external view returns (uint); function lastIssueEvent(address account) external view returns (uint); function maxIssuableSynths(address issuer) external view returns (uint maxIssuable); function minimumStakeTime() external view returns (uint); function remainingIssuableSynths(address issuer) external view returns ( uint maxIssuable, uint alreadyIssued, uint totalSystemDebt ); function synths(bytes32 currencyKey) external view returns (ISynth); function getSynths(bytes32[] calldata currencyKeys) external view returns (ISynth[] memory); function synthsByAddress(address synthAddress) external view returns (bytes32); function totalIssuedSynths(bytes32 currencyKey, bool excludeOtherCollateral) external view returns (uint); function transferableSynthetixAndAnyRateIsInvalid(address account, uint balance) external view returns (uint transferable, bool anyRateIsInvalid); // Restricted: used internally to Synthetix function issueSynths(address from, uint amount) external; function issueSynthsOnBehalf( address issueFor, address from, uint amount ) external; function issueMaxSynths(address from) external; function issueMaxSynthsOnBehalf(address issueFor, address from) external; function burnSynths(address from, uint amount) external; function burnSynthsOnBehalf( address burnForAddress, address from, uint amount ) external; function burnSynthsToTarget(address from) external; function burnSynthsToTargetOnBehalf(address burnForAddress, address from) external; function burnForRedemption( address deprecatedSynthProxy, address account, uint balance ) external; function liquidateDelinquentAccount( address account, uint susdAmount, address liquidator ) external returns (uint totalRedeemed, uint amountToLiquidate); function setCurrentPeriodId(uint128 periodId) external; } // Inheritance // Internal references // https://docs.synthetix.io/contracts/source/contracts/addressresolver contract AddressResolver is Owned, IAddressResolver { mapping(bytes32 => address) public repository; constructor(address _owner) public Owned(_owner) {} /* ========== RESTRICTED FUNCTIONS ========== */ function importAddresses(bytes32[] calldata names, address[] calldata destinations) external onlyOwner { require(names.length == destinations.length, "Input lengths must match"); for (uint i = 0; i < names.length; i++) { bytes32 name = names[i]; address destination = destinations[i]; repository[name] = destination; emit AddressImported(name, destination); } } /* ========= PUBLIC FUNCTIONS ========== */ function rebuildCaches(MixinResolver[] calldata destinations) external { for (uint i = 0; i < destinations.length; i++) { destinations[i].rebuildCache(); } } /* ========== VIEWS ========== */ function areAddressesImported(bytes32[] calldata names, address[] calldata destinations) external view returns (bool) { for (uint i = 0; i < names.length; i++) { if (repository[names[i]] != destinations[i]) { return false; } } return true; } function getAddress(bytes32 name) external view returns (address) { return repository[name]; } function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address) { address _foundAddress = repository[name]; require(_foundAddress != address(0), reason); return _foundAddress; } function getSynth(bytes32 key) external view returns (address) { IIssuer issuer = IIssuer(repository["Issuer"]); require(address(issuer) != address(0), "Cannot find Issuer address"); return address(issuer.synths(key)); } /* ========== EVENTS ========== */ event AddressImported(bytes32 name, address destination); } // Internal references // https://docs.synthetix.io/contracts/source/contracts/mixinresolver contract MixinResolver { AddressResolver public resolver; mapping(bytes32 => address) private addressCache; constructor(address _resolver) internal { resolver = AddressResolver(_resolver); } /* ========== INTERNAL FUNCTIONS ========== */ function combineArrays(bytes32[] memory first, bytes32[] memory second) internal pure returns (bytes32[] memory combination) { combination = new bytes32[](first.length + second.length); for (uint i = 0; i < first.length; i++) { combination[i] = first[i]; } for (uint j = 0; j < second.length; j++) { combination[first.length + j] = second[j]; } } /* ========== PUBLIC FUNCTIONS ========== */ // Note: this function is public not external in order for it to be overridden and invoked via super in subclasses function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {} function rebuildCache() public { bytes32[] memory requiredAddresses = resolverAddressesRequired(); // The resolver must call this function whenver it updates its state for (uint i = 0; i < requiredAddresses.length; i++) { bytes32 name = requiredAddresses[i]; // Note: can only be invoked once the resolver has all the targets needed added address destination = resolver.requireAndGetAddress(name, string(abi.encodePacked("Resolver missing target: ", name))); addressCache[name] = destination; emit CacheUpdated(name, destination); } } /* ========== VIEWS ========== */ function isResolverCached() external view returns (bool) { bytes32[] memory requiredAddresses = resolverAddressesRequired(); for (uint i = 0; i < requiredAddresses.length; i++) { bytes32 name = requiredAddresses[i]; // false if our cache is invalid or if the resolver doesn't have the required address if (resolver.getAddress(name) != addressCache[name] || addressCache[name] == address(0)) { return false; } } return true; } /* ========== INTERNAL FUNCTIONS ========== */ function requireAndGetAddress(bytes32 name) internal view returns (address) { address _foundAddress = addressCache[name]; require(_foundAddress != address(0), string(abi.encodePacked("Missing address: ", name))); return _foundAddress; } /* ========== EVENTS ========== */ event CacheUpdated(bytes32 name, address destination); } // https://docs.synthetix.io/contracts/source/interfaces/iflexiblestorage interface IFlexibleStorage { // Views function getUIntValue(bytes32 contractName, bytes32 record) external view returns (uint); function getUIntValues(bytes32 contractName, bytes32[] calldata records) external view returns (uint[] memory); function getIntValue(bytes32 contractName, bytes32 record) external view returns (int); function getIntValues(bytes32 contractName, bytes32[] calldata records) external view returns (int[] memory); function getAddressValue(bytes32 contractName, bytes32 record) external view returns (address); function getAddressValues(bytes32 contractName, bytes32[] calldata records) external view returns (address[] memory); function getBoolValue(bytes32 contractName, bytes32 record) external view returns (bool); function getBoolValues(bytes32 contractName, bytes32[] calldata records) external view returns (bool[] memory); function getBytes32Value(bytes32 contractName, bytes32 record) external view returns (bytes32); function getBytes32Values(bytes32 contractName, bytes32[] calldata records) external view returns (bytes32[] memory); // Mutative functions function deleteUIntValue(bytes32 contractName, bytes32 record) external; function deleteIntValue(bytes32 contractName, bytes32 record) external; function deleteAddressValue(bytes32 contractName, bytes32 record) external; function deleteBoolValue(bytes32 contractName, bytes32 record) external; function deleteBytes32Value(bytes32 contractName, bytes32 record) external; function setUIntValue( bytes32 contractName, bytes32 record, uint value ) external; function setUIntValues( bytes32 contractName, bytes32[] calldata records, uint[] calldata values ) external; function setIntValue( bytes32 contractName, bytes32 record, int value ) external; function setIntValues( bytes32 contractName, bytes32[] calldata records, int[] calldata values ) external; function setAddressValue( bytes32 contractName, bytes32 record, address value ) external; function setAddressValues( bytes32 contractName, bytes32[] calldata records, address[] calldata values ) external; function setBoolValue( bytes32 contractName, bytes32 record, bool value ) external; function setBoolValues( bytes32 contractName, bytes32[] calldata records, bool[] calldata values ) external; function setBytes32Value( bytes32 contractName, bytes32 record, bytes32 value ) external; function setBytes32Values( bytes32 contractName, bytes32[] calldata records, bytes32[] calldata values ) external; } // Internal references // https://docs.synthetix.io/contracts/source/contracts/mixinsystemsettings contract MixinSystemSettings is MixinResolver { // must match the one defined SystemSettingsLib, defined in both places due to sol v0.5 limitations bytes32 internal constant SETTING_CONTRACT_NAME = "SystemSettings"; bytes32 internal constant SETTING_WAITING_PERIOD_SECS = "waitingPeriodSecs"; bytes32 internal constant SETTING_PRICE_DEVIATION_THRESHOLD_FACTOR = "priceDeviationThresholdFactor"; bytes32 internal constant SETTING_ISSUANCE_RATIO = "issuanceRatio"; bytes32 internal constant SETTING_FEE_PERIOD_DURATION = "feePeriodDuration"; bytes32 internal constant SETTING_TARGET_THRESHOLD = "targetThreshold"; bytes32 internal constant SETTING_LIQUIDATION_DELAY = "liquidationDelay"; bytes32 internal constant SETTING_LIQUIDATION_RATIO = "liquidationRatio"; bytes32 internal constant SETTING_LIQUIDATION_PENALTY = "liquidationPenalty"; bytes32 internal constant SETTING_RATE_STALE_PERIOD = "rateStalePeriod"; /* ========== Exchange Fees Related ========== */ bytes32 internal constant SETTING_EXCHANGE_FEE_RATE = "exchangeFeeRate"; bytes32 internal constant SETTING_EXCHANGE_DYNAMIC_FEE_THRESHOLD = "exchangeDynamicFeeThreshold"; bytes32 internal constant SETTING_EXCHANGE_DYNAMIC_FEE_WEIGHT_DECAY = "exchangeDynamicFeeWeightDecay"; bytes32 internal constant SETTING_EXCHANGE_DYNAMIC_FEE_ROUNDS = "exchangeDynamicFeeRounds"; bytes32 internal constant SETTING_EXCHANGE_MAX_DYNAMIC_FEE = "exchangeMaxDynamicFee"; /* ========== End Exchange Fees Related ========== */ bytes32 internal constant SETTING_MINIMUM_STAKE_TIME = "minimumStakeTime"; bytes32 internal constant SETTING_AGGREGATOR_WARNING_FLAGS = "aggregatorWarningFlags"; bytes32 internal constant SETTING_TRADING_REWARDS_ENABLED = "tradingRewardsEnabled"; bytes32 internal constant SETTING_DEBT_SNAPSHOT_STALE_TIME = "debtSnapshotStaleTime"; bytes32 internal constant SETTING_CROSS_DOMAIN_DEPOSIT_GAS_LIMIT = "crossDomainDepositGasLimit"; bytes32 internal constant SETTING_CROSS_DOMAIN_ESCROW_GAS_LIMIT = "crossDomainEscrowGasLimit"; bytes32 internal constant SETTING_CROSS_DOMAIN_REWARD_GAS_LIMIT = "crossDomainRewardGasLimit"; bytes32 internal constant SETTING_CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT = "crossDomainWithdrawalGasLimit"; bytes32 internal constant SETTING_CROSS_DOMAIN_FEE_PERIOD_CLOSE_GAS_LIMIT = "crossDomainCloseGasLimit"; bytes32 internal constant SETTING_CROSS_DOMAIN_RELAY_GAS_LIMIT = "crossDomainRelayGasLimit"; bytes32 internal constant SETTING_ETHER_WRAPPER_MAX_ETH = "etherWrapperMaxETH"; bytes32 internal constant SETTING_ETHER_WRAPPER_MINT_FEE_RATE = "etherWrapperMintFeeRate"; bytes32 internal constant SETTING_ETHER_WRAPPER_BURN_FEE_RATE = "etherWrapperBurnFeeRate"; bytes32 internal constant SETTING_WRAPPER_MAX_TOKEN_AMOUNT = "wrapperMaxTokens"; bytes32 internal constant SETTING_WRAPPER_MINT_FEE_RATE = "wrapperMintFeeRate"; bytes32 internal constant SETTING_WRAPPER_BURN_FEE_RATE = "wrapperBurnFeeRate"; bytes32 internal constant SETTING_INTERACTION_DELAY = "interactionDelay"; bytes32 internal constant SETTING_COLLAPSE_FEE_RATE = "collapseFeeRate"; bytes32 internal constant SETTING_ATOMIC_MAX_VOLUME_PER_BLOCK = "atomicMaxVolumePerBlock"; bytes32 internal constant SETTING_ATOMIC_TWAP_WINDOW = "atomicTwapWindow"; bytes32 internal constant SETTING_ATOMIC_EQUIVALENT_FOR_DEX_PRICING = "atomicEquivalentForDexPricing"; bytes32 internal constant SETTING_ATOMIC_EXCHANGE_FEE_RATE = "atomicExchangeFeeRate"; bytes32 internal constant SETTING_ATOMIC_PRICE_BUFFER = "atomicPriceBuffer"; bytes32 internal constant SETTING_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW = "atomicVolConsiderationWindow"; bytes32 internal constant SETTING_ATOMIC_VOLATILITY_UPDATE_THRESHOLD = "atomicVolUpdateThreshold"; bytes32 internal constant CONTRACT_FLEXIBLESTORAGE = "FlexibleStorage"; enum CrossDomainMessageGasLimits {Deposit, Escrow, Reward, Withdrawal, CloseFeePeriod, Relay} struct DynamicFeeConfig { uint threshold; uint weightDecay; uint rounds; uint maxFee; } constructor(address _resolver) internal MixinResolver(_resolver) {} function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { addresses = new bytes32[](1); addresses[0] = CONTRACT_FLEXIBLESTORAGE; } function flexibleStorage() internal view returns (IFlexibleStorage) { return IFlexibleStorage(requireAndGetAddress(CONTRACT_FLEXIBLESTORAGE)); } function _getGasLimitSetting(CrossDomainMessageGasLimits gasLimitType) internal pure returns (bytes32) { if (gasLimitType == CrossDomainMessageGasLimits.Deposit) { return SETTING_CROSS_DOMAIN_DEPOSIT_GAS_LIMIT; } else if (gasLimitType == CrossDomainMessageGasLimits.Escrow) { return SETTING_CROSS_DOMAIN_ESCROW_GAS_LIMIT; } else if (gasLimitType == CrossDomainMessageGasLimits.Reward) { return SETTING_CROSS_DOMAIN_REWARD_GAS_LIMIT; } else if (gasLimitType == CrossDomainMessageGasLimits.Withdrawal) { return SETTING_CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT; } else if (gasLimitType == CrossDomainMessageGasLimits.Relay) { return SETTING_CROSS_DOMAIN_RELAY_GAS_LIMIT; } else if (gasLimitType == CrossDomainMessageGasLimits.CloseFeePeriod) { return SETTING_CROSS_DOMAIN_FEE_PERIOD_CLOSE_GAS_LIMIT; } else { revert("Unknown gas limit type"); } } function getCrossDomainMessageGasLimit(CrossDomainMessageGasLimits gasLimitType) internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, _getGasLimitSetting(gasLimitType)); } function getTradingRewardsEnabled() internal view returns (bool) { return flexibleStorage().getBoolValue(SETTING_CONTRACT_NAME, SETTING_TRADING_REWARDS_ENABLED); } function getWaitingPeriodSecs() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_WAITING_PERIOD_SECS); } function getPriceDeviationThresholdFactor() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_PRICE_DEVIATION_THRESHOLD_FACTOR); } function getIssuanceRatio() internal view returns (uint) { // lookup on flexible storage directly for gas savings (rather than via SystemSettings) return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ISSUANCE_RATIO); } function getFeePeriodDuration() internal view returns (uint) { // lookup on flexible storage directly for gas savings (rather than via SystemSettings) return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_FEE_PERIOD_DURATION); } function getTargetThreshold() internal view returns (uint) { // lookup on flexible storage directly for gas savings (rather than via SystemSettings) return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_TARGET_THRESHOLD); } function getLiquidationDelay() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_DELAY); } function getLiquidationRatio() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_RATIO); } function getLiquidationPenalty() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_PENALTY); } function getRateStalePeriod() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_RATE_STALE_PERIOD); } /* ========== Exchange Related Fees ========== */ function getExchangeFeeRate(bytes32 currencyKey) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_EXCHANGE_FEE_RATE, currencyKey)) ); } /// @notice Get exchange dynamic fee related keys /// @return threshold, weight decay, rounds, and max fee function getExchangeDynamicFeeConfig() internal view returns (DynamicFeeConfig memory) { bytes32[] memory keys = new bytes32[](4); keys[0] = SETTING_EXCHANGE_DYNAMIC_FEE_THRESHOLD; keys[1] = SETTING_EXCHANGE_DYNAMIC_FEE_WEIGHT_DECAY; keys[2] = SETTING_EXCHANGE_DYNAMIC_FEE_ROUNDS; keys[3] = SETTING_EXCHANGE_MAX_DYNAMIC_FEE; uint[] memory values = flexibleStorage().getUIntValues(SETTING_CONTRACT_NAME, keys); return DynamicFeeConfig({threshold: values[0], weightDecay: values[1], rounds: values[2], maxFee: values[3]}); } /* ========== End Exchange Related Fees ========== */ function getMinimumStakeTime() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_MINIMUM_STAKE_TIME); } function getAggregatorWarningFlags() internal view returns (address) { return flexibleStorage().getAddressValue(SETTING_CONTRACT_NAME, SETTING_AGGREGATOR_WARNING_FLAGS); } function getDebtSnapshotStaleTime() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_DEBT_SNAPSHOT_STALE_TIME); } function getEtherWrapperMaxETH() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ETHER_WRAPPER_MAX_ETH); } function getEtherWrapperMintFeeRate() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ETHER_WRAPPER_MINT_FEE_RATE); } function getEtherWrapperBurnFeeRate() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ETHER_WRAPPER_BURN_FEE_RATE); } function getWrapperMaxTokenAmount(address wrapper) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_WRAPPER_MAX_TOKEN_AMOUNT, wrapper)) ); } function getWrapperMintFeeRate(address wrapper) internal view returns (int) { return flexibleStorage().getIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_WRAPPER_MINT_FEE_RATE, wrapper)) ); } function getWrapperBurnFeeRate(address wrapper) internal view returns (int) { return flexibleStorage().getIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_WRAPPER_BURN_FEE_RATE, wrapper)) ); } function getInteractionDelay(address collateral) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_INTERACTION_DELAY, collateral)) ); } function getCollapseFeeRate(address collateral) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_COLLAPSE_FEE_RATE, collateral)) ); } function getAtomicMaxVolumePerBlock() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ATOMIC_MAX_VOLUME_PER_BLOCK); } function getAtomicTwapWindow() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ATOMIC_TWAP_WINDOW); } function getAtomicEquivalentForDexPricing(bytes32 currencyKey) internal view returns (address) { return flexibleStorage().getAddressValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_ATOMIC_EQUIVALENT_FOR_DEX_PRICING, currencyKey)) ); } function getAtomicExchangeFeeRate(bytes32 currencyKey) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_ATOMIC_EXCHANGE_FEE_RATE, currencyKey)) ); } function getAtomicPriceBuffer(bytes32 currencyKey) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_ATOMIC_PRICE_BUFFER, currencyKey)) ); } function getAtomicVolatilityConsiderationWindow(bytes32 currencyKey) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW, currencyKey)) ); } function getAtomicVolatilityUpdateThreshold(bytes32 currencyKey) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_ATOMIC_VOLATILITY_UPDATE_THRESHOLD, currencyKey)) ); } } pragma experimental ABIEncoderV2; interface IBaseSynthetixBridge { function suspendInitiation() external; function resumeInitiation() external; } interface IVirtualSynth { // Views function balanceOfUnderlying(address account) external view returns (uint); function rate() external view returns (uint); function readyToSettle() external view returns (bool); function secsLeftInWaitingPeriod() external view returns (uint); function settled() external view returns (bool); function synth() external view returns (ISynth); // Mutative functions function settle(address account) external; } // https://docs.synthetix.io/contracts/source/interfaces/isynthetix interface ISynthetix { // Views function anySynthOrSNXRateIsInvalid() external view returns (bool anyRateInvalid); function availableCurrencyKeys() external view returns (bytes32[] memory); function availableSynthCount() external view returns (uint); function availableSynths(uint index) external view returns (ISynth); function collateral(address account) external view returns (uint); function collateralisationRatio(address issuer) external view returns (uint); function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint); function isWaitingPeriod(bytes32 currencyKey) external view returns (bool); function maxIssuableSynths(address issuer) external view returns (uint maxIssuable); function remainingIssuableSynths(address issuer) external view returns ( uint maxIssuable, uint alreadyIssued, uint totalSystemDebt ); function synths(bytes32 currencyKey) external view returns (ISynth); function synthsByAddress(address synthAddress) external view returns (bytes32); function totalIssuedSynths(bytes32 currencyKey) external view returns (uint); function totalIssuedSynthsExcludeOtherCollateral(bytes32 currencyKey) external view returns (uint); function transferableSynthetix(address account) external view returns (uint transferable); // Mutative Functions function burnSynths(uint amount) external; function burnSynthsOnBehalf(address burnForAddress, uint amount) external; function burnSynthsToTarget() external; function burnSynthsToTargetOnBehalf(address burnForAddress) external; function exchange( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external returns (uint amountReceived); function exchangeOnBehalf( address exchangeForAddress, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external returns (uint amountReceived); function exchangeWithTracking( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address rewardAddress, bytes32 trackingCode ) external returns (uint amountReceived); function exchangeWithTrackingForInitiator( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address rewardAddress, bytes32 trackingCode ) external returns (uint amountReceived); function exchangeOnBehalfWithTracking( address exchangeForAddress, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address rewardAddress, bytes32 trackingCode ) external returns (uint amountReceived); function exchangeWithVirtual( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, bytes32 trackingCode ) external returns (uint amountReceived, IVirtualSynth vSynth); function exchangeAtomically( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, bytes32 trackingCode ) external returns (uint amountReceived); function issueMaxSynths() external; function issueMaxSynthsOnBehalf(address issueForAddress) external; function issueSynths(uint amount) external; function issueSynthsOnBehalf(address issueForAddress, uint amount) external; function mint() external returns (bool); function settle(bytes32 currencyKey) external returns ( uint reclaimed, uint refunded, uint numEntries ); // Liquidations function liquidateDelinquentAccount(address account, uint susdAmount) external returns (bool); // Restricted Functions function mintSecondary(address account, uint amount) external; function mintSecondaryRewards(uint amount) external; function burnSecondary(address account, uint amount) external; } library VestingEntries { struct VestingEntry { uint64 endTime; uint256 escrowAmount; } struct VestingEntryWithID { uint64 endTime; uint256 escrowAmount; uint256 entryID; } } interface IRewardEscrowV2 { // Views function balanceOf(address account) external view returns (uint); function numVestingEntries(address account) external view returns (uint); function totalEscrowedAccountBalance(address account) external view returns (uint); function totalVestedAccountBalance(address account) external view returns (uint); function getVestingQuantity(address account, uint256[] calldata entryIDs) external view returns (uint); function getVestingSchedules( address account, uint256 index, uint256 pageSize ) external view returns (VestingEntries.VestingEntryWithID[] memory); function getAccountVestingEntryIDs( address account, uint256 index, uint256 pageSize ) external view returns (uint256[] memory); function getVestingEntryClaimable(address account, uint256 entryID) external view returns (uint); function getVestingEntry(address account, uint256 entryID) external view returns (uint64, uint256); // Mutative functions function vest(uint256[] calldata entryIDs) external; function createEscrowEntry( address beneficiary, uint256 deposit, uint256 duration ) external; function appendVestingEntry( address account, uint256 quantity, uint256 duration ) external; function migrateVestingSchedule(address _addressToMigrate) external; function migrateAccountEscrowBalances( address[] calldata accounts, uint256[] calldata escrowBalances, uint256[] calldata vestedBalances ) external; // Account Merging function startMergingWindow() external; function mergeAccount(address accountToMerge, uint256[] calldata entryIDs) external; function nominateAccountToMerge(address account) external; function accountMergingIsOpen() external view returns (bool); // L2 Migration function importVestingEntries( address account, uint256 escrowedAmount, VestingEntries.VestingEntry[] calldata vestingEntries ) external; // Return amount of SNX transfered to SynthetixBridgeToOptimism deposit contract function burnForMigration(address account, uint256[] calldata entryIDs) external returns (uint256 escrowedAccountBalance, VestingEntries.VestingEntry[] memory vestingEntries); } // https://docs.synthetix.io/contracts/source/interfaces/ifeepool interface IFeePool { // Views // solhint-disable-next-line func-name-mixedcase function FEE_ADDRESS() external view returns (address); function feesAvailable(address account) external view returns (uint, uint); function feePeriodDuration() external view returns (uint); function isFeesClaimable(address account) external view returns (bool); function targetThreshold() external view returns (uint); function totalFeesAvailable() external view returns (uint); function totalRewardsAvailable() external view returns (uint); // Mutative Functions function claimFees() external returns (bool); function claimOnBehalf(address claimingForAddress) external returns (bool); function closeCurrentFeePeriod() external; function closeSecondary(uint snxBackedDebt, uint debtShareSupply) external; function recordFeePaid(uint sUSDAmount) external; function setRewardsToDistribute(uint amount) external; } // SPDX-License-Identifier: MIT /** * @title iAbs_BaseCrossDomainMessenger */ interface iAbs_BaseCrossDomainMessenger { /********** * Events * **********/ event SentMessage(bytes message); event RelayedMessage(bytes32 msgHash); event FailedRelayedMessage(bytes32 msgHash); /************* * Variables * *************/ function xDomainMessageSender() external view returns (address); /******************** * Public Functions * ********************/ /** * Sends a cross domain message to the target messenger. * @param _target Target contract address. * @param _message Message to send to the target. * @param _gasLimit Gas limit for the provided message. */ function sendMessage( address _target, bytes calldata _message, uint32 _gasLimit ) external; } // Inheritance // Internal references contract BaseSynthetixBridge is Owned, MixinSystemSettings, IBaseSynthetixBridge { /* ========== ADDRESS RESOLVER CONFIGURATION ========== */ bytes32 private constant CONTRACT_EXT_MESSENGER = "ext:Messenger"; bytes32 internal constant CONTRACT_SYNTHETIX = "Synthetix"; bytes32 private constant CONTRACT_REWARDESCROW = "RewardEscrowV2"; bytes32 private constant CONTRACT_FEEPOOL = "FeePool"; bool public initiationActive; // ========== CONSTRUCTOR ========== constructor(address _owner, address _resolver) public Owned(_owner) MixinSystemSettings(_resolver) { initiationActive = true; } // ========== INTERNALS ============ function messenger() internal view returns (iAbs_BaseCrossDomainMessenger) { return iAbs_BaseCrossDomainMessenger(requireAndGetAddress(CONTRACT_EXT_MESSENGER)); } function synthetix() internal view returns (ISynthetix) { return ISynthetix(requireAndGetAddress(CONTRACT_SYNTHETIX)); } function rewardEscrowV2() internal view returns (IRewardEscrowV2) { return IRewardEscrowV2(requireAndGetAddress(CONTRACT_REWARDESCROW)); } function feePool() internal view returns (IFeePool) { return IFeePool(requireAndGetAddress(CONTRACT_FEEPOOL)); } function initiatingActive() internal view { require(initiationActive, "Initiation deactivated"); } /* ========== VIEWS ========== */ function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { bytes32[] memory existingAddresses = MixinSystemSettings.resolverAddressesRequired(); bytes32[] memory newAddresses = new bytes32[](4); newAddresses[0] = CONTRACT_EXT_MESSENGER; newAddresses[1] = CONTRACT_SYNTHETIX; newAddresses[2] = CONTRACT_REWARDESCROW; newAddresses[3] = CONTRACT_FEEPOOL; addresses = combineArrays(existingAddresses, newAddresses); } // ========== MODIFIERS ============ modifier requireInitiationActive() { initiatingActive(); _; } // ========= RESTRICTED FUNCTIONS ============== function suspendInitiation() external onlyOwner { require(initiationActive, "Initiation suspended"); initiationActive = false; emit InitiationSuspended(); } function resumeInitiation() external onlyOwner { require(!initiationActive, "Initiation not suspended"); initiationActive = true; emit InitiationResumed(); } // ========== EVENTS ========== event InitiationSuspended(); event InitiationResumed(); } interface ISynthetixBridgeToBase { // invoked by the xDomain messenger on L2 function finalizeEscrowMigration( address account, uint256 escrowedAmount, VestingEntries.VestingEntry[] calldata vestingEntries ) external; // invoked by the xDomain messenger on L2 function finalizeRewardDeposit(address from, uint amount) external; function finalizeFeePeriodClose(uint snxBackedDebt, uint debtSharesSupply) external; } // SPDX-License-Identifier: MIT /** * @title iOVM_L2DepositedToken */ interface iOVM_L2DepositedToken { /********** * Events * **********/ event WithdrawalInitiated( address indexed _from, address _to, uint256 _amount ); event DepositFinalized( address indexed _to, uint256 _amount ); /******************** * Public Functions * ********************/ function withdraw( uint _amount ) external; function withdrawTo( address _to, uint _amount ) external; /************************* * Cross-chain Functions * *************************/ function finalizeDeposit( address _to, uint _amount ) external; } // SPDX-License-Identifier: MIT /** * @title iOVM_L1TokenGateway */ interface iOVM_L1TokenGateway { /********** * Events * **********/ event DepositInitiated( address indexed _from, address _to, uint256 _amount ); event WithdrawalFinalized( address indexed _to, uint256 _amount ); /******************** * Public Functions * ********************/ function deposit( uint _amount ) external; function depositTo( address _to, uint _amount ) external; /************************* * Cross-chain Functions * *************************/ function finalizeWithdrawal( address _to, uint _amount ) external; } // Inheritance // Internal references contract SynthetixBridgeToBase is BaseSynthetixBridge, ISynthetixBridgeToBase, iOVM_L2DepositedToken { /* ========== ADDRESS RESOLVER CONFIGURATION ========== */ bytes32 public constant CONTRACT_NAME = "SynthetixBridgeToBase"; bytes32 private constant CONTRACT_BASE_SYNTHETIXBRIDGETOOPTIMISM = "base:SynthetixBridgeToOptimism"; // ========== CONSTRUCTOR ========== constructor(address _owner, address _resolver) public BaseSynthetixBridge(_owner, _resolver) {} // ========== INTERNALS ============ function synthetixBridgeToOptimism() internal view returns (address) { return requireAndGetAddress(CONTRACT_BASE_SYNTHETIXBRIDGETOOPTIMISM); } function onlyAllowFromOptimism() internal view { // ensure function only callable from the L2 bridge via messenger (aka relayer) iAbs_BaseCrossDomainMessenger _messenger = messenger(); require(msg.sender == address(_messenger), "Only the relayer can call this"); require(_messenger.xDomainMessageSender() == synthetixBridgeToOptimism(), "Only the L1 bridge can invoke"); } modifier onlyOptimismBridge() { onlyAllowFromOptimism(); _; } // ========== VIEWS ========== function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { bytes32[] memory existingAddresses = BaseSynthetixBridge.resolverAddressesRequired(); bytes32[] memory newAddresses = new bytes32[](1); newAddresses[0] = CONTRACT_BASE_SYNTHETIXBRIDGETOOPTIMISM; addresses = combineArrays(existingAddresses, newAddresses); } // ========== PUBLIC FUNCTIONS ========= // invoked by user on L2 function withdraw(uint amount) external requireInitiationActive { _initiateWithdraw(msg.sender, amount); } function withdrawTo(address to, uint amount) external requireInitiationActive { _initiateWithdraw(to, amount); } function _initiateWithdraw(address to, uint amount) private { require(synthetix().transferableSynthetix(msg.sender) >= amount, "Not enough transferable SNX"); // instruct L2 Synthetix to burn this supply synthetix().burnSecondary(msg.sender, amount); // create message payload for L1 iOVM_L1TokenGateway bridgeToOptimism; bytes memory messageData = abi.encodeWithSelector(bridgeToOptimism.finalizeWithdrawal.selector, to, amount); // relay the message to Bridge on L1 via L2 Messenger messenger().sendMessage( synthetixBridgeToOptimism(), messageData, uint32(getCrossDomainMessageGasLimit(CrossDomainMessageGasLimits.Withdrawal)) ); emit iOVM_L2DepositedToken.WithdrawalInitiated(msg.sender, to, amount); } // ========= RESTRICTED FUNCTIONS ============== function finalizeEscrowMigration( address account, uint256 escrowedAmount, VestingEntries.VestingEntry[] calldata vestingEntries ) external onlyOptimismBridge { IRewardEscrowV2 rewardEscrow = rewardEscrowV2(); // First, mint the escrowed SNX that are being migrated synthetix().mintSecondary(address(rewardEscrow), escrowedAmount); rewardEscrow.importVestingEntries(account, escrowedAmount, vestingEntries); emit ImportedVestingEntries(account, escrowedAmount, vestingEntries); } // invoked by Messenger on L2 function finalizeDeposit(address to, uint256 amount) external onlyOptimismBridge { // now tell Synthetix to mint these tokens, deposited in L1, into the specified account for L2 synthetix().mintSecondary(to, amount); emit iOVM_L2DepositedToken.DepositFinalized(to, amount); } // invoked by Messenger on L2 function finalizeRewardDeposit(address from, uint256 amount) external onlyOptimismBridge { // now tell Synthetix to mint these tokens, deposited in L1, into reward escrow on L2 synthetix().mintSecondaryRewards(amount); emit RewardDepositFinalized(from, amount); } // invoked by Messenger on L2 function finalizeFeePeriodClose(uint256 snxBackedAmount, uint256 totalDebtShares) external onlyOptimismBridge { // now tell Synthetix to mint these tokens, deposited in L1, into reward escrow on L2 feePool().closeSecondary(snxBackedAmount, totalDebtShares); emit FeePeriodCloseFinalized(snxBackedAmount, totalDebtShares); } // ========== EVENTS ========== event ImportedVestingEntries( address indexed account, uint256 escrowedAmount, VestingEntries.VestingEntry[] vestingEntries ); event RewardDepositFinalized(address from, uint256 amount); event FeePeriodCloseFinalized(uint snxBackedAmount, uint totalDebtShares); }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_resolver","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"name","type":"bytes32"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"CacheUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"DepositFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"snxBackedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalDebtShares","type":"uint256"}],"name":"FeePeriodCloseFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"escrowedAmount","type":"uint256"},{"components":[{"internalType":"uint64","name":"endTime","type":"uint64"},{"internalType":"uint256","name":"escrowAmount","type":"uint256"}],"indexed":false,"internalType":"struct VestingEntries.VestingEntry[]","name":"vestingEntries","type":"tuple[]"}],"name":"ImportedVestingEntries","type":"event"},{"anonymous":false,"inputs":[],"name":"InitiationResumed","type":"event"},{"anonymous":false,"inputs":[],"name":"InitiationSuspended","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardDepositFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"WithdrawalInitiated","type":"event"},{"constant":true,"inputs":[],"name":"CONTRACT_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"finalizeDeposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"escrowedAmount","type":"uint256"},{"components":[{"internalType":"uint64","name":"endTime","type":"uint64"},{"internalType":"uint256","name":"escrowAmount","type":"uint256"}],"internalType":"struct VestingEntries.VestingEntry[]","name":"vestingEntries","type":"tuple[]"}],"name":"finalizeEscrowMigration","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"snxBackedAmount","type":"uint256"},{"internalType":"uint256","name":"totalDebtShares","type":"uint256"}],"name":"finalizeFeePeriodClose","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"finalizeRewardDeposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"initiationActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isResolverCached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","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":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"rebuildCache","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"resolver","outputs":[{"internalType":"contract AddressResolver","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"resolverAddressesRequired","outputs":[{"internalType":"bytes32[]","name":"addresses","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"resumeInitiation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"suspendInitiation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162001e5138038062001e5183398101604081905262000034916200010d565b81818080836001600160a01b0381166200006b5760405162461bcd60e51b81526004016200006290620001c9565b60405180910390fd5b600080546001600160a01b0319166001600160a01b0383161781556040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91620000b8918490620001a3565b60405180910390a150600280546001600160a01b0319166001600160a01b039290921691909117905550506004805460ff191660011790555062000224915050565b805162000107816200020a565b92915050565b600080604083850312156200012157600080fd5b60006200012f8585620000fa565b92505060206200014285828601620000fa565b9150509250929050565b6200015781620001f6565b82525050565b6200015781620001e4565b600062000177601983620001db565b7f4f776e657220616464726573732063616e6e6f74206265203000000000000000815260200192915050565b60408101620001b382856200014c565b620001c260208301846200015d565b9392505050565b60208082528101620001078162000168565b90815260200190565b60006001600160a01b03821662000107565b6000620001078260006200010782620001e4565b6200021581620001e4565b81146200022157600080fd5b50565b611c1d80620002346000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c8063614d08f8116100a2578063899ffef411610071578063899ffef4146101ee5780638d6e9a5b146102035780638da5cb5b14610216578063a616cdfb1461021e578063f97824fe1461023157610116565b8063614d08f8146101c1578063698a26b2146101d657806374185360146101de57806379ba5097146101e657610116565b806325aae563116100e957806325aae563146101765780632af64bd3146101895780632e1a7d4d146101915780633872dda3146101a457806353a47bb7146101ac57610116565b806304f3bcec1461011b578063100be6d4146101395780631627540c1461014e578063205c287814610163575b600080fd5b610123610244565b6040516101309190611a26565b60405180910390f35b610141610253565b60405161013091906119ce565b61016161015c366004611368565b61025c565b005b6101616101713660046113ac565b6102ba565b61016161018436600461148a565b6102d0565b61014161037c565b61016161019f36600461144e565b610494565b6101616104a9565b6101b4610511565b60405161013091906118ef565b6101c9610520565b60405161013091906119dc565b61016161053c565b61016161059f565b6101616106f1565b6101f661078d565b60405161013091906119bd565b6101616102113660046113ac565b610809565b6101b46108bd565b61016161022c3660046113ac565b6108cc565b61016161023f3660046113e6565b61096a565b6002546001600160a01b031681565b60045460ff1681565b610264610a95565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906102af9083906118ef565b60405180910390a150565b6102c2610ac1565b6102cc8282610ae3565b5050565b6102d8610d04565b6102e0610de0565b6001600160a01b03166373941b9683836040518363ffffffff1660e01b815260040161030d9291906119f8565b600060405180830381600087803b15801561032757600080fd5b505af115801561033b573d6000803e3d6000fd5b505050507f64691ff866d6248d6d89e8c1b6c92df685ddf8224377dc6f1e928ef732e55ace82826040516103709291906119f8565b60405180910390a15050565b6000606061038861078d565b905060005b815181101561048a5760008282815181106103a457fe5b602090810291909101810151600081815260039092526040918290205460025492516321f8a72160e01b81529193506001600160a01b039081169216906321f8a721906103f59085906004016119dc565b60206040518083038186803b15801561040d57600080fd5b505afa158015610421573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610445919081019061138e565b6001600160a01b031614158061047057506000818152600360205260409020546001600160a01b0316155b156104815760009350505050610491565b5060010161038d565b5060019150505b90565b61049c610ac1565b6104a63382610ae3565b50565b6104b1610a95565b60045460ff166104dc5760405162461bcd60e51b81526004016104d390611a65565b60405180910390fd5b6004805460ff191690556040517f43e00f2c8f8651a29db34d34fb689573423f8aaae8f9d32e3e871b4c35c6254690600090a1565b6001546001600160a01b031681565b7453796e746865746978427269646765546f4261736560581b81565b610544610a95565b60045460ff16156105675760405162461bcd60e51b81526004016104d390611a45565b6004805460ff191660011790556040517f7c88488c18e2ff121a34a4a2a44990557a5b76ab1ceb6bd95ebe7d419c7575f490600090a1565b60606105a961078d565b905060005b81518110156102cc5760008282815181106105c557fe5b602002602001015190506000600260009054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200161060791906118e4565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401610633929190611a06565b60206040518083038186803b15801561064b57600080fd5b505afa15801561065f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610683919081019061138e565b6000838152600360205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68906106df90849084906119ea565b60405180910390a150506001016105ae565b6001546001600160a01b0316331461071b5760405162461bcd60e51b81526004016104d390611a55565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9261075e926001600160a01b039182169291169061192d565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b606080610798610dfa565b60408051600180825281830190925291925060609190602080830190803883390190505090507f626173653a53796e746865746978427269646765546f4f7074696d69736d0000816000815181106107ec57fe5b6020026020010181815250506108028282610ebf565b9250505090565b610811610d04565b610819610f7b565b6001600160a01b031663666ed4f183836040518363ffffffff1660e01b8152600401610846929190611977565b600060405180830381600087803b15801561086057600080fd5b505af1158015610874573d6000803e3d6000fd5b50505050816001600160a01b03167f162eb12ad2bd8b6ca7960f162208414ab3bc2da9f37953788ffd8cf850c3492b826040516108b191906119dc565b60405180910390a25050565b6000546001600160a01b031681565b6108d4610d04565b6108dc610f7b565b6001600160a01b031663d8a1f76f826040518263ffffffff1660e01b815260040161090791906119dc565b600060405180830381600087803b15801561092157600080fd5b505af1158015610935573d6000803e3d6000fd5b505050507f3b30e867826d81d6591924b1675cfdcac994f0199eed66250d8c834b3b0ed2168282604051610370929190611977565b610972610d04565b600061097c610f92565b9050610986610f7b565b6001600160a01b031663666ed4f182866040518363ffffffff1660e01b81526004016109b3929190611977565b600060405180830381600087803b1580156109cd57600080fd5b505af11580156109e1573d6000803e3d6000fd5b505060405163cd7b43dd60e01b81526001600160a01b038416925063cd7b43dd9150610a17908890889088908890600401611985565b600060405180830381600087803b158015610a3157600080fd5b505af1158015610a45573d6000803e3d6000fd5b50505050846001600160a01b03167f7538b9bce825b4555048bb2f80c04ee79b5ffc422f39b959994a27c21c32c8d1858585604051610a8693929190611ad5565b60405180910390a25050505050565b6000546001600160a01b03163314610abf5760405162461bcd60e51b81526004016104d390611a85565b565b60045460ff16610abf5760405162461bcd60e51b81526004016104d390611a75565b80610aec610f7b565b6001600160a01b0316636ac0bf9c336040518263ffffffff1660e01b8152600401610b1791906118fd565b60206040518083038186803b158015610b2f57600080fd5b505afa158015610b43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b67919081019061146c565b1015610b855760405162461bcd60e51b81526004016104d390611ac5565b610b8d610f7b565b6001600160a01b031663edef719a33836040518363ffffffff1660e01b8152600401610bba92919061190b565b600060405180830381600087803b158015610bd457600080fd5b505af1158015610be8573d6000803e3d6000fd5b50506040516000925060609150637a7bda0d60e11b90610c0e9086908690602401611977565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529050610c4a610fae565b6001600160a01b0316633dbb202b610c60610fc9565b83610c6b6003610ff4565b6040518463ffffffff1660e01b8152600401610c8993929190611948565b600060405180830381600087803b158015610ca357600080fd5b505af1158015610cb7573d6000803e3d6000fd5b50505050336001600160a01b03167fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da28585604051610cf6929190611977565b60405180910390a250505050565b6000610d0e610fae565b9050336001600160a01b03821614610d385760405162461bcd60e51b81526004016104d390611a95565b610d40610fc9565b6001600160a01b0316816001600160a01b0316636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b158015610d8257600080fd5b505afa158015610d96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610dba919081019061138e565b6001600160a01b0316146104a65760405162461bcd60e51b81526004016104d390611aa5565b6000610df566119959541bdbdb60ca1b61109c565b905090565b606080610e056110f9565b60408051600480825260a0820190925291925060609190602082016080803883390190505090506c32bc3a1d26b2b9b9b2b733b2b960991b81600081518110610e4a57fe5b602002602001018181525050680a6f2dce8d0cae8d2f60bb1b81600181518110610e7057fe5b6020026020010181815250506d2932bbb0b93222b9b1b937bbab1960911b81600281518110610e9b57fe5b60200260200101818152505066119959541bdbdb60ca1b816003815181106107ec57fe5b60608151835101604051908082528060200260200182016040528015610eef578160200160208202803883390190505b50905060005b8351811015610f3157838181518110610f0a57fe5b6020026020010151828281518110610f1e57fe5b6020908102919091010152600101610ef5565b5060005b8251811015610f7457828181518110610f4a57fe5b6020026020010151828286510181518110610f6157fe5b6020908102919091010152600101610f35565b5092915050565b6000610df5680a6f2dce8d0cae8d2f60bb1b61109c565b6000610df56d2932bbb0b93222b9b1b937bbab1960911b61109c565b6000610df56c32bc3a1d26b2b9b9b2b733b2b960991b61109c565b6000610df57f626173653a53796e746865746978427269646765546f4f7074696d69736d000061109c565b6000610ffe61114a565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b61102785611167565b6040518363ffffffff1660e01b81526004016110449291906119f8565b60206040518083038186803b15801561105c57600080fd5b505afa158015611070573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611094919081019061146c565b90505b919050565b60008181526003602090815260408083205490516001600160a01b0390911691821515916110cc918691016118c4565b60405160208183030381529060405290610f745760405162461bcd60e51b81526004016104d39190611a34565b604080516001808252818301909252606091602080830190803883390190505090506e466c657869626c6553746f7261676560881b8160008151811061113b57fe5b60200260200101818152505090565b6000610df56e466c657869626c6553746f7261676560881b61109c565b60008082600581111561117657fe5b14156111a357507f63726f7373446f6d61696e4465706f7369744761734c696d6974000000000000611097565b60018260058111156111b157fe5b14156111de57507f63726f7373446f6d61696e457363726f774761734c696d697400000000000000611097565b60028260058111156111ec57fe5b141561121957507f63726f7373446f6d61696e5265776172644761734c696d697400000000000000611097565b600382600581111561122757fe5b141561125457507f63726f7373446f6d61696e5769746864726177616c4761734c696d6974000000611097565b600582600581111561126257fe5b141561128f57507f63726f7373446f6d61696e52656c61794761734c696d69740000000000000000611097565b600482600581111561129d57fe5b14156112ca57507f63726f7373446f6d61696e436c6f73654761734c696d69740000000000000000611097565b60405162461bcd60e51b81526004016104d390611ab5565b80356112ed81611bb4565b92915050565b80516112ed81611bb4565b60008083601f84011261131057600080fd5b50813567ffffffffffffffff81111561132857600080fd5b60208301915083604082028301111561134057600080fd5b9250929050565b80356112ed81611bc8565b80516112ed81611bc8565b80356112ed81611bd1565b60006020828403121561137a57600080fd5b600061138684846112e2565b949350505050565b6000602082840312156113a057600080fd5b600061138684846112f3565b600080604083850312156113bf57600080fd5b60006113cb85856112e2565b92505060206113dc85828601611347565b9150509250929050565b600080600080606085870312156113fc57600080fd5b600061140887876112e2565b945050602061141987828801611347565b935050604085013567ffffffffffffffff81111561143657600080fd5b611442878288016112fe565b95989497509550505050565b60006020828403121561146057600080fd5b60006113868484611347565b60006020828403121561147e57600080fd5b60006113868484611352565b6000806040838503121561149d57600080fd5b60006113cb8585611347565b60006114b58383611598565b505060200190565b60006114c98383611879565b505060400190565b6114da81611b6c565b82525050565b6114da81611b3a565b60006114f482611b05565b6114fe8185611b0f565b935061150983611aff565b8060005b8381101561153757815161152188826114a9565b975061152c83611aff565b92505060010161150d565b509495945050505050565b600061154e8385611b0f565b935061155982610491565b8060005b858110156115375761156f8284611b18565b61157988826114bd565b975061158483611b09565b92505060010161155d565b6114da81611b45565b6114da81610491565b6114da6115ad82610491565b610491565b60006115bd82611b05565b6115c78185611b0f565b93506115d7818560208601611b7e565b6115e081611baa565b9093019392505050565b6114da81611b73565b6000611600601883611b0f565b7f496e6974696174696f6e206e6f742073757370656e6465640000000000000000815260200192915050565b6000611639603583611b0f565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527402063616e20616363657074206f776e65727368697605c1b602082015260400192915050565b6000611690601483611b0f565b73125b9a5d1a585d1a5bdb881cdd5cdc195b99195960621b815260200192915050565b60006116c0601183611097565b70026b4b9b9b4b7339030b2323932b9b99d1607d1b815260110192915050565b60006116ed601683611b0f565b75125b9a5d1a585d1a5bdb8819195858dd1a5d985d195960521b815260200192915050565b600061171f602f83611b0f565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681526e37b936903a3434b99030b1ba34b7b760891b602082015260400192915050565b6000611770601e83611b0f565b7f4f6e6c79207468652072656c617965722063616e2063616c6c20746869730000815260200192915050565b60006117a9601d83611b0f565b7f4f6e6c7920746865204c31206272696467652063616e20696e766f6b65000000815260200192915050565b60006117e2601983611097565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b600061181b601683611b0f565b75556e6b6e6f776e20676173206c696d6974207479706560501b815260200192915050565b600061184d601b83611b0f565b7f4e6f7420656e6f756768207472616e7366657261626c6520534e580000000000815260200192915050565b604082016118878280611b2b565b61189184826118bb565b5061189f6020830183611b1c565b6118ac6020850182611598565b50505050565b6114da81611b56565b6114da81611b5f565b60006118cf826116b3565b91506118db82846115a1565b50602001919050565b60006118cf826117d5565b602081016112ed82846114e0565b602081016112ed82846114d1565b6040810161191982856114d1565b6119266020830184611598565b9392505050565b6040810161193b82856114e0565b61192660208301846114e0565b6060810161195682866114e0565b818103602083015261196881856115b2565b905061138660408301846118b2565b6040810161191982856114e0565b6060810161199382876114e0565b6119a06020830186611598565b81810360408301526119b3818486611542565b9695505050505050565b6020808252810161192681846114e9565b602081016112ed828461158f565b602081016112ed8284611598565b6040810161193b8285611598565b604081016119198285611598565b60408101611a148285611598565b818103602083015261138681846115b2565b602081016112ed82846115ea565b6020808252810161192681846115b2565b60208082528101611094816115f3565b602080825281016110948161162c565b6020808252810161109481611683565b60208082528101611094816116e0565b6020808252810161109481611712565b6020808252810161109481611763565b602080825281016110948161179c565b602080825281016110948161180e565b6020808252810161109481611840565b60408101611ae38286611598565b8181036020830152611af6818486611542565b95945050505050565b60200190565b5190565b60400190565b90815260200190565b5090565b60006119266020840184611347565b6000611926602084018461135d565b600061109482611b4a565b151590565b6001600160a01b031690565b63ffffffff1690565b67ffffffffffffffff1690565b6000611094825b600061109482611b3a565b60005b83811015611b99578181015183820152602001611b81565b838111156118ac5750506000910152565b601f01601f191690565b611bbd81611b3a565b81146104a657600080fd5b611bbd81610491565b611bbd81611b5f56fea365627a7a7231582047a4543b59643bd36d6ee76be769d462f977f4952ba6d60ed1fbb4e61fcb3a996c6578706572696d656e74616cf564736f6c63430005100040000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe0000000000000000000000001cb059b7e74fd21665968c908806143e744d5f30
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe0000000000000000000000001cb059b7e74fd21665968c908806143e744d5f30
-----Decoded View---------------
Arg [0] : _owner (address): 0xde910777c787903f78c89e7a0bf7f4c435cbb1fe
Arg [1] : _resolver (address): 0x1cb059b7e74fd21665968c908806143e744d5f30
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe
Arg [1] : 0000000000000000000000001cb059b7e74fd21665968c908806143e744d5f30
Library Used
SafeDecimalMath : 0x0142f40c25ce1f1177ed131101fa19217396cb88
SystemSettingsLib : 0x478d479bac034f89fa28d8d2ab430ec973a3a0ac
SignedSafeDecimalMath : 0x253914cf059f4c3e277c28060c404acfc38fb6e2
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.