ETH Price: $1,570.92 (-13.20%)

Contract

0x7DfB5180878B43C6Ff5aA6A2Ea55Db20Bcc87410
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Upgrade Old156736922022-10-04 8:50:23915 days ago1664873423IN
0x7DfB5180...0Bcc87410
0 ETH0.031220117.31907568
Accept Ownership146879242022-04-30 21:11:101072 days ago1651353070IN
0x7DfB5180...0Bcc87410
0 ETH0.0011949141.96815454
Transfer Ownersh...146878452022-04-30 20:53:551072 days ago1651352035IN
0x7DfB5180...0Bcc87410
0 ETH0.0015904134.41710543
Upgrade Old139554342022-01-07 1:42:561185 days ago1641519776IN
0x7DfB5180...0Bcc87410
0 ETH0.04332869156.68714811
Upgrade Old132297022021-09-15 10:14:041299 days ago1631700844IN
0x7DfB5180...0Bcc87410
0 ETH0.1697802738.98051077
Upgrade Old129296282021-07-30 22:27:001346 days ago1627684020IN
0x7DfB5180...0Bcc87410
0 ETH0.1647877238
Upgrade Old126008042021-06-09 14:20:261397 days ago1623248426IN
0x7DfB5180...0Bcc87410
0 ETH0.1128592626
Upgrade Old125561482021-06-02 16:24:121404 days ago1622651052IN
0x7DfB5180...0Bcc87410
0 ETH0.1605167337
Upgrade Old124516612021-05-17 11:36:441420 days ago1621251404IN
0x7DfB5180...0Bcc87410
0 ETH0.234189954
Accept Ownership121746052021-04-04 17:53:431463 days ago1617558823IN
0x7DfB5180...0Bcc87410
0 ETH0.0025048114
Transfer Ownersh...121745982021-04-04 17:52:271463 days ago1617558747IN
0x7DfB5180...0Bcc87410
0 ETH0.00472787106.70000123

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ConverterUpgrader

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-04-04
*/

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
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.
     *
     * IMPORTANT: 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);
}

// File: solidity/contracts/utility/interfaces/IOwned.sol


pragma solidity 0.6.12;

/*
    Owned contract interface
*/
interface IOwned {
    // this function isn't since the compiler emits automatically generated getter functions as external
    function owner() external view returns (address);

    function transferOwnership(address _newOwner) external;

    function acceptOwnership() external;
}

// File: solidity/contracts/converter/interfaces/IConverterAnchor.sol


pragma solidity 0.6.12;


/*
    Converter Anchor interface
*/
interface IConverterAnchor is IOwned {

}

// File: solidity/contracts/converter/interfaces/IConverter.sol


pragma solidity 0.6.12;




/*
    Converter interface
*/
interface IConverter is IOwned {
    function converterType() external pure returns (uint16);

    function anchor() external view returns (IConverterAnchor);

    function isActive() external view returns (bool);

    function targetAmountAndFee(
        IERC20 _sourceToken,
        IERC20 _targetToken,
        uint256 _amount
    ) external view returns (uint256, uint256);

    function convert(
        IERC20 _sourceToken,
        IERC20 _targetToken,
        uint256 _amount,
        address _trader,
        address payable _beneficiary
    ) external payable returns (uint256);

    function conversionFee() external view returns (uint32);

    function maxConversionFee() external view returns (uint32);

    function reserveBalance(IERC20 _reserveToken) external view returns (uint256);

    receive() external payable;

    function transferAnchorOwnership(address _newOwner) external;

    function acceptAnchorOwnership() external;

    function setConversionFee(uint32 _conversionFee) external;

    function addReserve(IERC20 _token, uint32 _weight) external;

    function transferReservesOnUpgrade(address _newConverter) external;

    function onUpgradeComplete() external;

    // deprecated, backward compatibility
    function token() external view returns (IConverterAnchor);

    function transferTokenOwnership(address _newOwner) external;

    function acceptTokenOwnership() external;

    function connectors(IERC20 _address)
        external
        view
        returns (
            uint256,
            uint32,
            bool,
            bool,
            bool
        );

    function getConnectorBalance(IERC20 _connectorToken) external view returns (uint256);

    function connectorTokens(uint256 _index) external view returns (IERC20);

    function connectorTokenCount() external view returns (uint16);

    /**
     * @dev triggered when the converter is activated
     *
     * @param _type        converter type
     * @param _anchor      converter anchor
     * @param _activated   true if the converter was activated, false if it was deactivated
     */
    event Activation(uint16 indexed _type, IConverterAnchor indexed _anchor, bool indexed _activated);

    /**
     * @dev triggered when a conversion between two tokens occurs
     *
     * @param _fromToken       source ERC20 token
     * @param _toToken         target ERC20 token
     * @param _trader          wallet that initiated the trade
     * @param _amount          input amount in units of the source token
     * @param _return          output amount minus conversion fee in units of the target token
     * @param _conversionFee   conversion fee in units of the target token
     */
    event Conversion(
        IERC20 indexed _fromToken,
        IERC20 indexed _toToken,
        address indexed _trader,
        uint256 _amount,
        uint256 _return,
        int256 _conversionFee
    );

    /**
     * @dev triggered when the rate between two tokens in the converter changes
     * note that the event might be dispatched for rate updates between any two tokens in the converter
     *
     * @param  _token1 address of the first token
     * @param  _token2 address of the second token
     * @param  _rateN  rate of 1 unit of `_token1` in `_token2` (numerator)
     * @param  _rateD  rate of 1 unit of `_token1` in `_token2` (denominator)
     */
    event TokenRateUpdate(IERC20 indexed _token1, IERC20 indexed _token2, uint256 _rateN, uint256 _rateD);

    /**
     * @dev triggered when the conversion fee is updated
     *
     * @param  _prevFee    previous fee percentage, represented in ppm
     * @param  _newFee     new fee percentage, represented in ppm
     */
    event ConversionFeeUpdate(uint32 _prevFee, uint32 _newFee);
}

// File: solidity/contracts/converter/interfaces/IConverterUpgrader.sol


pragma solidity 0.6.12;

