Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 957 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Deposit ERC20To | 14778643 | 967 days ago | IN | 0 ETH | 0.00046096 | ||||
Deposit ERC20To | 14762633 | 969 days ago | IN | 0 ETH | 0.00262884 | ||||
Deposit | 14750784 | 971 days ago | IN | 0 ETH | 0.00125941 | ||||
Deposit | 14750768 | 971 days ago | IN | 0 ETH | 0.00114565 | ||||
Deposit | 14750458 | 971 days ago | IN | 0 ETH | 0.00065839 | ||||
Migrate Escrow | 14750363 | 971 days ago | IN | 0 ETH | 0.00118861 | ||||
Deposit | 14749302 | 971 days ago | IN | 0 ETH | 0.01102528 | ||||
Deposit | 14748884 | 971 days ago | IN | 0 ETH | 0.00931898 | ||||
Deposit | 14748293 | 972 days ago | IN | 0 ETH | 0.01168543 | ||||
Deposit | 14748029 | 972 days ago | IN | 0 ETH | 0.00796104 | ||||
Deposit | 14747665 | 972 days ago | IN | 0 ETH | 0.00924853 | ||||
Deposit | 14747577 | 972 days ago | IN | 0 ETH | 0.00996929 | ||||
Deposit | 14747566 | 972 days ago | IN | 0 ETH | 0.00933042 | ||||
Deposit | 14747531 | 972 days ago | IN | 0 ETH | 0.01178557 | ||||
Deposit | 14747174 | 972 days ago | IN | 0 ETH | 0.01210147 | ||||
Deposit | 14746827 | 972 days ago | IN | 0 ETH | 0.00992757 | ||||
Deposit | 14746722 | 972 days ago | IN | 0 ETH | 0.01104535 | ||||
Deposit | 14746167 | 972 days ago | IN | 0 ETH | 0.016515 | ||||
Deposit | 14745917 | 972 days ago | IN | 0 ETH | 0.01848198 | ||||
Deposit | 14745853 | 972 days ago | IN | 0 ETH | 0.01853979 | ||||
Deposit | 14745637 | 972 days ago | IN | 0 ETH | 0.02434868 | ||||
Migrate Escrow | 14745553 | 972 days ago | IN | 0 ETH | 0.01152253 | ||||
Deposit | 14744858 | 972 days ago | IN | 0 ETH | 0.0147314 | ||||
Deposit | 14744539 | 972 days ago | IN | 0 ETH | 0.01835846 | ||||
Deposit | 14744524 | 972 days ago | IN | 0 ETH | 0.01767608 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
SynthetixBridgeToOptimism
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 Etherscan.io on 2022-03-17 */ /* ____ __ __ __ _ / __/__ __ ___ / /_ / / ___ / /_ (_)__ __ _\ \ / // // _ \/ __// _ \/ -_)/ __// / \ \ / /___/ \_, //_//_/\__//_//_/\__/ \__//_/ /_\_\ /___/ * Synthetix: SynthetixBridgeToOptimism.sol * * Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/SynthetixBridgeToOptimism.sol * Docs: https://docs.synthetix.io/contracts/SynthetixBridgeToOptimism * * Contract Dependencies: * - BaseSynthetixBridge * - IAddressResolver * - IBaseSynthetixBridge * - ISynthetixBridgeToOptimism * - MixinResolver * - MixinSystemSettings * - Owned * - iOVM_L1TokenGateway * Libraries: * - Address * - SafeERC20 * - SafeMath * - 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 ISynthetixBridgeToOptimism { function closeFeePeriod(uint snxBackedDebt, uint debtSharesSupply) external; function migrateEscrow(uint256[][] calldata entryIDs) external; function depositReward(uint amount) external; function depositAndMigrateEscrow(uint256 depositAmount, uint256[][] calldata entryIDs) 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; } /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see `ERC20Detailed`. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a `Transfer` event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through `transferFrom`. This is * zero by default. * * This value changes when `approve` or `transferFrom` are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * > Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an `Approval` event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a `Transfer` event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to `approve`. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } /** * @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; } } /** * @dev Collection of functions related to the address type, */ library Address { /** * @dev Returns true if `account` is a contract. * * This test is non-exhaustive, and there may be false-negatives: during the * execution of a contract's constructor, its address will be reported as * not containing a contract. * * > It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. */ function isContract(address account) internal view returns (bool) { // This method relies in extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. // A Solidity high level call has three parts: // 1. The target address is checked to verify it contains contract code // 2. The call itself is made, and success asserted // 3. The return value is decoded, which in turn checks the size of the returned data. // solhint-disable-next-line max-line-length require(address(token).isContract(), "SafeERC20: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } 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; } // Inheritance // Internal references contract SynthetixBridgeToOptimism is BaseSynthetixBridge, ISynthetixBridgeToOptimism, iOVM_L1TokenGateway { using SafeERC20 for IERC20; /* ========== ADDRESS RESOLVER CONFIGURATION ========== */ bytes32 public constant CONTRACT_NAME = "SynthetixBridgeToOptimism"; bytes32 private constant CONTRACT_ISSUER = "Issuer"; bytes32 private constant CONTRACT_REWARDSDISTRIBUTION = "RewardsDistribution"; bytes32 private constant CONTRACT_OVM_SYNTHETIXBRIDGETOBASE = "ovm:SynthetixBridgeToBase"; bytes32 private constant CONTRACT_SYNTHETIXBRIDGEESCROW = "SynthetixBridgeEscrow"; uint8 private constant MAX_ENTRIES_MIGRATED_PER_MESSAGE = 26; // ========== CONSTRUCTOR ========== constructor(address _owner, address _resolver) public BaseSynthetixBridge(_owner, _resolver) {} // ========== INTERNALS ============ function synthetixERC20() internal view returns (IERC20) { return IERC20(requireAndGetAddress(CONTRACT_SYNTHETIX)); } function issuer() internal view returns (IIssuer) { return IIssuer(requireAndGetAddress(CONTRACT_ISSUER)); } function rewardsDistribution() internal view returns (address) { return requireAndGetAddress(CONTRACT_REWARDSDISTRIBUTION); } function synthetixBridgeToBase() internal view returns (address) { return requireAndGetAddress(CONTRACT_OVM_SYNTHETIXBRIDGETOBASE); } function synthetixBridgeEscrow() internal view returns (address) { return requireAndGetAddress(CONTRACT_SYNTHETIXBRIDGEESCROW); } function hasZeroDebt() internal view { require(issuer().debtBalanceOf(msg.sender, "sUSD") == 0, "Cannot deposit or migrate with debt"); } /* ========== VIEWS ========== */ function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { bytes32[] memory existingAddresses = BaseSynthetixBridge.resolverAddressesRequired(); bytes32[] memory newAddresses = new bytes32[](4); newAddresses[0] = CONTRACT_ISSUER; newAddresses[1] = CONTRACT_REWARDSDISTRIBUTION; newAddresses[2] = CONTRACT_OVM_SYNTHETIXBRIDGETOBASE; newAddresses[3] = CONTRACT_SYNTHETIXBRIDGEESCROW; addresses = combineArrays(existingAddresses, newAddresses); } // ========== MODIFIERS ============ modifier requireZeroDebt() { hasZeroDebt(); _; } // ========== PUBLIC FUNCTIONS ========= function deposit(uint256 amount) external requireInitiationActive requireZeroDebt { _initiateDeposit(msg.sender, amount); } function depositTo(address to, uint amount) external requireInitiationActive requireZeroDebt { _initiateDeposit(to, amount); } function migrateEscrow(uint256[][] memory entryIDs) public requireInitiationActive requireZeroDebt { _migrateEscrow(entryIDs); } // invoked by a generous user on L1 function depositReward(uint amount) external requireInitiationActive { // move the SNX into the deposit escrow synthetixERC20().transferFrom(msg.sender, synthetixBridgeEscrow(), amount); _depositReward(msg.sender, amount); } // forward any accidental tokens sent here to the escrow function forwardTokensToEscrow(address token) external { IERC20 erc20 = IERC20(token); erc20.safeTransfer(synthetixBridgeEscrow(), erc20.balanceOf(address(this))); } // ========= RESTRICTED FUNCTIONS ============== function closeFeePeriod(uint snxBackedAmount, uint totalDebtShares) external requireInitiationActive { require(msg.sender == address(feePool()), "Only the fee pool can call this"); ISynthetixBridgeToBase bridgeToBase; bytes memory messageData = abi.encodeWithSelector(bridgeToBase.finalizeFeePeriodClose.selector, snxBackedAmount, totalDebtShares); // relay the message to this contract on L2 via L1 Messenger messenger().sendMessage( synthetixBridgeToBase(), messageData, uint32(getCrossDomainMessageGasLimit(CrossDomainMessageGasLimits.CloseFeePeriod)) ); emit FeePeriodClosed(snxBackedAmount, totalDebtShares); } // invoked by Messenger on L1 after L2 waiting period elapses function finalizeWithdrawal(address to, uint256 amount) external { // ensure function only callable from L2 Bridge via messenger (aka relayer) require(msg.sender == address(messenger()), "Only the relayer can call this"); require(messenger().xDomainMessageSender() == synthetixBridgeToBase(), "Only the L2 bridge can invoke"); // transfer amount back to user synthetixERC20().transferFrom(synthetixBridgeEscrow(), to, amount); // no escrow actions - escrow remains on L2 emit iOVM_L1TokenGateway.WithdrawalFinalized(to, amount); } // invoked by RewardsDistribution on L1 (takes SNX) function notifyRewardAmount(uint256 amount) external { require(msg.sender == address(rewardsDistribution()), "Caller is not RewardsDistribution contract"); // NOTE: transfer SNX to synthetixBridgeEscrow because RewardsDistribution transfers them initially to this contract. synthetixERC20().transfer(synthetixBridgeEscrow(), amount); // to be here means I've been given an amount of SNX to distribute onto L2 _depositReward(msg.sender, amount); } function depositAndMigrateEscrow(uint256 depositAmount, uint256[][] memory entryIDs) public requireInitiationActive requireZeroDebt { if (entryIDs.length > 0) { _migrateEscrow(entryIDs); } if (depositAmount > 0) { _initiateDeposit(msg.sender, depositAmount); } } // ========== PRIVATE/INTERNAL FUNCTIONS ========= function _depositReward(address _from, uint256 _amount) internal { // create message payload for L2 ISynthetixBridgeToBase bridgeToBase; bytes memory messageData = abi.encodeWithSelector(bridgeToBase.finalizeRewardDeposit.selector, _from, _amount); // relay the message to this contract on L2 via L1 Messenger messenger().sendMessage( synthetixBridgeToBase(), messageData, uint32(getCrossDomainMessageGasLimit(CrossDomainMessageGasLimits.Reward)) ); emit RewardDepositInitiated(_from, _amount); } function _initiateDeposit(address _to, uint256 _depositAmount) private { // Transfer SNX to L2 // First, move the SNX into the deposit escrow synthetixERC20().transferFrom(msg.sender, synthetixBridgeEscrow(), _depositAmount); // create message payload for L2 iOVM_L2DepositedToken bridgeToBase; bytes memory messageData = abi.encodeWithSelector(bridgeToBase.finalizeDeposit.selector, _to, _depositAmount); // relay the message to this contract on L2 via L1 Messenger messenger().sendMessage( synthetixBridgeToBase(), messageData, uint32(getCrossDomainMessageGasLimit(CrossDomainMessageGasLimits.Deposit)) ); emit iOVM_L1TokenGateway.DepositInitiated(msg.sender, _to, _depositAmount); } function _migrateEscrow(uint256[][] memory _entryIDs) private { // loop through the entryID array for (uint256 i = 0; i < _entryIDs.length; i++) { // Cannot send more than MAX_ENTRIES_MIGRATED_PER_MESSAGE entries due to ovm gas restrictions require(_entryIDs[i].length <= MAX_ENTRIES_MIGRATED_PER_MESSAGE, "Exceeds max entries per migration"); // Burn their reward escrow first // Note: escrowSummary would lose the fidelity of the weekly escrows, so this may not be sufficient uint256 escrowedAccountBalance; VestingEntries.VestingEntry[] memory vestingEntries; (escrowedAccountBalance, vestingEntries) = rewardEscrowV2().burnForMigration(msg.sender, _entryIDs[i]); // if there is an escrow amount to be migrated if (escrowedAccountBalance > 0) { // NOTE: transfer SNX to synthetixBridgeEscrow because burnForMigration() transfers them to this contract. synthetixERC20().transfer(synthetixBridgeEscrow(), escrowedAccountBalance); // create message payload for L2 ISynthetixBridgeToBase bridgeToBase; bytes memory messageData = abi.encodeWithSelector( bridgeToBase.finalizeEscrowMigration.selector, msg.sender, escrowedAccountBalance, vestingEntries ); // relay the message to this contract on L2 via L1 Messenger messenger().sendMessage( synthetixBridgeToBase(), messageData, uint32(getCrossDomainMessageGasLimit(CrossDomainMessageGasLimits.Escrow)) ); emit ExportedVestingEntries(msg.sender, escrowedAccountBalance, vestingEntries); } } } // ========== EVENTS ========== event ExportedVestingEntries( address indexed account, uint256 escrowedAccountBalance, VestingEntries.VestingEntry[] vestingEntries ); event RewardDepositInitiated(address indexed account, uint256 amount); event FeePeriodClosed(uint snxBackedDebt, 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":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"DepositInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"escrowedAccountBalance","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":"ExportedVestingEntries","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"snxBackedDebt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalDebtShares","type":"uint256"}],"name":"FeePeriodClosed","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":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardDepositInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"WithdrawalFinalized","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":"uint256","name":"snxBackedAmount","type":"uint256"},{"internalType":"uint256","name":"totalDebtShares","type":"uint256"}],"name":"closeFeePeriod","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256[][]","name":"entryIDs","type":"uint256[][]"}],"name":"depositAndMigrateEscrow","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositReward","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"finalizeWithdrawal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"forwardTokensToEscrow","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":"uint256[][]","name":"entryIDs","type":"uint256[][]"}],"name":"migrateEscrow","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":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"payable":false,"stateMutability":"nonpayable","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"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162002a7438038062002a7483398101604081905262000034916200010d565b81818080836001600160a01b0381166200006b5760405162461bcd60e51b81526004016200006290620001c9565b60405180910390fd5b600080546001600160a01b0319166001600160a01b0383161781556040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91620000b8918490620001a3565b60405180910390a150600280546001600160a01b0319166001600160a01b039290921691909117905550506004805460ff191660011790555062000224915050565b805162000107816200020a565b92915050565b600080604083850312156200012157600080fd5b60006200012f8585620000fa565b92505060206200014285828601620000fa565b9150509250929050565b6200015781620001f6565b82525050565b6200015781620001e4565b600062000177601983620001db565b7f4f776e657220616464726573732063616e6e6f74206265203000000000000000815260200192915050565b60408101620001b382856200014c565b620001c260208301846200015d565b9392505050565b60208082528101620001078162000168565b90815260200190565b60006001600160a01b03821662000107565b6000620001078260006200010782620001e4565b6200021581620001e4565b81146200022157600080fd5b50565b61284080620002346000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c8063698a26b2116100b85780639a9e7f961161007c5780639a9e7f961461022c578063a18e23071461023f578063b6b55f2514610252578063b9958ab814610265578063f4f7b41a14610278578063ffaad6a51461028b57610137565b8063698a26b2146101f757806374185360146101ff57806379ba509714610207578063899ffef41461020f5780638da5cb5b1461022457610137565b80633872dda3116100ff5780633872dda31461019f5780633c6b16ab146101a7578063462286d5146101ba57806353a47bb7146101cd578063614d08f8146101e257610137565b806304f3bcec1461013c578063100be6d41461015a5780631627540c1461016f5780631e2720ff146101845780632af64bd314610197575b600080fd5b61014461029e565b60405161015191906125ca565b60405180910390f35b6101626102ad565b6040516101519190612572565b61018261017d366004611c2c565b6102b6565b005b610182610192366004611cfd565b610314565b6101626103ba565b6101826104d2565b6101826101b5366004611cfd565b61053a565b6101826101c8366004611c2c565b6105ae565b6101d5610651565b6040516101519190612448565b6101ea610660565b6040516101519190612580565b610182610684565b6101826106e7565b610182610839565b6102176108d5565b6040516101519190612561565b6101d56109d3565b61018261023a366004611caa565b6109e2565b61018261024d366004611d39565b6109fb565b610182610260366004611cfd565b610a2b565b610182610273366004611dc9565b610a45565b610182610286366004611c70565b610b93565b610182610299366004611c70565b610d50565b6002546001600160a01b031681565b60045460ff1681565b6102be610d6a565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290610309908390612448565b60405180910390a150565b61031c610d96565b610324610db8565b6001600160a01b03166323b872dd3361033b610dd4565b846040518463ffffffff1660e01b815260040161035a93929190612456565b602060405180830381600087803b15801561037457600080fd5b505af1158015610388573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103ac9190810190611cdf565b506103b73382610df7565b50565b600060606103c66108d5565b905060005b81518110156104c85760008282815181106103e257fe5b602090810291909101810151600081815260039092526040918290205460025492516321f8a72160e01b81529193506001600160a01b039081169216906321f8a72190610433908590600401612580565b60206040518083038186803b15801561044b57600080fd5b505afa15801561045f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104839190810190611c52565b6001600160a01b03161415806104ae57506000818152600360205260409020546001600160a01b0316155b156104bf57600093505050506104cf565b506001016103cb565b5060019150505b90565b6104da610d6a565b60045460ff166105055760405162461bcd60e51b81526004016104fc90612619565b60405180910390fd5b6004805460ff191690556040517f43e00f2c8f8651a29db34d34fb689573423f8aaae8f9d32e3e871b4c35c6254690600090a1565b610542610f0d565b6001600160a01b0316336001600160a01b0316146105725760405162461bcd60e51b81526004016104fc90612699565b61057a610db8565b6001600160a01b031663a9059cbb610590610dd4565b836040518363ffffffff1660e01b815260040161035a929190612546565b8061064d6105ba610dd4565b6040516370a0823160e01b81526001600160a01b038416906370a08231906105e6903090600401612448565b60206040518083038186803b1580156105fe57600080fd5b505afa158015610612573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106369190810190611d1b565b6001600160a01b038416919063ffffffff610f2e16565b5050565b6001546001600160a01b031681565b7f53796e746865746978427269646765546f4f7074696d69736d0000000000000081565b61068c610d6a565b60045460ff16156106af5760405162461bcd60e51b81526004016104fc906125e9565b6004805460ff191660011790556040517f7c88488c18e2ff121a34a4a2a44990557a5b76ab1ceb6bd95ebe7d419c7575f490600090a1565b60606106f16108d5565b905060005b815181101561064d57600082828151811061070d57fe5b602002602001015190506000600260009054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200161074f919061243d565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161077b9291906125aa565b60206040518083038186803b15801561079357600080fd5b505afa1580156107a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107cb9190810190611c52565b6000838152600360205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa6890610827908490849061258e565b60405180910390a150506001016106f6565b6001546001600160a01b031633146108635760405162461bcd60e51b81526004016104fc906125f9565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c926108a6926001600160a01b03918216929116906124ee565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6060806108e0610f8c565b60408051600480825260a0820190925291925060609190602082016080803883390190505090506524b9b9bab2b960d11b8160008151811061091e57fe5b602002602001018181525050722932bbb0b93239a234b9ba3934b13aba34b7b760691b8160018151811061094e57fe5b602002602001018181525050786f766d3a53796e746865746978427269646765546f4261736560381b8160028151811061098457fe5b6020026020010181815250507453796e746865746978427269646765457363726f7760581b816003815181106109b657fe5b6020026020010181815250506109cc8282611051565b9250505090565b6000546001600160a01b031681565b6109ea610d96565b6109f261110d565b6103b7816111ad565b610a03610d96565b610a0b61110d565b805115610a1b57610a1b816111ad565b811561064d5761064d338361144e565b610a33610d96565b610a3b61110d565b6103b7338261144e565b610a4d610d96565b610a556115e9565b6001600160a01b0316336001600160a01b031614610a855760405162461bcd60e51b81526004016104fc90612679565b6040516000906060906325aae56360e01b90610aa7908690869060240161259c565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529050610ae36115fe565b6001600160a01b0316633dbb202b610af9611619565b83610b046004611640565b6040518463ffffffff1660e01b8152600401610b2293929190612517565b600060405180830381600087803b158015610b3c57600080fd5b505af1158015610b50573d6000803e3d6000fd5b505050507fcca0df3f2f18cd65d14c04abffc77c2d00aaca7ad00b0d2eb074adeea3fb54f48484604051610b8592919061259c565b60405180910390a150505050565b610b9b6115fe565b6001600160a01b0316336001600160a01b031614610bcb5760405162461bcd60e51b81526004016104fc90612689565b610bd3611619565b6001600160a01b0316610be46115fe565b6001600160a01b0316636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b158015610c1c57600080fd5b505afa158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c549190810190611c52565b6001600160a01b031614610c7a5760405162461bcd60e51b81526004016104fc90612609565b610c82610db8565b6001600160a01b03166323b872dd610c98610dd4565b84846040518463ffffffff1660e01b8152600401610cb893929190612509565b602060405180830381600087803b158015610cd257600080fd5b505af1158015610ce6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d0a9190810190611cdf565b50816001600160a01b03167f9e5c4f9f4e46b8629d3dda85f43a69194f50254404a72dc62b9e932d9c94eda882604051610d449190612580565b60405180910390a25050565b610d58610d96565b610d6061110d565b61064d828261144e565b6000546001600160a01b03163314610d945760405162461bcd60e51b81526004016104fc90612669565b565b60045460ff16610d945760405162461bcd60e51b81526004016104fc90612649565b6000610dcf680a6f2dce8d0cae8d2f60bb1b6116e8565b905090565b6000610dcf7453796e746865746978427269646765457363726f7760581b6116e8565b60405160009060609063a616cdfb60e01b90610e199086908690602401612546565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529050610e556115fe565b6001600160a01b0316633dbb202b610e6b611619565b83610e766002611640565b6040518463ffffffff1660e01b8152600401610e9493929190612517565b600060405180830381600087803b158015610eae57600080fd5b505af1158015610ec2573d6000803e3d6000fd5b50505050836001600160a01b03167f0ac6af0c6fd21e58850b0385f451cdcc08071424f47fd04652be4e51069f43cc84604051610eff9190612580565b60405180910390a250505050565b6000610dcf722932bbb0b93239a234b9ba3934b13aba34b7b760691b6116e8565b604051610f8790849063a9059cbb60e01b90610f509086908690602401612546565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611745565b505050565b606080610f97611830565b60408051600480825260a0820190925291925060609190602082016080803883390190505090506c32bc3a1d26b2b9b9b2b733b2b960991b81600081518110610fdc57fe5b602002602001018181525050680a6f2dce8d0cae8d2f60bb1b8160018151811061100257fe5b6020026020010181815250506d2932bbb0b93222b9b1b937bbab1960911b8160028151811061102d57fe5b60200260200101818152505066119959541bdbdb60ca1b816003815181106109b657fe5b60608151835101604051908082528060200260200182016040528015611081578160200160208202803883390190505b50905060005b83518110156110c35783818151811061109c57fe5b60200260200101518282815181106110b057fe5b6020908102919091010152600101611087565b5060005b8251811015611106578281815181106110dc57fe5b60200260200101518282865101815181106110f357fe5b60209081029190910101526001016110c7565b5092915050565b611115611881565b6001600160a01b031663d37c4d8b336040518263ffffffff1660e01b8152600401611140919061249e565b60206040518083038186803b15801561115857600080fd5b505afa15801561116c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111909190810190611d1b565b15610d945760405162461bcd60e51b81526004016104fc90612659565b60005b815181101561064d57601a60ff168282815181106111ca57fe5b60200260200101515111156111f15760405162461bcd60e51b81526004016104fc90612639565b600060606111fd611895565b6001600160a01b03166380d46f583386868151811061121857fe5b60200260200101516040518363ffffffff1660e01b815260040161123d92919061247e565b600060405180830381600087803b15801561125757600080fd5b505af115801561126b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112939190810190611d81565b90925090508115611444576112a6610db8565b6001600160a01b031663a9059cbb6112bc610dd4565b846040518363ffffffff1660e01b81526004016112da929190612546565b602060405180830381600087803b1580156112f457600080fd5b505af1158015611308573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061132c9190810190611cdf565b50604051600090606090637cbc127f60e11b90611351903390879087906024016124b8565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905061138d6115fe565b6001600160a01b0316633dbb202b6113a3611619565b836113ae6001611640565b6040518463ffffffff1660e01b81526004016113cc93929190612517565b600060405180830381600087803b1580156113e657600080fd5b505af11580156113fa573d6000803e3d6000fd5b50505050336001600160a01b03167f4dc5956ab6218a4dfa2cc5e5c50d98d039dde03aabfc504c54b601b6f562269685856040516114399291906126d9565b60405180910390a250505b50506001016111b0565b611456610db8565b6001600160a01b03166323b872dd3361146d610dd4565b846040518463ffffffff1660e01b815260040161148c93929190612456565b602060405180830381600087803b1580156114a657600080fd5b505af11580156114ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114de9190810190611cdf565b50604051600090606090638d6e9a5b60e01b906115019086908690602401612546565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905061153d6115fe565b6001600160a01b0316633dbb202b611553611619565b8361155e6000611640565b6040518463ffffffff1660e01b815260040161157c93929190612517565b600060405180830381600087803b15801561159657600080fd5b505af11580156115aa573d6000803e3d6000fd5b50505050336001600160a01b03167ff531653a5819e21265de50358610d55dbe6594c61605b209dfa4280d277938c18585604051610eff929190612546565b6000610dcf66119959541bdbdb60ca1b6116e8565b6000610dcf6c32bc3a1d26b2b9b9b2b733b2b960991b6116e8565b6000610dcf786f766d3a53796e746865746978427269646765546f4261736560381b6116e8565b600061164a6118b1565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b611673856118ce565b6040518363ffffffff1660e01b815260040161169092919061259c565b60206040518083038186803b1580156116a857600080fd5b505afa1580156116bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116e09190810190611d1b565b90505b919050565b60008181526003602090815260408083205490516001600160a01b0390911691821515916117189186910161241d565b604051602081830303815290604052906111065760405162461bcd60e51b81526004016104fc91906125d8565b611757826001600160a01b0316611a49565b6117735760405162461bcd60e51b81526004016104fc906126c9565b60006060836001600160a01b03168360405161178f919061240a565b6000604051808303816000865af19150503d80600081146117cc576040519150601f19603f3d011682016040523d82523d6000602084013e6117d1565b606091505b5091509150816117f35760405162461bcd60e51b81526004016104fc90612629565b80511561182a578080602001905161180e9190810190611cdf565b61182a5760405162461bcd60e51b81526004016104fc906126a9565b50505050565b604080516001808252818301909252606091602080830190803883390190505090506e466c657869626c6553746f7261676560881b8160008151811061187257fe5b60200260200101818152505090565b6000610dcf6524b9b9bab2b960d11b6116e8565b6000610dcf6d2932bbb0b93222b9b1b937bbab1960911b6116e8565b6000610dcf6e466c657869626c6553746f7261676560881b6116e8565b6000808260058111156118dd57fe5b141561190a57507f63726f7373446f6d61696e4465706f7369744761734c696d69740000000000006116e3565b600182600581111561191857fe5b141561194557507f63726f7373446f6d61696e457363726f774761734c696d6974000000000000006116e3565b600282600581111561195357fe5b141561198057507f63726f7373446f6d61696e5265776172644761734c696d6974000000000000006116e3565b600382600581111561198e57fe5b14156119bb57507f63726f7373446f6d61696e5769746864726177616c4761734c696d69740000006116e3565b60058260058111156119c957fe5b14156119f657507f63726f7373446f6d61696e52656c61794761734c696d697400000000000000006116e3565b6004826005811115611a0457fe5b1415611a3157507f63726f7373446f6d61696e436c6f73654761734c696d697400000000000000006116e3565b60405162461bcd60e51b81526004016104fc906126b9565b3b151590565b8035611a5a816127ce565b92915050565b8051611a5a816127ce565b600082601f830112611a7c57600080fd5b8135611a8f611a8a82612720565b6126f9565b81815260209384019390925082018360005b83811015611acd5781358601611ab78882611b49565b8452506020928301929190910190600101611aa1565b5050505092915050565b600082601f830112611ae857600080fd5b8151611af6611a8a82612720565b91508181835260208401935060208101905083856040840282011115611b1b57600080fd5b60005b83811015611acd5781611b318882611bc4565b84525060209092019160409190910190600101611b1e565b600082601f830112611b5a57600080fd5b8135611b68611a8a82612720565b91508181835260208401935060208101905083856020840282011115611b8d57600080fd5b60005b83811015611acd5781611ba38882611c0b565b8452506020928301929190910190600101611b90565b8051611a5a816127e2565b600060408284031215611bd657600080fd5b611be060406126f9565b90506000611bee8484611c21565b8252506020611bff84848301611c16565b60208301525092915050565b8035611a5a816127eb565b8051611a5a816127eb565b8051611a5a816127f4565b600060208284031215611c3e57600080fd5b6000611c4a8484611a4f565b949350505050565b600060208284031215611c6457600080fd5b6000611c4a8484611a60565b60008060408385031215611c8357600080fd5b6000611c8f8585611a4f565b9250506020611ca085828601611c0b565b9150509250929050565b600060208284031215611cbc57600080fd5b813567ffffffffffffffff811115611cd357600080fd5b611c4a84828501611a6b565b600060208284031215611cf157600080fd5b6000611c4a8484611bb9565b600060208284031215611d0f57600080fd5b6000611c4a8484611c0b565b600060208284031215611d2d57600080fd5b6000611c4a8484611c16565b60008060408385031215611d4c57600080fd5b6000611d588585611c0b565b925050602083013567ffffffffffffffff811115611d7557600080fd5b611ca085828601611a6b565b60008060408385031215611d9457600080fd5b6000611da08585611c16565b925050602083015167ffffffffffffffff811115611dbd57600080fd5b611ca085828601611ad7565b60008060408385031215611ddc57600080fd5b6000611c8f8585611c0b565b6000611df48383611f26565b505060200190565b6000611e0883836123d4565b505060400190565b611e1981612786565b82525050565b611e1981612754565b6000611e3382612747565b611e3d818561274b565b9350611e4883612741565b8060005b83811015611e76578151611e608882611de8565b9750611e6b83612741565b925050600101611e4c565b509495945050505050565b6000611e8c82612747565b611e96818561274b565b9350611ea183612741565b8060005b83811015611e76578151611eb98882611dfc565b9750611ec483612741565b925050600101611ea5565b6000611eda82612747565b611ee4818561274b565b9350611eef83612741565b8060005b83811015611e76578151611f078882611de8565b9750611f1283612741565b925050600101611ef3565b611e198161275f565b611e19816104cf565b611e19611f3b826104cf565b6104cf565b6000611f4b82612747565b611f55818561274b565b9350611f65818560208601612798565b611f6e816127c4565b9093019392505050565b6000611f8382612747565b611f8d81856116e3565b9350611f9d818560208601612798565b9290920192915050565b611e198161278d565b6000611fbd60188361274b565b7f496e6974696174696f6e206e6f742073757370656e6465640000000000000000815260200192915050565b6000611ff660358361274b565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527402063616e20616363657074206f776e65727368697605c1b602082015260400192915050565b600061204d601d8361274b565b7f4f6e6c7920746865204c32206272696467652063616e20696e766f6b65000000815260200192915050565b600061208660148361274b565b73125b9a5d1a585d1a5bdb881cdd5cdc195b99195960621b815260200192915050565b60006120b660208361274b565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815260200192915050565b60006120ef60218361274b565b7f45786365656473206d617820656e747269657320706572206d6967726174696f8152603760f91b602082015260400192915050565b60006121326011836116e3565b70026b4b9b9b4b7339030b2323932b9b99d1607d1b815260110192915050565b600061215f60168361274b565b75125b9a5d1a585d1a5bdb8819195858dd1a5d985d195960521b815260200192915050565b600061219160238361274b565b7f43616e6e6f74206465706f736974206f72206d6967726174652077697468206481526219589d60ea1b602082015260400192915050565b60006121d6602f8361274b565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681526e37b936903a3434b99030b1ba34b7b760891b602082015260400192915050565b631cd554d160e21b9052565b6000612233601f8361274b565b7f4f6e6c79207468652066656520706f6f6c2063616e2063616c6c207468697300815260200192915050565b600061226c601e8361274b565b7f4f6e6c79207468652072656c617965722063616e2063616c6c20746869730000815260200192915050565b60006122a56019836116e3565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b60006122de602a8361274b565b7f43616c6c6572206973206e6f742052657761726473446973747269627574696f8152691b8818dbdb9d1c9858dd60b21b602082015260400192915050565b600061232a602a8361274b565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b602082015260400192915050565b600061237660168361274b565b75556e6b6e6f776e20676173206c696d6974207479706560501b815260200192915050565b60006123a8601f8361274b565b7f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400815260200192915050565b805160408301906123e58482612401565b50602082015161182a6020850182611f26565b611e1981612770565b611e1981612779565b60006124168284611f78565b9392505050565b600061242882612125565b91506124348284611f2f565b50602001919050565b600061242882612298565b60208101611a5a8284611e1f565b606081016124648286611e10565b6124716020830185611e1f565b611c4a6040830184611f26565b6040810161248c8285611e10565b8181036020830152611c4a8184611ecf565b604081016124ac8284611e10565b611a5a6020830161221a565b606081016124c68286611e1f565b6124d36020830185611f26565b81810360408301526124e58184611e81565b95945050505050565b604081016124fc8285611e1f565b6124166020830184611e1f565b606081016124648286611e1f565b606081016125258286611e1f565b81810360208301526125378185611f40565b9050611c4a60408301846123f8565b604081016125548285611e1f565b6124166020830184611f26565b602080825281016124168184611e28565b60208101611a5a8284611f1d565b60208101611a5a8284611f26565b604081016124fc8285611f26565b604081016125548285611f26565b604081016125b88285611f26565b8181036020830152611c4a8184611f40565b60208101611a5a8284611fa7565b602080825281016124168184611f40565b602080825281016116e081611fb0565b602080825281016116e081611fe9565b602080825281016116e081612040565b602080825281016116e081612079565b602080825281016116e0816120a9565b602080825281016116e0816120e2565b602080825281016116e081612152565b602080825281016116e081612184565b602080825281016116e0816121c9565b602080825281016116e081612226565b602080825281016116e08161225f565b602080825281016116e0816122d1565b602080825281016116e08161231d565b602080825281016116e081612369565b602080825281016116e08161239b565b604081016126e78285611f26565b8181036020830152611c4a8184611e81565b60405181810167ffffffffffffffff8111828210171561271857600080fd5b604052919050565b600067ffffffffffffffff82111561273757600080fd5b5060209081020190565b60200190565b5190565b90815260200190565b60006116e082612764565b151590565b6001600160a01b031690565b63ffffffff1690565b67ffffffffffffffff1690565b60006116e0825b60006116e082612754565b60005b838110156127b357818101518382015260200161279b565b8381111561182a5750506000910152565b601f01601f191690565b6127d781612754565b81146103b757600080fd5b6127d78161275f565b6127d7816104cf565b6127d78161277956fea365627a7a723158204a667cde1d713fe831bf7a74c17f5901ca90e504369c01257fed874e1872b5d06c6578706572696d656e74616cf564736f6c63430005100040000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe0000000000000000000000004e3b31eb0e5cb73641ee1e65e7dcefe520ba3ef2
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101375760003560e01c8063698a26b2116100b85780639a9e7f961161007c5780639a9e7f961461022c578063a18e23071461023f578063b6b55f2514610252578063b9958ab814610265578063f4f7b41a14610278578063ffaad6a51461028b57610137565b8063698a26b2146101f757806374185360146101ff57806379ba509714610207578063899ffef41461020f5780638da5cb5b1461022457610137565b80633872dda3116100ff5780633872dda31461019f5780633c6b16ab146101a7578063462286d5146101ba57806353a47bb7146101cd578063614d08f8146101e257610137565b806304f3bcec1461013c578063100be6d41461015a5780631627540c1461016f5780631e2720ff146101845780632af64bd314610197575b600080fd5b61014461029e565b60405161015191906125ca565b60405180910390f35b6101626102ad565b6040516101519190612572565b61018261017d366004611c2c565b6102b6565b005b610182610192366004611cfd565b610314565b6101626103ba565b6101826104d2565b6101826101b5366004611cfd565b61053a565b6101826101c8366004611c2c565b6105ae565b6101d5610651565b6040516101519190612448565b6101ea610660565b6040516101519190612580565b610182610684565b6101826106e7565b610182610839565b6102176108d5565b6040516101519190612561565b6101d56109d3565b61018261023a366004611caa565b6109e2565b61018261024d366004611d39565b6109fb565b610182610260366004611cfd565b610a2b565b610182610273366004611dc9565b610a45565b610182610286366004611c70565b610b93565b610182610299366004611c70565b610d50565b6002546001600160a01b031681565b60045460ff1681565b6102be610d6a565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290610309908390612448565b60405180910390a150565b61031c610d96565b610324610db8565b6001600160a01b03166323b872dd3361033b610dd4565b846040518463ffffffff1660e01b815260040161035a93929190612456565b602060405180830381600087803b15801561037457600080fd5b505af1158015610388573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103ac9190810190611cdf565b506103b73382610df7565b50565b600060606103c66108d5565b905060005b81518110156104c85760008282815181106103e257fe5b602090810291909101810151600081815260039092526040918290205460025492516321f8a72160e01b81529193506001600160a01b039081169216906321f8a72190610433908590600401612580565b60206040518083038186803b15801561044b57600080fd5b505afa15801561045f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104839190810190611c52565b6001600160a01b03161415806104ae57506000818152600360205260409020546001600160a01b0316155b156104bf57600093505050506104cf565b506001016103cb565b5060019150505b90565b6104da610d6a565b60045460ff166105055760405162461bcd60e51b81526004016104fc90612619565b60405180910390fd5b6004805460ff191690556040517f43e00f2c8f8651a29db34d34fb689573423f8aaae8f9d32e3e871b4c35c6254690600090a1565b610542610f0d565b6001600160a01b0316336001600160a01b0316146105725760405162461bcd60e51b81526004016104fc90612699565b61057a610db8565b6001600160a01b031663a9059cbb610590610dd4565b836040518363ffffffff1660e01b815260040161035a929190612546565b8061064d6105ba610dd4565b6040516370a0823160e01b81526001600160a01b038416906370a08231906105e6903090600401612448565b60206040518083038186803b1580156105fe57600080fd5b505afa158015610612573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106369190810190611d1b565b6001600160a01b038416919063ffffffff610f2e16565b5050565b6001546001600160a01b031681565b7f53796e746865746978427269646765546f4f7074696d69736d0000000000000081565b61068c610d6a565b60045460ff16156106af5760405162461bcd60e51b81526004016104fc906125e9565b6004805460ff191660011790556040517f7c88488c18e2ff121a34a4a2a44990557a5b76ab1ceb6bd95ebe7d419c7575f490600090a1565b60606106f16108d5565b905060005b815181101561064d57600082828151811061070d57fe5b602002602001015190506000600260009054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200161074f919061243d565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161077b9291906125aa565b60206040518083038186803b15801561079357600080fd5b505afa1580156107a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107cb9190810190611c52565b6000838152600360205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa6890610827908490849061258e565b60405180910390a150506001016106f6565b6001546001600160a01b031633146108635760405162461bcd60e51b81526004016104fc906125f9565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c926108a6926001600160a01b03918216929116906124ee565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6060806108e0610f8c565b60408051600480825260a0820190925291925060609190602082016080803883390190505090506524b9b9bab2b960d11b8160008151811061091e57fe5b602002602001018181525050722932bbb0b93239a234b9ba3934b13aba34b7b760691b8160018151811061094e57fe5b602002602001018181525050786f766d3a53796e746865746978427269646765546f4261736560381b8160028151811061098457fe5b6020026020010181815250507453796e746865746978427269646765457363726f7760581b816003815181106109b657fe5b6020026020010181815250506109cc8282611051565b9250505090565b6000546001600160a01b031681565b6109ea610d96565b6109f261110d565b6103b7816111ad565b610a03610d96565b610a0b61110d565b805115610a1b57610a1b816111ad565b811561064d5761064d338361144e565b610a33610d96565b610a3b61110d565b6103b7338261144e565b610a4d610d96565b610a556115e9565b6001600160a01b0316336001600160a01b031614610a855760405162461bcd60e51b81526004016104fc90612679565b6040516000906060906325aae56360e01b90610aa7908690869060240161259c565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529050610ae36115fe565b6001600160a01b0316633dbb202b610af9611619565b83610b046004611640565b6040518463ffffffff1660e01b8152600401610b2293929190612517565b600060405180830381600087803b158015610b3c57600080fd5b505af1158015610b50573d6000803e3d6000fd5b505050507fcca0df3f2f18cd65d14c04abffc77c2d00aaca7ad00b0d2eb074adeea3fb54f48484604051610b8592919061259c565b60405180910390a150505050565b610b9b6115fe565b6001600160a01b0316336001600160a01b031614610bcb5760405162461bcd60e51b81526004016104fc90612689565b610bd3611619565b6001600160a01b0316610be46115fe565b6001600160a01b0316636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b158015610c1c57600080fd5b505afa158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c549190810190611c52565b6001600160a01b031614610c7a5760405162461bcd60e51b81526004016104fc90612609565b610c82610db8565b6001600160a01b03166323b872dd610c98610dd4565b84846040518463ffffffff1660e01b8152600401610cb893929190612509565b602060405180830381600087803b158015610cd257600080fd5b505af1158015610ce6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d0a9190810190611cdf565b50816001600160a01b03167f9e5c4f9f4e46b8629d3dda85f43a69194f50254404a72dc62b9e932d9c94eda882604051610d449190612580565b60405180910390a25050565b610d58610d96565b610d6061110d565b61064d828261144e565b6000546001600160a01b03163314610d945760405162461bcd60e51b81526004016104fc90612669565b565b60045460ff16610d945760405162461bcd60e51b81526004016104fc90612649565b6000610dcf680a6f2dce8d0cae8d2f60bb1b6116e8565b905090565b6000610dcf7453796e746865746978427269646765457363726f7760581b6116e8565b60405160009060609063a616cdfb60e01b90610e199086908690602401612546565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529050610e556115fe565b6001600160a01b0316633dbb202b610e6b611619565b83610e766002611640565b6040518463ffffffff1660e01b8152600401610e9493929190612517565b600060405180830381600087803b158015610eae57600080fd5b505af1158015610ec2573d6000803e3d6000fd5b50505050836001600160a01b03167f0ac6af0c6fd21e58850b0385f451cdcc08071424f47fd04652be4e51069f43cc84604051610eff9190612580565b60405180910390a250505050565b6000610dcf722932bbb0b93239a234b9ba3934b13aba34b7b760691b6116e8565b604051610f8790849063a9059cbb60e01b90610f509086908690602401612546565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611745565b505050565b606080610f97611830565b60408051600480825260a0820190925291925060609190602082016080803883390190505090506c32bc3a1d26b2b9b9b2b733b2b960991b81600081518110610fdc57fe5b602002602001018181525050680a6f2dce8d0cae8d2f60bb1b8160018151811061100257fe5b6020026020010181815250506d2932bbb0b93222b9b1b937bbab1960911b8160028151811061102d57fe5b60200260200101818152505066119959541bdbdb60ca1b816003815181106109b657fe5b60608151835101604051908082528060200260200182016040528015611081578160200160208202803883390190505b50905060005b83518110156110c35783818151811061109c57fe5b60200260200101518282815181106110b057fe5b6020908102919091010152600101611087565b5060005b8251811015611106578281815181106110dc57fe5b60200260200101518282865101815181106110f357fe5b60209081029190910101526001016110c7565b5092915050565b611115611881565b6001600160a01b031663d37c4d8b336040518263ffffffff1660e01b8152600401611140919061249e565b60206040518083038186803b15801561115857600080fd5b505afa15801561116c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111909190810190611d1b565b15610d945760405162461bcd60e51b81526004016104fc90612659565b60005b815181101561064d57601a60ff168282815181106111ca57fe5b60200260200101515111156111f15760405162461bcd60e51b81526004016104fc90612639565b600060606111fd611895565b6001600160a01b03166380d46f583386868151811061121857fe5b60200260200101516040518363ffffffff1660e01b815260040161123d92919061247e565b600060405180830381600087803b15801561125757600080fd5b505af115801561126b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112939190810190611d81565b90925090508115611444576112a6610db8565b6001600160a01b031663a9059cbb6112bc610dd4565b846040518363ffffffff1660e01b81526004016112da929190612546565b602060405180830381600087803b1580156112f457600080fd5b505af1158015611308573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061132c9190810190611cdf565b50604051600090606090637cbc127f60e11b90611351903390879087906024016124b8565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905061138d6115fe565b6001600160a01b0316633dbb202b6113a3611619565b836113ae6001611640565b6040518463ffffffff1660e01b81526004016113cc93929190612517565b600060405180830381600087803b1580156113e657600080fd5b505af11580156113fa573d6000803e3d6000fd5b50505050336001600160a01b03167f4dc5956ab6218a4dfa2cc5e5c50d98d039dde03aabfc504c54b601b6f562269685856040516114399291906126d9565b60405180910390a250505b50506001016111b0565b611456610db8565b6001600160a01b03166323b872dd3361146d610dd4565b846040518463ffffffff1660e01b815260040161148c93929190612456565b602060405180830381600087803b1580156114a657600080fd5b505af11580156114ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114de9190810190611cdf565b50604051600090606090638d6e9a5b60e01b906115019086908690602401612546565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905061153d6115fe565b6001600160a01b0316633dbb202b611553611619565b8361155e6000611640565b6040518463ffffffff1660e01b815260040161157c93929190612517565b600060405180830381600087803b15801561159657600080fd5b505af11580156115aa573d6000803e3d6000fd5b50505050336001600160a01b03167ff531653a5819e21265de50358610d55dbe6594c61605b209dfa4280d277938c18585604051610eff929190612546565b6000610dcf66119959541bdbdb60ca1b6116e8565b6000610dcf6c32bc3a1d26b2b9b9b2b733b2b960991b6116e8565b6000610dcf786f766d3a53796e746865746978427269646765546f4261736560381b6116e8565b600061164a6118b1565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b611673856118ce565b6040518363ffffffff1660e01b815260040161169092919061259c565b60206040518083038186803b1580156116a857600080fd5b505afa1580156116bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116e09190810190611d1b565b90505b919050565b60008181526003602090815260408083205490516001600160a01b0390911691821515916117189186910161241d565b604051602081830303815290604052906111065760405162461bcd60e51b81526004016104fc91906125d8565b611757826001600160a01b0316611a49565b6117735760405162461bcd60e51b81526004016104fc906126c9565b60006060836001600160a01b03168360405161178f919061240a565b6000604051808303816000865af19150503d80600081146117cc576040519150601f19603f3d011682016040523d82523d6000602084013e6117d1565b606091505b5091509150816117f35760405162461bcd60e51b81526004016104fc90612629565b80511561182a578080602001905161180e9190810190611cdf565b61182a5760405162461bcd60e51b81526004016104fc906126a9565b50505050565b604080516001808252818301909252606091602080830190803883390190505090506e466c657869626c6553746f7261676560881b8160008151811061187257fe5b60200260200101818152505090565b6000610dcf6524b9b9bab2b960d11b6116e8565b6000610dcf6d2932bbb0b93222b9b1b937bbab1960911b6116e8565b6000610dcf6e466c657869626c6553746f7261676560881b6116e8565b6000808260058111156118dd57fe5b141561190a57507f63726f7373446f6d61696e4465706f7369744761734c696d69740000000000006116e3565b600182600581111561191857fe5b141561194557507f63726f7373446f6d61696e457363726f774761734c696d6974000000000000006116e3565b600282600581111561195357fe5b141561198057507f63726f7373446f6d61696e5265776172644761734c696d6974000000000000006116e3565b600382600581111561198e57fe5b14156119bb57507f63726f7373446f6d61696e5769746864726177616c4761734c696d69740000006116e3565b60058260058111156119c957fe5b14156119f657507f63726f7373446f6d61696e52656c61794761734c696d697400000000000000006116e3565b6004826005811115611a0457fe5b1415611a3157507f63726f7373446f6d61696e436c6f73654761734c696d697400000000000000006116e3565b60405162461bcd60e51b81526004016104fc906126b9565b3b151590565b8035611a5a816127ce565b92915050565b8051611a5a816127ce565b600082601f830112611a7c57600080fd5b8135611a8f611a8a82612720565b6126f9565b81815260209384019390925082018360005b83811015611acd5781358601611ab78882611b49565b8452506020928301929190910190600101611aa1565b5050505092915050565b600082601f830112611ae857600080fd5b8151611af6611a8a82612720565b91508181835260208401935060208101905083856040840282011115611b1b57600080fd5b60005b83811015611acd5781611b318882611bc4565b84525060209092019160409190910190600101611b1e565b600082601f830112611b5a57600080fd5b8135611b68611a8a82612720565b91508181835260208401935060208101905083856020840282011115611b8d57600080fd5b60005b83811015611acd5781611ba38882611c0b565b8452506020928301929190910190600101611b90565b8051611a5a816127e2565b600060408284031215611bd657600080fd5b611be060406126f9565b90506000611bee8484611c21565b8252506020611bff84848301611c16565b60208301525092915050565b8035611a5a816127eb565b8051611a5a816127eb565b8051611a5a816127f4565b600060208284031215611c3e57600080fd5b6000611c4a8484611a4f565b949350505050565b600060208284031215611c6457600080fd5b6000611c4a8484611a60565b60008060408385031215611c8357600080fd5b6000611c8f8585611a4f565b9250506020611ca085828601611c0b565b9150509250929050565b600060208284031215611cbc57600080fd5b813567ffffffffffffffff811115611cd357600080fd5b611c4a84828501611a6b565b600060208284031215611cf157600080fd5b6000611c4a8484611bb9565b600060208284031215611d0f57600080fd5b6000611c4a8484611c0b565b600060208284031215611d2d57600080fd5b6000611c4a8484611c16565b60008060408385031215611d4c57600080fd5b6000611d588585611c0b565b925050602083013567ffffffffffffffff811115611d7557600080fd5b611ca085828601611a6b565b60008060408385031215611d9457600080fd5b6000611da08585611c16565b925050602083015167ffffffffffffffff811115611dbd57600080fd5b611ca085828601611ad7565b60008060408385031215611ddc57600080fd5b6000611c8f8585611c0b565b6000611df48383611f26565b505060200190565b6000611e0883836123d4565b505060400190565b611e1981612786565b82525050565b611e1981612754565b6000611e3382612747565b611e3d818561274b565b9350611e4883612741565b8060005b83811015611e76578151611e608882611de8565b9750611e6b83612741565b925050600101611e4c565b509495945050505050565b6000611e8c82612747565b611e96818561274b565b9350611ea183612741565b8060005b83811015611e76578151611eb98882611dfc565b9750611ec483612741565b925050600101611ea5565b6000611eda82612747565b611ee4818561274b565b9350611eef83612741565b8060005b83811015611e76578151611f078882611de8565b9750611f1283612741565b925050600101611ef3565b611e198161275f565b611e19816104cf565b611e19611f3b826104cf565b6104cf565b6000611f4b82612747565b611f55818561274b565b9350611f65818560208601612798565b611f6e816127c4565b9093019392505050565b6000611f8382612747565b611f8d81856116e3565b9350611f9d818560208601612798565b9290920192915050565b611e198161278d565b6000611fbd60188361274b565b7f496e6974696174696f6e206e6f742073757370656e6465640000000000000000815260200192915050565b6000611ff660358361274b565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527402063616e20616363657074206f776e65727368697605c1b602082015260400192915050565b600061204d601d8361274b565b7f4f6e6c7920746865204c32206272696467652063616e20696e766f6b65000000815260200192915050565b600061208660148361274b565b73125b9a5d1a585d1a5bdb881cdd5cdc195b99195960621b815260200192915050565b60006120b660208361274b565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815260200192915050565b60006120ef60218361274b565b7f45786365656473206d617820656e747269657320706572206d6967726174696f8152603760f91b602082015260400192915050565b60006121326011836116e3565b70026b4b9b9b4b7339030b2323932b9b99d1607d1b815260110192915050565b600061215f60168361274b565b75125b9a5d1a585d1a5bdb8819195858dd1a5d985d195960521b815260200192915050565b600061219160238361274b565b7f43616e6e6f74206465706f736974206f72206d6967726174652077697468206481526219589d60ea1b602082015260400192915050565b60006121d6602f8361274b565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681526e37b936903a3434b99030b1ba34b7b760891b602082015260400192915050565b631cd554d160e21b9052565b6000612233601f8361274b565b7f4f6e6c79207468652066656520706f6f6c2063616e2063616c6c207468697300815260200192915050565b600061226c601e8361274b565b7f4f6e6c79207468652072656c617965722063616e2063616c6c20746869730000815260200192915050565b60006122a56019836116e3565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b60006122de602a8361274b565b7f43616c6c6572206973206e6f742052657761726473446973747269627574696f8152691b8818dbdb9d1c9858dd60b21b602082015260400192915050565b600061232a602a8361274b565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b602082015260400192915050565b600061237660168361274b565b75556e6b6e6f776e20676173206c696d6974207479706560501b815260200192915050565b60006123a8601f8361274b565b7f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400815260200192915050565b805160408301906123e58482612401565b50602082015161182a6020850182611f26565b611e1981612770565b611e1981612779565b60006124168284611f78565b9392505050565b600061242882612125565b91506124348284611f2f565b50602001919050565b600061242882612298565b60208101611a5a8284611e1f565b606081016124648286611e10565b6124716020830185611e1f565b611c4a6040830184611f26565b6040810161248c8285611e10565b8181036020830152611c4a8184611ecf565b604081016124ac8284611e10565b611a5a6020830161221a565b606081016124c68286611e1f565b6124d36020830185611f26565b81810360408301526124e58184611e81565b95945050505050565b604081016124fc8285611e1f565b6124166020830184611e1f565b606081016124648286611e1f565b606081016125258286611e1f565b81810360208301526125378185611f40565b9050611c4a60408301846123f8565b604081016125548285611e1f565b6124166020830184611f26565b602080825281016124168184611e28565b60208101611a5a8284611f1d565b60208101611a5a8284611f26565b604081016124fc8285611f26565b604081016125548285611f26565b604081016125b88285611f26565b8181036020830152611c4a8184611f40565b60208101611a5a8284611fa7565b602080825281016124168184611f40565b602080825281016116e081611fb0565b602080825281016116e081611fe9565b602080825281016116e081612040565b602080825281016116e081612079565b602080825281016116e0816120a9565b602080825281016116e0816120e2565b602080825281016116e081612152565b602080825281016116e081612184565b602080825281016116e0816121c9565b602080825281016116e081612226565b602080825281016116e08161225f565b602080825281016116e0816122d1565b602080825281016116e08161231d565b602080825281016116e081612369565b602080825281016116e08161239b565b604081016126e78285611f26565b8181036020830152611c4a8184611e81565b60405181810167ffffffffffffffff8111828210171561271857600080fd5b604052919050565b600067ffffffffffffffff82111561273757600080fd5b5060209081020190565b60200190565b5190565b90815260200190565b60006116e082612764565b151590565b6001600160a01b031690565b63ffffffff1690565b67ffffffffffffffff1690565b60006116e0825b60006116e082612754565b60005b838110156127b357818101518382015260200161279b565b8381111561182a5750506000910152565b601f01601f191690565b6127d781612754565b81146103b757600080fd5b6127d78161275f565b6127d7816104cf565b6127d78161277956fea365627a7a723158204a667cde1d713fe831bf7a74c17f5901ca90e504369c01257fed874e1872b5d06c6578706572696d656e74616cf564736f6c63430005100040
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe0000000000000000000000004e3b31eb0e5cb73641ee1e65e7dcefe520ba3ef2
-----Decoded View---------------
Arg [0] : _owner (address): 0xDe910777C787903F78C89e7a0bf7F4C435cBB1Fe
Arg [1] : _resolver (address): 0x4E3b31eB0E5CB73641EE1E65E7dCEFe520bA3ef2
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe
Arg [1] : 0000000000000000000000004e3b31eb0e5cb73641ee1e65e7dcefe520ba3ef2
Libraries Used
SafeDecimalMath : 0x84d626b2bb4d0f064067e4bf80fce7055d8f3e7bSystemSettingsLib : 0xa62f71d599ec6179b4f6569add69ffc7e1a7a1c5SignedSafeDecimalMath : 0x728a2b79cad691531cc1146ef802617ff50c7095
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.