/*
    Converter Upgrader interface
*/
interface IConverterUpgrader {
    function upgrade(bytes32 _version) external;

    function upgrade(uint16 _version) external;
}

// File: solidity/contracts/converter/interfaces/ITypedConverterCustomFactory.sol


pragma solidity 0.6.12;

/*
    Typed Converter Custom Factory interface
*/
interface ITypedConverterCustomFactory {
    function converterType() external pure returns (uint16);
}

// File: solidity/contracts/utility/interfaces/IContractRegistry.sol


pragma solidity 0.6.12;

/*
    Contract Registry interface
*/
interface IContractRegistry {
    function addressOf(bytes32 _contractName) external view returns (address);
}

// File: solidity/contracts/converter/interfaces/IConverterFactory.sol


pragma solidity 0.6.12;





/*
    Converter Factory interface
*/
interface IConverterFactory {
    function createAnchor(
        uint16 _type,
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) external returns (IConverterAnchor);

    function createConverter(
        uint16 _type,
        IConverterAnchor _anchor,
        IContractRegistry _registry,
        uint32 _maxConversionFee
    ) external returns (IConverter);

    function customFactories(uint16 _type) external view returns (ITypedConverterCustomFactory);
}

// File: solidity/contracts/utility/Owned.sol


pragma solidity 0.6.12;


/**
 * @dev This contract provides support and utilities for contract ownership.
 */
contract Owned is IOwned {
    address public override owner;
    address public newOwner;

    /**
     * @dev triggered when the owner is updated
     *
     * @param _prevOwner previous owner
     * @param _newOwner  new owner
     */
    event OwnerUpdate(address indexed _prevOwner, address indexed _newOwner);

    /**
     * @dev initializes a new Owned instance
     */
    constructor() public {
        owner = msg.sender;
    }

    // allows execution by the owner only
    modifier ownerOnly {
        _ownerOnly();
        _;
    }

    // error message binary size optimization
    function _ownerOnly() internal view {
        require(msg.sender == owner, "ERR_ACCESS_DENIED");
    }

    /**
     * @dev allows transferring the contract ownership
     * the new owner still needs to accept the transfer
     * can only be called by the contract owner
     *
     * @param _newOwner    new contract owner
     */
    function transferOwnership(address _newOwner) public override ownerOnly {
        require(_newOwner != owner, "ERR_SAME_OWNER");
        newOwner = _newOwner;
    }

    /**
     * @dev used by a new owner to accept an ownership transfer
     */
    function acceptOwnership() public override {
        require(msg.sender == newOwner, "ERR_ACCESS_DENIED");
        emit OwnerUpdate(owner, newOwner);
        owner = newOwner;
        newOwner = address(0);
    }
}

// File: solidity/contracts/utility/Utils.sol


pragma solidity 0.6.12;


/**
 * @dev Utilities & Common Modifiers
 */
contract Utils {
    uint32 internal constant PPM_RESOLUTION = 1000000;
    IERC20 internal constant NATIVE_TOKEN_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);

    // verifies that a value is greater than zero
    modifier greaterThanZero(uint256 _value) {
        _greaterThanZero(_value);
        _;
    }

    // error message binary size optimization
    function _greaterThanZero(uint256 _value) internal pure {
        require(_value > 0, "ERR_ZERO_VALUE");
    }

    // validates an address - currently only checks that it isn't null
    modifier validAddress(address _address) {
        _validAddress(_address);
        _;
    }

    // error message binary size optimization
    function _validAddress(address _address) internal pure {
        require(_address != address(0), "ERR_INVALID_ADDRESS");
    }

    // ensures that the portion is valid
    modifier validPortion(uint32 _portion) {
        _validPortion(_portion);
        _;
    }

    // error message binary size optimization
    function _validPortion(uint32 _portion) internal pure {
        require(_portion > 0 && _portion <= PPM_RESOLUTION, "ERR_INVALID_PORTION");
    }

    // validates an external address - currently only checks that it isn't null or this
    modifier validExternalAddress(address _address) {
        _validExternalAddress(_address);
        _;
    }

    // error message binary size optimization
    function _validExternalAddress(address _address) internal view {
        require(_address != address(0) && _address != address(this), "ERR_INVALID_EXTERNAL_ADDRESS");
    }

    // ensures that the fee is valid
    modifier validFee(uint32 fee) {
        _validFee(fee);
        _;
    }

    // error message binary size optimization
    function _validFee(uint32 fee) internal pure {
        require(fee <= PPM_RESOLUTION, "ERR_INVALID_FEE");
    }
}

// File: solidity/contracts/utility/ContractRegistryClient.sol


pragma solidity 0.6.12;




/**
 * @dev This is the base contract for ContractRegistry clients.
 */
contract ContractRegistryClient is Owned, Utils {
    bytes32 internal constant CONTRACT_REGISTRY = "ContractRegistry";
    bytes32 internal constant BANCOR_NETWORK = "BancorNetwork";
    bytes32 internal constant BANCOR_FORMULA = "BancorFormula";
    bytes32 internal constant CONVERTER_FACTORY = "ConverterFactory";
    bytes32 internal constant CONVERSION_PATH_FINDER = "ConversionPathFinder";
    bytes32 internal constant CONVERTER_UPGRADER = "BancorConverterUpgrader";
    bytes32 internal constant CONVERTER_REGISTRY = "BancorConverterRegistry";
    bytes32 internal constant CONVERTER_REGISTRY_DATA = "BancorConverterRegistryData";
    bytes32 internal constant BNT_TOKEN = "BNTToken";
    bytes32 internal constant BANCOR_X = "BancorX";
    bytes32 internal constant BANCOR_X_UPGRADER = "BancorXUpgrader";
    bytes32 internal constant LIQUIDITY_PROTECTION = "LiquidityProtection";
    bytes32 internal constant NETWORK_SETTINGS = "NetworkSettings";

    IContractRegistry public registry; // address of the current contract-registry
    IContractRegistry public prevRegistry; // address of the previous contract-registry
    bool public onlyOwnerCanUpdateRegistry; // only an owner can update the contract-registry

    /**
     * @dev verifies that the caller is mapped to the given contract name
     *
     * @param _contractName    contract name
     */
    modifier only(bytes32 _contractName) {
        _only(_contractName);
        _;
    }

    // error message binary size optimization
    function _only(bytes32 _contractName) internal view {
        require(msg.sender == addressOf(_contractName), "ERR_ACCESS_DENIED");
    }

    /**
     * @dev initializes a new ContractRegistryClient instance
     *
     * @param  _registry   address of a contract-registry contract
     */
    constructor(IContractRegistry _registry) internal validAddress(address(_registry)) {
        registry = IContractRegistry(_registry);
        prevRegistry = IContractRegistry(_registry);
    }

    /**
     * @dev updates to the new contract-registry
     */
    function updateRegistry() public {
        // verify that this function is permitted
        require(msg.sender == owner || !onlyOwnerCanUpdateRegistry, "ERR_ACCESS_DENIED");

        // get the new contract-registry
        IContractRegistry newRegistry = IContractRegistry(addressOf(CONTRACT_REGISTRY));

        // verify that the new contract-registry is different and not zero
        require(newRegistry != registry && address(newRegistry) != address(0), "ERR_INVALID_REGISTRY");

        // verify that the new contract-registry is pointing to a non-zero contract-registry
        require(newRegistry.addressOf(CONTRACT_REGISTRY) != address(0), "ERR_INVALID_REGISTRY");

        // save a backup of the current contract-registry before replacing it
        prevRegistry = registry;

        // replace the current contract-registry with the new contract-registry
        registry = newRegistry;
    }

    /**
     * @dev restores the previous contract-registry
     */
    function restoreRegistry() public ownerOnly {
        // restore the previous contract-registry
        registry = prevRegistry;
    }

    /**
     * @dev restricts the permission to update the contract-registry
     *
     * @param _onlyOwnerCanUpdateRegistry  indicates whether or not permission is restricted to owner only
     */
    function restrictRegistryUpdate(bool _onlyOwnerCanUpdateRegistry) public ownerOnly {
        // change the permission to update the contract-registry
        onlyOwnerCanUpdateRegistry = _onlyOwnerCanUpdateRegistry;
    }

    /**
     * @dev returns the address associated with the given contract name
     *
     * @param _contractName    contract name
     *
     * @return contract address
     */
    function addressOf(bytes32 _contractName) internal view returns (address) {
        return registry.addressOf(_contractName);
    }
}

// File: solidity/contracts/converter/ConverterUpgrader.sol


pragma solidity 0.6.12;





interface ILegacyConverterVersion45 is IConverter {
    function withdrawTokens(
        IERC20 _token,
        address _to,
        uint256 _amount
    ) external;

    function withdrawETH(address payable _to) external;
}

/**
 * @dev This contract contract allows upgrading an older converter contract (0.4 and up)
 * to the latest version.
 * To begin the upgrade process, simply execute the 'upgrade' function.
 * At the end of the process, the ownership of the newly upgraded converter will be transferred
 * back to the original owner and the original owner will need to execute the 'acceptOwnership' function.
 *
 * The address of the new converter is available in the ConverterUpgrade event.
 *
 * Note that for older converters that don't yet have the 'upgrade' function, ownership should first
 * be transferred manually to the ConverterUpgrader contract using the 'transferOwnership' function
 * and then the upgrader 'upgrade' function should be executed directly.
 */
contract ConverterUpgrader is IConverterUpgrader, ContractRegistryClient {
    /**
     * @dev triggered when the contract accept a converter ownership
     *
     * @param _converter   converter address
     * @param _owner       new owner - local upgrader address
     */
    event ConverterOwned(IConverter indexed _converter, address indexed _owner);

    /**
     * @dev triggered when the upgrading process is done
     *
     * @param _oldConverter    old converter address
     * @param _newConverter    new converter address
     */
    event ConverterUpgrade(address indexed _oldConverter, address indexed _newConverter);

    /**
     * @dev initializes a new ConverterUpgrader instance
     *
     * @param _registry    address of a contract registry contract
     */
    constructor(IContractRegistry _registry) public ContractRegistryClient(_registry) {}

    /**
     * @dev upgrades an old converter to the latest version
     * will throw if ownership wasn't transferred to the upgrader before calling this function.
     * ownership of the new converter will be transferred back to the original owner.
     * fires the ConverterUpgrade event upon success.
     * can only be called by a converter
     *
     * @param _version old converter version
     */
    function upgrade(bytes32 _version) external override {
        upgradeOld(IConverter(msg.sender), _version);
    }

    /**
     * @dev upgrades an old converter to the latest version
     * will throw if ownership wasn't transferred to the upgrader before calling this function.
     * ownership of the new converter will be transferred back to the original owner.
     * fires the ConverterUpgrade event upon success.
     * can only be called by a converter
     *
     * @param _version old converter version
     */
    function upgrade(uint16 _version) external override {
        upgrade(IConverter(msg.sender), _version);
    }

    /**
     * @dev upgrades an old converter to the latest version
     * will throw if ownership wasn't transferred to the upgrader before calling this function.
     * ownership of the new converter will be transferred back to the original owner.
     * fires the ConverterUpgrade event upon success.
     *
     * @param _converter old converter contract address
     */
    function upgradeOld(
        IConverter _converter,
        bytes32 /* _version */
    ) public {
        // the upgrader doesn't require the version for older converters
        upgrade(_converter, 0);
    }

    /**
     * @dev upgrades an old converter to the latest version
     * will throw if ownership wasn't transferred to the upgrader before calling this function.
     * ownership of the new converter will be transferred back to the original owner.
     * fires the ConverterUpgrade event upon success.
     *
     * @param _converter old converter contract address
     * @param _version old converter version
     */
    function upgrade(IConverter _converter, uint16 _version) private {
        IConverter converter = IConverter(_converter);
        address prevOwner = converter.owner();
        acceptConverterOwnership(converter);
        IConverter newConverter = createConverter(converter);
        copyReserves(converter, newConverter);
        copyConversionFee(converter, newConverter);
        transferReserveBalances(converter, newConverter, _version);
        IConverterAnchor anchor = converter.token();

        if (anchor.owner() == address(converter)) {
            converter.transferTokenOwnership(address(newConverter));
            newConverter.acceptAnchorOwnership();
        }

        converter.transferOwnership(prevOwner);
        newConverter.transferOwnership(prevOwner);

        newConverter.onUpgradeComplete();

        emit ConverterUpgrade(address(converter), address(newConverter));
    }

    /**
     * @dev the first step when upgrading a converter is to transfer the ownership to the local contract.
     * the upgrader contract then needs to accept the ownership transfer before initiating
     * the upgrade process.
     * fires the ConverterOwned event upon success
     *
     * @param _oldConverter       converter to accept ownership of
     */
    function acceptConverterOwnership(IConverter _oldConverter) private {
        _oldConverter.acceptOwnership();
        emit ConverterOwned(_oldConverter, address(this));
    }

    /**
     * @dev creates a new converter with same basic data as the original old converter
     * the newly created converter will have no reserves at this step.
     *
     * @param _oldConverter    old converter contract address
     *
     * @return the new converter  new converter contract address
     */
    function createConverter(IConverter _oldConverter) private returns (IConverter) {
        IConverterAnchor anchor = _oldConverter.token();
        uint32 maxConversionFee = _oldConverter.maxConversionFee();
        uint16 reserveTokenCount = _oldConverter.connectorTokenCount();

        // determine new converter type
        uint16 newType = 0;
        // new converter - get the type from the converter itself
        if (isV28OrHigherConverter(_oldConverter)) {
            newType = _oldConverter.converterType();
        } else if (reserveTokenCount > 1) {
            // old converter - if it has 1 reserve token, the type is a liquid token, otherwise the type liquidity pool
            newType = 1;
        }

        if (newType == 1 && reserveTokenCount == 2) {
            (, uint32 weight0, , , ) = _oldConverter.connectors(_oldConverter.connectorTokens(0));
            (, uint32 weight1, , , ) = _oldConverter.connectors(_oldConverter.connectorTokens(1));
            if (weight0 == PPM_RESOLUTION / 2 && weight1 == PPM_RESOLUTION / 2) {
                newType = 3;
            }
        }

        IConverterFactory converterFactory = IConverterFactory(addressOf(CONVERTER_FACTORY));
        IConverter converter = converterFactory.createConverter(newType, anchor, registry, maxConversionFee);

        converter.acceptOwnership();
        return converter;
    }

    /**
     * @dev copies the reserves from the old converter to the new one.
     * note that this will not work for an unlimited number of reserves due to block gas limit constraints.
     *
     * @param _oldConverter    old converter contract address
     * @param _newConverter    new converter contract address
     */
    function copyReserves(IConverter _oldConverter, IConverter _newConverter) private {
        uint16 reserveTokenCount = _oldConverter.connectorTokenCount();

        for (uint16 i = 0; i < reserveTokenCount; i++) {
            IERC20 reserveAddress = _oldConverter.connectorTokens(i);
            (, uint32 weight, , , ) = _oldConverter.connectors(reserveAddress);

            _newConverter.addReserve(reserveAddress, weight);
        }
    }

    /**
     * @dev copies the conversion fee from the old converter to the new one
     *
     * @param _oldConverter    old converter contract address
     * @param _newConverter    new converter contract address
     */
    function copyConversionFee(IConverter _oldConverter, IConverter _newConverter) private {
        uint32 conversionFee = _oldConverter.conversionFee();
        _newConverter.setConversionFee(conversionFee);
    }

    /**
     * @dev transfers the balance of each reserve in the old converter to the new one.
     * note that the function assumes that the new converter already has the exact same number of reserves
     * also, this will not work for an unlimited number of reserves due to block gas limit constraints.
     *
     * @param _oldConverter    old converter contract address
     * @param _newConverter    new converter contract address
     * @param _version old converter version
     */
    function transferReserveBalances(
        IConverter _oldConverter,
        IConverter _newConverter,
        uint16 _version
    ) private {
        if (_version <= 45) {
            transferReserveBalancesVersion45(ILegacyConverterVersion45(address(_oldConverter)), _newConverter);

            return;
        }

        _oldConverter.transferReservesOnUpgrade(address(_newConverter));
    }

    /**
     * @dev transfers the balance of each reserve in the old converter to the new one.
     * note that the function assumes that the new converter already has the exact same number of reserves
     * also, this will not work for an unlimited number of reserves due to block gas limit constraints.
     *
     * @param _oldConverter old converter contract address
     * @param _newConverter new converter contract address
     */
    function transferReserveBalancesVersion45(ILegacyConverterVersion45 _oldConverter, IConverter _newConverter)
        private
    {
        uint256 reserveBalance;
        uint16 reserveTokenCount = _oldConverter.connectorTokenCount();

        for (uint16 i = 0; i < reserveTokenCount; i++) {
            IERC20 reserveAddress = _oldConverter.connectorTokens(i);
            // Ether reserve
            if (reserveAddress == NATIVE_TOKEN_ADDRESS) {
                if (address(_oldConverter).balance > 0) {
                    _oldConverter.withdrawETH(address(_newConverter));
                }
            }
            // ERC20 reserve token
            else {
                IERC20 connector = reserveAddress;
                reserveBalance = connector.balanceOf(address(_oldConverter));
                if (reserveBalance > 0) {
                    _oldConverter.withdrawTokens(connector, address(_newConverter), reserveBalance);
                }
            }
        }
    }

    bytes4 private constant IS_V28_OR_HIGHER_FUNC_SELECTOR = bytes4(keccak256("isV28OrHigher()"));

    // using a static call to identify converter version
    // can't rely on the version number since the function had a different signature in older converters
    function isV28OrHigherConverter(IConverter _converter) internal view returns (bool) {
        bytes memory data = abi.encodeWithSelector(IS_V28_OR_HIGHER_FUNC_SELECTOR);
        (bool success, bytes memory returnData) = address(_converter).staticcall{ gas: 4000 }(data);

        if (success && returnData.length == 32) {
            return abi.decode(returnData, (bool));
        }

        return false;
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"contract IContractRegistry","name":"_registry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IConverter","name":"_converter","type":"address"},{"indexed":true,"internalType":"address","name":"_owner","type":"address"}],"name":"ConverterOwned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_oldConverter","type":"address"},{"indexed":true,"internalType":"address","name":"_newConverter","type":"address"}],"name":"ConverterUpgrade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_prevOwner","type":"address"},{"indexed":true,"internalType":"address","name":"_newOwner","type":"address"}],"name":"OwnerUpdate","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"newOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"onlyOwnerCanUpdateRegistry","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prevRegistry","outputs":[{"internalType":"contract IContractRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"contract IContractRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"restoreRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_onlyOwnerCanUpdateRegistry","type":"bool"}],"name":"restrictRegistryUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"upgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_version","type":"bytes32"}],"name":"upgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IConverter","name":"_converter","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"upgradeOld","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b506040516118543803806118548339818101604052602081101561003357600080fd5b5051600080546001600160a01b03191633179055808061005281610083565b50600280546001600160a01b039092166001600160a01b0319928316811790915560038054909216179055506100e1565b6001600160a01b0381166100de576040805162461bcd60e51b815260206004820152601360248201527f4552525f494e56414c49445f4144445245535300000000000000000000000000604482015290519081900360640190fd5b50565b611764806100f06000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c80638da5cb5b1161008c578063bc444e1311610066578063bc444e131461017e578063d4ee1d901461019b578063f2cfed87146101a3578063f2fde38b146101cf576100cf565b80638da5cb5b1461014d57806390f58c9614610155578063b4a176d314610176576100cf565b8063024c7ec7146100d45780632fe8a6ad146100f557806349d10b641461011157806361cd756e1461011957806379ba50971461013d5780637b10399914610145575b600080fd5b6100f3600480360360208110156100ea57600080fd5b503515156101f5565b005b6100fd61021b565b604080519115158252519081900360200190f35b6100f361022b565b610121610433565b604080516001600160a01b039092168252519081900360200190f35b6100f3610442565b6101216104f9565b610121610508565b6100f36004803603602081101561016b57600080fd5b503561ffff16610517565b6100f3610524565b6100f36004803603602081101561019457600080fd5b5035610550565b61012161055a565b6100f3600480360360408110156101b957600080fd5b506001600160a01b038135169060200135610569565b6100f3600480360360208110156101e557600080fd5b50356001600160a01b0316610578565b6101fd6105f6565b60038054911515600160a01b0260ff60a01b19909216919091179055565b600354600160a01b900460ff1681565b6000546001600160a01b031633148061024e5750600354600160a01b900460ff16155b610293576040805162461bcd60e51b815260206004820152601160248201527011549497d050d0d154d4d7d11153925151607a1b604482015290519081900360640190fd5b60006102b16f436f6e7472616374526567697374727960801b61064b565b6002549091506001600160a01b038083169116148015906102da57506001600160a01b03811615155b610322576040805162461bcd60e51b81526020600482015260146024820152734552525f494e56414c49445f524547495354525960601b604482015290519081900360640190fd5b60006001600160a01b0316816001600160a01b031663bb34534c6f436f6e7472616374526567697374727960801b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561038457600080fd5b505afa158015610398573d6000803e3d6000fd5b505050506040513d60208110156103ae57600080fd5b50516001600160a01b03161415610403576040805162461bcd60e51b81526020600482015260146024820152734552525f494e56414c49445f524547495354525960601b604482015290519081900360640190fd5b60028054600380546001600160a01b038084166001600160a01b0319928316179092559091169216919091179055565b6003546001600160a01b031681565b6001546001600160a01b03163314610495576040805162461bcd60e51b815260206004820152601160248201527011549497d050d0d154d4d7d11153925151607a1b604482015290519081900360640190fd5b600154600080546040516001600160a01b0393841693909116917f343765429aea5a34b3ff6a3785a98a5abb2597aca87bfbb58632c173d585373a91a360018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6002546001600160a01b031681565b6000546001600160a01b031681565b61052133826106cb565b50565b61052c6105f6565b600354600280546001600160a01b0319166001600160a01b03909216919091179055565b6105213382610569565b6001546001600160a01b031681565b6105748260006106cb565b5050565b6105806105f6565b6000546001600160a01b03828116911614156105d4576040805162461bcd60e51b815260206004820152600e60248201526d22a9292fa9a0a6a2afa7aba722a960911b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610649576040805162461bcd60e51b815260206004820152601160248201527011549497d050d0d154d4d7d11153925151607a1b604482015290519081900360640190fd5b565b60025460408051632ecd14d360e21b81526004810184905290516000926001600160a01b03169163bb34534c916024808301926020929190829003018186803b15801561069757600080fd5b505afa1580156106ab573d6000803e3d6000fd5b505050506040513d60208110156106c157600080fd5b505190505b919050565b60008290506000816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561070b57600080fd5b505afa15801561071f573d6000803e3d6000fd5b505050506040513d602081101561073557600080fd5b5051905061074282610a74565b600061074d83610b00565b90506107598382611034565b610763838261122b565b61076e838286611300565b6000836001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107a957600080fd5b505afa1580156107bd573d6000803e3d6000fd5b505050506040513d60208110156107d357600080fd5b505160408051638da5cb5b60e01b815290519192506001600160a01b038087169290841691638da5cb5b916004808301926020929190829003018186803b15801561081d57600080fd5b505afa158015610831573d6000803e3d6000fd5b505050506040513d602081101561084757600080fd5b50516001600160a01b0316141561091357836001600160a01b03166321e6b53d836040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b1580156108a757600080fd5b505af11580156108bb573d6000803e3d6000fd5b50505050816001600160a01b031663cdc91c696040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156108fa57600080fd5b505af115801561090e573d6000803e3d6000fd5b505050505b836001600160a01b031663f2fde38b846040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b15801561096257600080fd5b505af1158015610976573d6000803e3d6000fd5b50505050816001600160a01b031663f2fde38b846040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b1580156109c957600080fd5b505af11580156109dd573d6000803e3d6000fd5b50505050816001600160a01b03166350dc78f96040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a1c57600080fd5b505af1158015610a30573d6000803e3d6000fd5b50506040516001600160a01b038086169350871691507f522b846327aea07106ec4d64ae4b6d6dea47689884dab650fd3a1f2e1d6a270190600090a3505050505050565b806001600160a01b03166379ba50976040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610aaf57600080fd5b505af1158015610ac3573d6000803e3d6000fd5b50506040513092506001600160a01b03841691507ff764604894fa993d4370a9cb28b81c11deb1aafdb2909156173ae3833dad807590600090a350565b600080826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b3c57600080fd5b505afa158015610b50573d6000803e3d6000fd5b505050506040513d6020811015610b6657600080fd5b5051604080516394c275ad60e01b815290519192506000916001600160a01b038616916394c275ad916004808301926020929190829003018186803b158015610bae57600080fd5b505afa158015610bc2573d6000803e3d6000fd5b505050506040513d6020811015610bd857600080fd5b5051604080516371f52bf360e01b815290519192506000916001600160a01b038716916371f52bf3916004808301926020929190829003018186803b158015610c2057600080fd5b505afa158015610c34573d6000803e3d6000fd5b505050506040513d6020811015610c4a57600080fd5b505190506000610c598661136f565b15610cca57856001600160a01b0316633e8ff43f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c9757600080fd5b505afa158015610cab573d6000803e3d6000fd5b505050506040513d6020811015610cc157600080fd5b50519050610cdb565b60018261ffff161115610cdb575060015b8061ffff166001148015610cf357508161ffff166002145b15610f0f576000866001600160a01b0316630e53aae9886001600160a01b03166319b6401560006040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610d4e57600080fd5b505afa158015610d62573d6000803e3d6000fd5b505050506040513d6020811015610d7857600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b0390921660048301525160248083019260a0929190829003018186803b158015610dbf57600080fd5b505afa158015610dd3573d6000803e3d6000fd5b505050506040513d60a0811015610de957600080fd5b50602090810151604080516319b6401560e01b81526001600482015290519193506000926001600160a01b038b1692630e53aae99284926319b6401592602480840193829003018186803b158015610e4057600080fd5b505afa158015610e54573d6000803e3d6000fd5b505050506040513d6020811015610e6a57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b0390921660048301525160248083019260a0929190829003018186803b158015610eb157600080fd5b505afa158015610ec5573d6000803e3d6000fd5b505050506040513d60a0811015610edb57600080fd5b5060200151905063ffffffff82166207a120148015610f02575063ffffffff81166207a120145b15610f0c57600392505b50505b6000610f2d6f436f6e766572746572466163746f727960801b61064b565b60025460408051630afb25b560e11b815261ffff861660048201526001600160a01b038981166024830152928316604482015263ffffffff881660648201529051929350600092918416916315f64b6a9160848082019260209290919082900301818787803b158015610f9f57600080fd5b505af1158015610fb3573d6000803e3d6000fd5b505050506040513d6020811015610fc957600080fd5b5051604080516379ba509760e01b815290519192506001600160a01b038316916379ba50979160048082019260009290919082900301818387803b15801561101057600080fd5b505af1158015611024573d6000803e3d6000fd5b50929a9950505050505050505050565b6000826001600160a01b03166371f52bf36040518163ffffffff1660e01b815260040160206040518083038186803b15801561106f57600080fd5b505afa158015611083573d6000803e3d6000fd5b505050506040513d602081101561109957600080fd5b5051905060005b8161ffff168161ffff161015611225576000846001600160a01b03166319b64015836040518263ffffffff1660e01b8152600401808261ffff16815260200191505060206040518083038186803b1580156110fa57600080fd5b505afa15801561110e573d6000803e3d6000fd5b505050506040513d602081101561112457600080fd5b505160408051630e53aae960e01b81526001600160a01b038084166004830152915192935060009291881691630e53aae99160248082019260a092909190829003018186803b15801561117657600080fd5b505afa15801561118a573d6000803e3d6000fd5b505050506040513d60a08110156111a057600080fd5b506020015160408051631a9274b160e21b81526001600160a01b03858116600483015263ffffffff84166024830152915192935090871691636a49d2c49160448082019260009290919082900301818387803b1580156111ff57600080fd5b505af1158015611213573d6000803e3d6000fd5b5050600190940193506110a092505050565b50505050565b6000826001600160a01b031663579cd3ca6040518163ffffffff1660e01b815260040160206040518083038186803b15801561126657600080fd5b505afa15801561127a573d6000803e3d6000fd5b505050506040513d602081101561129057600080fd5b50516040805163ecbca55d60e01b815263ffffffff8316600482015290519192506001600160a01b0384169163ecbca55d9160248082019260009290919082900301818387803b1580156112e357600080fd5b505af11580156112f7573d6000803e3d6000fd5b50505050505050565b602d8161ffff161161131b576113168383611486565b61136a565b826001600160a01b031663038d09e1836040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b1580156112e357600080fd5b505050565b60408051600481526024810182526020810180516001600160e01b031663349814a760e21b1781529151815160009384926060926001600160a01b03881692610fa0928792909182918083835b602083106113db5780518252601f1990920191602091820191016113bc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303818686fa925050503d806000811461143c576040519150601f19603f3d011682016040523d82523d6000602084013e611441565b606091505b5091509150818015611454575080516020145b1561147b5780806020019051602081101561146e57600080fd5b505193506106c692505050565b506000949350505050565b600080836001600160a01b03166371f52bf36040518163ffffffff1660e01b815260040160206040518083038186803b1580156114c257600080fd5b505afa1580156114d6573d6000803e3d6000fd5b505050506040513d60208110156114ec57600080fd5b5051905060005b8161ffff168161ffff161015611727576000856001600160a01b03166319b64015836040518263ffffffff1660e01b8152600401808261ffff16815260200191505060206040518083038186803b15801561154d57600080fd5b505afa158015611561573d6000803e3d6000fd5b505050506040513d602081101561157757600080fd5b505190506001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561161d576001600160a01b038616311561161857856001600160a01b031663690d8320866040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b1580156115ff57600080fd5b505af1158015611613573d6000803e3d6000fd5b505050505b61171e565b604080516370a0823160e01b81526001600160a01b038881166004830152915183928316916370a08231916024808301926020929190829003018186803b15801561166757600080fd5b505afa15801561167b573d6000803e3d6000fd5b505050506040513d602081101561169157600080fd5b50519450841561171c57866001600160a01b0316635e35359e8288886040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561170357600080fd5b505af1158015611717573d6000803e3d6000fd5b505050505b505b506001016114f3565b505050505056fea2646970667358221220bb3a2f04c77d42089e7e53e8a362ce595c5fa772c33e4e4b50955a051ffafda964736f6c634300060c003300000000000000000000000052ae12abe5d8bd778bd5397f99ca900624cfadd4

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c80638da5cb5b1161008c578063bc444e1311610066578063bc444e131461017e578063d4ee1d901461019b578063f2cfed87146101a3578063f2fde38b146101cf576100cf565b80638da5cb5b1461014d57806390f58c9614610155578063b4a176d314610176576100cf565b8063024c7ec7146100d45780632fe8a6ad146100f557806349d10b641461011157806361cd756e1461011957806379ba50971461013d5780637b10399914610145575b600080fd5b6100f3600480360360208110156100ea57600080fd5b503515156101f5565b005b6100fd61021b565b604080519115158252519081900360200190f35b6100f361022b565b610121610433565b604080516001600160a01b039092168252519081900360200190f35b6100f3610442565b6101216104f9565b610121610508565b6100f36004803603602081101561016b57600080fd5b503561ffff16610517565b6100f3610524565b6100f36004803603602081101561019457600080fd5b5035610550565b61012161055a565b6100f3600480360360408110156101b957600080fd5b506001600160a01b038135169060200135610569565b6100f3600480360360208110156101e557600080fd5b50356001600160a01b0316610578565b6101fd6105f6565b60038054911515600160a01b0260ff60a01b19909216919091179055565b600354600160a01b900460ff1681565b6000546001600160a01b031633148061024e5750600354600160a01b900460ff16155b610293576040805162461bcd60e51b815260206004820152601160248201527011549497d050d0d154d4d7d11153925151607a1b604482015290519081900360640190fd5b60006102b16f436f6e7472616374526567697374727960801b61064b565b6002549091506001600160a01b038083169116148015906102da57506001600160a01b03811615155b610322576040805162461bcd60e51b81526020600482015260146024820152734552525f494e56414c49445f524547495354525960601b604482015290519081900360640190fd5b60006001600160a01b0316816001600160a01b031663bb34534c6f436f6e7472616374526567697374727960801b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561038457600080fd5b505afa158015610398573d6000803e3d6000fd5b505050506040513d60208110156103ae57600080fd5b50516001600160a01b03161415610403576040805162461bcd60e51b81526020600482015260146024820152734552525f494e56414c49445f524547495354525960601b604482015290519081900360640190fd5b60028054600380546001600160a01b038084166001600160a01b0319928316179092559091169216919091179055565b6003546001600160a01b031681565b6001546001600160a01b03163314610495576040805162461bcd60e51b815260206004820152601160248201527011549497d050d0d154d4d7d11153925151607a1b604482015290519081900360640190fd5b600154600080546040516001600160a01b0393841693909116917f343765429aea5a34b3ff6a3785a98a5abb2597aca87bfbb58632c173d585373a91a360018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6002546001600160a01b031681565b6000546001600160a01b031681565b61052133826106cb565b50565b61052c6105f6565b600354600280546001600160a01b0319166001600160a01b03909216919091179055565b6105213382610569565b6001546001600160a01b031681565b6105748260006106cb565b5050565b6105806105f6565b6000546001600160a01b03828116911614156105d4576040805162461bcd60e51b815260206004820152600e60248201526d22a9292fa9a0a6a2afa7aba722a960911b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610649576040805162461bcd60e51b815260206004820152601160248201527011549497d050d0d154d4d7d11153925151607a1b604482015290519081900360640190fd5b565b60025460408051632ecd14d360e21b81526004810184905290516000926001600160a01b03169163bb34534c916024808301926020929190829003018186803b15801561069757600080fd5b505afa1580156106ab573d6000803e3d6000fd5b505050506040513d60208110156106c157600080fd5b505190505b919050565b60008290506000816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561070b57600080fd5b505afa15801561071f573d6000803e3d6000fd5b505050506040513d602081101561073557600080fd5b5051905061074282610a74565b600061074d83610b00565b90506107598382611034565b610763838261122b565b61076e838286611300565b6000836001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107a957600080fd5b505afa1580156107bd573d6000803e3d6000fd5b505050506040513d60208110156107d357600080fd5b505160408051638da5cb5b60e01b815290519192506001600160a01b038087169290841691638da5cb5b916004808301926020929190829003018186803b15801561081d57600080fd5b505afa158015610831573d6000803e3d6000fd5b505050506040513d602081101561084757600080fd5b50516001600160a01b0316141561091357836001600160a01b03166321e6b53d836040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b1580156108a757600080fd5b505af11580156108bb573d6000803e3d6000fd5b50505050816001600160a01b031663cdc91c696040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156108fa57600080fd5b505af115801561090e573d6000803e3d6000fd5b505050505b836001600160a01b031663f2fde38b846040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b15801561096257600080fd5b505af1158015610976573d6000803e3d6000fd5b50505050816001600160a01b031663f2fde38b846040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b1580156109c957600080fd5b505af11580156109dd573d6000803e3d6000fd5b50505050816001600160a01b03166350dc78f96040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a1c57600080fd5b505af1158015610a30573d6000803e3d6000fd5b50506040516001600160a01b038086169350871691507f522b846327aea07106ec4d64ae4b6d6dea47689884dab650fd3a1f2e1d6a270190600090a3505050505050565b806001600160a01b03166379ba50976040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610aaf57600080fd5b505af1158015610ac3573d6000803e3d6000fd5b50506040513092506001600160a01b03841691507ff764604894fa993d4370a9cb28b81c11deb1aafdb2909156173ae3833dad807590600090a350565b600080826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b3c57600080fd5b505afa158015610b50573d6000803e3d6000fd5b505050506040513d6020811015610b6657600080fd5b5051604080516394c275ad60e01b815290519192506000916001600160a01b038616916394c275ad916004808301926020929190829003018186803b158015610bae57600080fd5b505afa158015610bc2573d6000803e3d6000fd5b505050506040513d6020811015610bd857600080fd5b5051604080516371f52bf360e01b815290519192506000916001600160a01b038716916371f52bf3916004808301926020929190829003018186803b158015610c2057600080fd5b505afa158015610c34573d6000803e3d6000fd5b505050506040513d6020811015610c4a57600080fd5b505190506000610c598661136f565b15610cca57856001600160a01b0316633e8ff43f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c9757600080fd5b505afa158015610cab573d6000803e3d6000fd5b505050506040513d6020811015610cc157600080fd5b50519050610cdb565b60018261ffff161115610cdb575060015b8061ffff166001148015610cf357508161ffff166002145b15610f0f576000866001600160a01b0316630e53aae9886001600160a01b03166319b6401560006040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610d4e57600080fd5b505afa158015610d62573d6000803e3d6000fd5b505050506040513d6020811015610d7857600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b0390921660048301525160248083019260a0929190829003018186803b158015610dbf57600080fd5b505afa158015610dd3573d6000803e3d6000fd5b505050506040513d60a0811015610de957600080fd5b50602090810151604080516319b6401560e01b81526001600482015290519193506000926001600160a01b038b1692630e53aae99284926319b6401592602480840193829003018186803b158015610e4057600080fd5b505afa158015610e54573d6000803e3d6000fd5b505050506040513d6020811015610e6a57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b0390921660048301525160248083019260a0929190829003018186803b158015610eb157600080fd5b505afa158015610ec5573d6000803e3d6000fd5b505050506040513d60a0811015610edb57600080fd5b5060200151905063ffffffff82166207a120148015610f02575063ffffffff81166207a120145b15610f0c57600392505b50505b6000610f2d6f436f6e766572746572466163746f727960801b61064b565b60025460408051630afb25b560e11b815261ffff861660048201526001600160a01b038981166024830152928316604482015263ffffffff881660648201529051929350600092918416916315f64b6a9160848082019260209290919082900301818787803b158015610f9f57600080fd5b505af1158015610fb3573d6000803e3d6000fd5b505050506040513d6020811015610fc957600080fd5b5051604080516379ba509760e01b815290519192506001600160a01b038316916379ba50979160048082019260009290919082900301818387803b15801561101057600080fd5b505af1158015611024573d6000803e3d6000fd5b50929a9950505050505050505050565b6000826001600160a01b03166371f52bf36040518163ffffffff1660e01b815260040160206040518083038186803b15801561106f57600080fd5b505afa158015611083573d6000803e3d6000fd5b505050506040513d602081101561109957600080fd5b5051905060005b8161ffff168161ffff161015611225576000846001600160a01b03166319b64015836040518263ffffffff1660e01b8152600401808261ffff16815260200191505060206040518083038186803b1580156110fa57600080fd5b505afa15801561110e573d6000803e3d6000fd5b505050506040513d602081101561112457600080fd5b505160408051630e53aae960e01b81526001600160a01b038084166004830152915192935060009291881691630e53aae99160248082019260a092909190829003018186803b15801561117657600080fd5b505afa15801561118a573d6000803e3d6000fd5b505050506040513d60a08110156111a057600080fd5b506020015160408051631a9274b160e21b81526001600160a01b03858116600483015263ffffffff84166024830152915192935090871691636a49d2c49160448082019260009290919082900301818387803b1580156111ff57600080fd5b505af1158015611213573d6000803e3d6000fd5b5050600190940193506110a092505050565b50505050565b6000826001600160a01b031663579cd3ca6040518163ffffffff1660e01b815260040160206040518083038186803b15801561126657600080fd5b505afa15801561127a573d6000803e3d6000fd5b505050506040513d602081101561129057600080fd5b50516040805163ecbca55d60e01b815263ffffffff8316600482015290519192506001600160a01b0384169163ecbca55d9160248082019260009290919082900301818387803b1580156112e357600080fd5b505af11580156112f7573d6000803e3d6000fd5b50505050505050565b602d8161ffff161161131b576113168383611486565b61136a565b826001600160a01b031663038d09e1836040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b1580156112e357600080fd5b505050565b60408051600481526024810182526020810180516001600160e01b031663349814a760e21b1781529151815160009384926060926001600160a01b03881692610fa0928792909182918083835b602083106113db5780518252601f1990920191602091820191016113bc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303818686fa925050503d806000811461143c576040519150601f19603f3d011682016040523d82523d6000602084013e611441565b606091505b5091509150818015611454575080516020145b1561147b5780806020019051602081101561146e57600080fd5b505193506106c692505050565b506000949350505050565b600080836001600160a01b03166371f52bf36040518163ffffffff1660e01b815260040160206040518083038186803b1580156114c257600080fd5b505afa1580156114d6573d6000803e3d6000fd5b505050506040513d60208110156114ec57600080fd5b5051905060005b8161ffff168161ffff161015611727576000856001600160a01b03166319b64015836040518263ffffffff1660e01b8152600401808261ffff16815260200191505060206040518083038186803b15801561154d57600080fd5b505afa158015611561573d6000803e3d6000fd5b505050506040513d602081101561157757600080fd5b505190506001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561161d576001600160a01b038616311561161857856001600160a01b031663690d8320866040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b1580156115ff57600080fd5b505af1158015611613573d6000803e3d6000fd5b505050505b61171e565b604080516370a0823160e01b81526001600160a01b038881166004830152915183928316916370a08231916024808301926020929190829003018186803b15801561166757600080fd5b505afa15801561167b573d6000803e3d6000fd5b505050506040513d602081101561169157600080fd5b50519450841561171c57866001600160a01b0316635e35359e8288886040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561170357600080fd5b505af1158015611717573d6000803e3d6000fd5b505050505b505b506001016114f3565b505050505056fea2646970667358221220bb3a2f04c77d42089e7e53e8a362ce595c5fa772c33e4e4b50955a051ffafda964736f6c634300060c0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000052ae12abe5d8bd778bd5397f99ca900624cfadd4

-----Decoded View---------------
Arg [0] : _registry (address): 0x52Ae12ABe5D8BD778BD5397F99cA900624CfADD4

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000052ae12abe5d8bd778bd5397f99ca900624cfadd4


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.