ETH Price: $3,462.34 (+2.11%)
Gas: 6 Gwei

Contract

0xb4cFd748B23c103f73c10259171ECc5Ef1DD31dA
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Migrate Dual Tok...202114412024-07-01 11:42:231 hr ago1719834143IN
Open Ticketing Ecosystem: Migration
0 ETH0.000500264.23685911
Migrate Dual Tok...202075322024-06-30 22:36:2314 hrs ago1719786983IN
Open Ticketing Ecosystem: Migration
0 ETH0.001628734.3907841
Migrate Dual Tok...202066952024-06-30 19:48:5917 hrs ago1719776939IN
Open Ticketing Ecosystem: Migration
0 ETH0.000432453.66256613
Migrate Dual Tok...202055912024-06-30 16:07:1121 hrs ago1719763631IN
Open Ticketing Ecosystem: Migration
0 ETH0.000560154.74407902
Migrate Dual Tok...202015392024-06-30 2:32:4734 hrs ago1719714767IN
Open Ticketing Ecosystem: Migration
0 ETH0.00052551.69792427
Migrate Dual Tok...202000302024-06-29 21:29:1139 hrs ago1719696551IN
Open Ticketing Ecosystem: Migration
0 ETH0.000511711.65331555
Migrate Dual Tok...201986642024-06-29 16:54:2344 hrs ago1719680063IN
Open Ticketing Ecosystem: Migration
0 ETH0.000292332.51014769
Migrate Dual Tok...201895922024-06-28 10:29:113 days ago1719570551IN
Open Ticketing Ecosystem: Migration
0 ETH0.002547557.05232375
Migrate Dual Tok...201869952024-06-28 1:47:233 days ago1719539243IN
Open Ticketing Ecosystem: Migration
0 ETH0.00201376.36212308
Migrate Dual Tok...201842522024-06-27 16:35:113 days ago1719506111IN
Open Ticketing Ecosystem: Migration
0 ETH0.0014478414.08684581
Migrate Dual Tok...201821272024-06-27 9:27:474 days ago1719480467IN
Open Ticketing Ecosystem: Migration
0 ETH0.000631065.34458513
Migrate Dual Tok...201797602024-06-27 1:32:474 days ago1719451967IN
Open Ticketing Ecosystem: Migration
0 ETH0.000543814.60568801
Migrate Dual Tok...201710322024-06-25 20:18:115 days ago1719346691IN
Open Ticketing Ecosystem: Migration
0 ETH0.000964218.16614162
Migrate Dual Tok...201704192024-06-25 18:14:355 days ago1719339275IN
Open Ticketing Ecosystem: Migration
0 ETH0.001057728.95808865
Migrate Dual Tok...201703992024-06-25 18:10:355 days ago1719339035IN
Open Ticketing Ecosystem: Migration
0 ETH0.000807957.86169061
Migrate Dual Tok...201703732024-06-25 18:05:235 days ago1719338723IN
Open Ticketing Ecosystem: Migration
0 ETH0.002528998.51113171
Migrate Dual Tok...201703622024-06-25 18:02:595 days ago1719338579IN
Open Ticketing Ecosystem: Migration
0 ETH0.002345117.89229531
Migrate Dual Tok...201703432024-06-25 17:59:115 days ago1719338351IN
Open Ticketing Ecosystem: Migration
0 ETH0.002201947.40997075
Migrate Dual Tok...201703122024-06-25 17:52:595 days ago1719337979IN
Open Ticketing Ecosystem: Migration
0 ETH0.002299977.39992711
Migrate Dual Tok...201702262024-06-25 17:35:475 days ago1719336947IN
Open Ticketing Ecosystem: Migration
0 ETH0.001005528.18491289
Migrate Dual Tok...201670542024-06-25 6:58:116 days ago1719298691IN
Open Ticketing Ecosystem: Migration
0 ETH0.000383053.2441487
Migrate Dual Tok...201617532024-06-24 13:11:117 days ago1719234671IN
Open Ticketing Ecosystem: Migration
0 ETH0.003038199.65059202
Migrate Dual Tok...201606982024-06-24 9:38:357 days ago1719221915IN
Open Ticketing Ecosystem: Migration
0 ETH0.0017561417.08479086
Migrate Dual Tok...201606072024-06-24 9:20:237 days ago1719220823IN
Open Ticketing Ecosystem: Migration
0 ETH0.000633335.36381639
Migrate Dual Tok...201599802024-06-24 7:13:357 days ago1719213215IN
Open Ticketing Ecosystem: Migration
0 ETH0.000354883.0477445
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
OPNMigration

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
london EvmVersion
File 1 of 8 : OPNMigration.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import {IERC20} from "erc20/interfaces/IERC20.sol";
import "@solmate/src/auth/Owned.sol";
import "./interfaces/IMigrationLockedRevenueDistributionToken.sol";
import "./interfaces/IGETToken.sol";
import "./interfaces/IOPNToken.sol";
import "./interfaces/IOPNMintManager.sol";
import "./interfaces/IOPNMigration.sol";

contract OPNMigration is IOPNMigration, Owned {
    // GET -> OPN ratio (1:1000) - 1 GET = 1000 OPN
    uint256 public constant GET_TO_OPN_RATIO = 1e3;

    // amount of time the migration is available for after the start of the migration
    uint256 public constant MIGRATION_AVAILABLE_UNTIL = 600 days;

    // chain id
    uint256 public immutable chainId;

    // OPN token address
    IOPNToken public openToken;

    // OPN mint manager address
    IOPNMintManager public opnMintManager;

    // xOPN token address
    IMigrationLockedRevenueDistributionToken public xOpenToken;

    // GET token address
    IGETToken public immutable liquidGETToken;

    // xGET token address
    IMigrationLockedRevenueDistributionToken public immutable stakedGETToken;

    address public immutable migrationDestinationAddress;

    // Storage variables for migration statistics

    // total amount of liquid GET migrated
    uint256 public totalLiquidGETMigrated;

    // total amount of  XGET migrated to XOPN, note xget isn't migrated, the xget is redeemed and then this GET is migrated (and restaked to XOPN)
    uint256 public totalXGETRedeemed;

    // total amount of GET that was migrated to OPN that was migrated with XGET as input
    uint256 public totalGETMigratedByXGETMigration;

    // total amount of OPN that was staked due to a fee charged on liquid GET migration
    uint256 public totalOPNStakedByGETMigration;

    // total amount of OPN that was minted by all migrations
    uint256 public totalOPNMintedByAllMigration;

    // if the migration is enabled
    bool public isMigrationActive = false;

    // Internal contract config and state

    uint256 private locked = 1; // Used in reentrancy check.

    // stake rate configurations

    // duration of the migration fee, after which the stake rate is 0
    uint256 public durationOfStakeMigrationPeriod;

    // epoch time when the migration starts
    uint256 public startOfMigration;

    // epoch time when the migration is not possible anymore
    uint256 public endOfMigration;

    // initial stake rate at the start of the migration
    uint256 public stakeRateInitial; // so 5 * 1e17 = 50% (SCALED: 1e18)

    // Constructor

    constructor(
        address _initialOwner,
        address _liquidGETAddress,
        address _stakedGETAddress,
        uint256 _startOfMigration,
        uint256 _startStakeRate,
        uint256 _durationOfStakeMigrationPeriod,
        address _bridgeMigrationAddress,
        uint256 _chainId
    ) Owned(_initialOwner) {
        liquidGETToken = IGETToken(_liquidGETAddress);
        stakedGETToken = IMigrationLockedRevenueDistributionToken(
            _stakedGETAddress
        );

        require(
            _startOfMigration > block.timestamp,
            "OPNMigration: Start of migration must be in the future"
        );

        startOfMigration = _startOfMigration;
        endOfMigration = _startOfMigration + MIGRATION_AVAILABLE_UNTIL;
        stakeRateInitial = _startStakeRate;

        require(
            MIGRATION_AVAILABLE_UNTIL > _durationOfStakeMigrationPeriod,
            "OPNMigration: Duration of stake migration period must be less than the total migration period"
        );

        durationOfStakeMigrationPeriod = _durationOfStakeMigrationPeriod;

        migrationDestinationAddress = _bridgeMigrationAddress;
        chainId = _chainId;
    }

    // Modifier functions

    modifier nonReentrant() {
        require(locked == 1, "OPNMigration: Reentrant call");
        locked = 2;
        _;
        locked = 1;
    }

    // Operational functions

    /// @inheritdoc IOPNMigration
    function migrateDualTokens(
        uint256 _amountGET,
        uint256 _amountXGET
    )
        external
        override
        nonReentrant
        returns (
            uint256 amountOPNToUserForGETMigration_,
            uint256 amountXOPNToUserForXGETMigration_,
            uint256 amountOPNStakedForGETMigration_,
            uint256 amountXOPNToUserForGETMigration_,
            uint256 amountGETRedeemedByXGET_
        )
    {
        // Ensure migration is currently active before proceeding.
        require(_isMigrationActive(), "OPNMigration: Migration not active");

        // if both amounts are 0 then revert because there is no point
        require(
            _amountGET > 0 || _amountXGET > 0,
            "OPNMigration: Both amounts are 0"
        );

        // Handle GET token migration.
        if (_amountGET > 0) {
            (
                amountOPNToUserForGETMigration_,
                amountOPNStakedForGETMigration_,
                amountXOPNToUserForGETMigration_
            ) = _migrateLiquidGETTokens(_amountGET);
        }

        // Handle XGET token migration.
        if (_amountXGET > 0) {
            (
                amountXOPNToUserForXGETMigration_,
                amountGETRedeemedByXGET_
            ) = _migrateStakedXGETTokens(_amountXGET);
        }

        // Emit an event to log the completion of the migration process for tracking and transparency.

        emit OPNMigrationComplete(
            msg.sender,
            _amountGET,
            _amountXGET,
            amountOPNToUserForGETMigration_,
            amountXOPNToUserForGETMigration_,
            amountXOPNToUserForXGETMigration_,
            amountOPNStakedForGETMigration_,
            amountGETRedeemedByXGET_,
            amountGETRedeemedByXGET_ * GET_TO_OPN_RATIO
        );

        return (
            amountOPNToUserForGETMigration_,
            amountXOPNToUserForXGETMigration_,
            amountOPNStakedForGETMigration_,
            amountXOPNToUserForGETMigration_,
            amountGETRedeemedByXGET_
        );
    }

    // Internal functions

    function _burn(uint256 _amount) internal {
        if (chainId == 1) {
            liquidGETToken.burn(_amount);
        } else {
            // transfer tokens to the migration destination address - note on polygon we do not burn tokens as the tokens on Polygon are issued by the bridge
            require(
                liquidGETToken.transfer(migrationDestinationAddress, _amount),
                "OPNMigration: GET transfer to migration destination failed"
            );
        }
    }

    function _migrateLiquidGETTokens(
        uint256 _amountGET
    )
        internal
        returns (
            uint256 amountOPNToUserForGETMigration_,
            uint256 amountOPNStakedForGETMigration_,
            uint256 amountXOPNToUserForGETMigration_
        )
    {
        _migratorCheckGET(_amountGET); // Check for GET token balance and approval, then transfer tokens to thi contract and stake them (on ethereum)

        totalLiquidGETMigrated += _amountGET; // Update the total migrated GET counter.

        // Calculate the amount of OPN to mint based on the GET to OPN ratio.
        uint256 amountOPNToMintGET_ = _amountGET * GET_TO_OPN_RATIO;

        totalOPNMintedByAllMigration += amountOPNToMintGET_; // Update the total OPN minted counter.

        uint256 stakeRate_ = _returnCurrentStakeRate(block.timestamp);

        if (stakeRate_ == 0) {
            amountOPNToUserForGETMigration_ = amountOPNToMintGET_;
            amountXOPNToUserForGETMigration_ = 0;
            amountOPNStakedForGETMigration_ = 0;
        } else {
            // Calculate the amount of OPN to stake based on the current stake rate.
            amountOPNStakedForGETMigration_ =
                (amountOPNToMintGET_ * stakeRate_) /
                1e18;

            amountOPNToUserForGETMigration_ =
                amountOPNToMintGET_ -
                amountOPNStakedForGETMigration_; // Calculate the net OPN to allocate to the user.

            totalOPNStakedByGETMigration += amountOPNStakedForGETMigration_; // Update the total OPN staked counter

            // Mint and then stake the calculated OPN amount for transparency and tracking on platforms.
            opnMintManager.issueTokensMigration(
                address(this),
                amountOPNStakedForGETMigration_
            );

            // Approve the xOPN contract to spend the OPN tokens to be staked.
            openToken.approve(
                address(xOpenToken),
                amountOPNStakedForGETMigration_
            );

            // Stake the OPN tokens in the xOPN contract, allocating XOPN tokens to the user.
            amountXOPNToUserForGETMigration_ = xOpenToken.deposit(
                amountOPNStakedForGETMigration_,
                msg.sender
            );
        }

        // Mint OPN tokens for the user. Separate transaction for cleaner look and tracking.
        opnMintManager.issueTokensMigration(
            msg.sender,
            amountOPNToUserForGETMigration_
        );

        return (
            amountOPNToUserForGETMigration_,
            amountOPNStakedForGETMigration_,
            amountXOPNToUserForGETMigration_
        );
    }

    /**
     * @dev Migrates staked XGET tokens to OPN tokens and allocates XOPN tokens to the user.
     * This function handles the entire migration process for staked XGET tokens. It checks the user's XGET token balance and approval,
     * redeems XGET for GET tokens (which are then burned), mints OPN tokens based on the redeemed GET tokens, and finally,
     * stakes a portion of OPN tokens to allocate XOPN tokens to the user.
     * @param _amountXGET The amount of XGET tokens to be migrated.
     * @return amountXOPNToUserForXGETMigration_ The amount of XOPN tokens allocated to the user as a result of the migration.
     * @return amountGETRedeemedByXGET_ The amount of GET tokens redeemed from the XGET tokens.
     */
    function _migrateStakedXGETTokens(
        uint256 _amountXGET
    )
        internal
        returns (
            uint256 amountXOPNToUserForXGETMigration_,
            uint256 amountGETRedeemedByXGET_
        )
    {
        // Check for XGET token balance and approval, then transfer, redeem for GET (the GET will be burned on Ethereum).
        amountGETRedeemedByXGET_ = _migratorCheckXGET(_amountXGET);

        // Update the total XGET redeemed counter.
        totalXGETRedeemed += _amountXGET;

        // Update the total GET migrated via XGET counter.
        totalGETMigratedByXGETMigration += amountGETRedeemedByXGET_;

        // Calculate the amount of OPN to mint for the redeemed GET.
        uint256 amountOPNToMintXGET_ = amountGETRedeemedByXGET_ *
            GET_TO_OPN_RATIO;

        // Update the total OPN minted counter.
        totalOPNMintedByAllMigration += amountOPNToMintXGET_;

        // Mint OPN tokens to this contract for staking.
        opnMintManager.issueTokensMigration(
            address(this),
            amountOPNToMintXGET_
        );

        // Approve the xOPN contract to spend the OPN tokens to be staked.
        openToken.approve(address(xOpenToken), amountOPNToMintXGET_);

        // Stake the OPN tokens in the xOPN contract, allocating XOPN tokens to the user.
        amountXOPNToUserForXGETMigration_ = xOpenToken.deposit(
            amountOPNToMintXGET_,
            msg.sender
        );

        return (amountXOPNToUserForXGETMigration_, amountGETRedeemedByXGET_);
    }

    /**
     * @dev Checks the user's balance and approval for GET tokens, transfers them to the contract, and then burns the GET tokens.
     * This function is a crucial part of the GET to OPN migration process. It ensures that the user has a sufficient balance of GET tokens and has granted the contract
     * permission to use them. After verifying these conditions, it transfers the specified amount of GET tokens from the user to the contract. Finally, it burns these tokens,
     * effectively removing them from circulation as part of the migration process.
     * @param _amountGET The amount of GET tokens the user intends to migrate.
     */
    function _migratorCheckGET(uint256 _amountGET) internal {
        // Ensure the caller has a sufficient balance of GET tokens for the migration.
        require(
            liquidGETToken.balanceOf(msg.sender) >= _amountGET,
            "OPNMigration: Insufficient GET balance"
        );

        // Ensure the contract is authorized to spend the specified amount of GET tokens on behalf of the caller.
        require(
            liquidGETToken.allowance(msg.sender, address(this)) >= _amountGET,
            "OPNMigration: GET spend not approved"
        );

        // Transfer the specified amount of GET tokens from the caller to this contract.
        // This step is necessary before the tokens can be burned.
        require(
            liquidGETToken.transferFrom(msg.sender, address(this), _amountGET),
            "OPNMigration: GET transfer failed"
        );

        // Burn the transferred GET tokens as part of the migration process.
        // This action permanently removes the tokens from circulation, marking their migration to OPN tokens.
        _burn(_amountGET);
    }

    /**
     * @dev Checks the user's balance and approval for XGET tokens, transfers them to the contract, redeems them for GET tokens, and then burns the GET tokens.
     * This function is a critical part of the XGET to OPN migration process. It ensures that the user has enough XGET tokens and has granted the contract
     * permission to use them. It then redeems these XGET tokens for GET tokens. The redeemed GET tokens are immediately burned as part of the migration process.
     * @param _amountXGET The amount of XGET tokens the user wants to migrate.
     * @return amountGETRedeemedByXGET_ The amount of GET tokens redeemed from the XGET tokens. This amount is calculated based on the redemption rate defined in the XGET token contract.
     */
    function _migratorCheckXGET(
        uint256 _amountXGET
    ) internal returns (uint256 amountGETRedeemedByXGET_) {
        // Ensure the caller has enough XGET tokens for the migration.
        require(
            stakedGETToken.balanceOf(msg.sender) >= _amountXGET,
            "OPNMigration: Insufficient XGET balance"
        );

        // Ensure the contract is allowed to spend the specified amount of XGET tokens on behalf of the caller.
        require(
            stakedGETToken.allowance(msg.sender, address(this)) >= _amountXGET,
            "OPNMigration: XGET spend not approved"
        );

        // Transfer the specified amount of XGET tokens from the caller to this contract.
        // This step is necessary to redeem the XGET tokens for GET tokens.
        require(
            stakedGETToken.transferFrom(msg.sender, address(this), _amountXGET),
            "OPNMigration: XGET transfer failed"
        );

        // Redeem the transferred XGET tokens for GET tokens.
        // The XGET token contract should define the redemption rate and mechanics.
        amountGETRedeemedByXGET_ = stakedGETToken.redeem(
            _amountXGET,
            address(this),
            address(this)
        );

        // Burn the redeemed GET tokens as part of the migration process (on Ethereum)
        // This step permanently removes the GET tokens from circulation, completing their migration to OPN tokens.

        _burn(amountGETRedeemedByXGET_);

        return amountGETRedeemedByXGET_;
    }

    // Calculates the current stake rate based on the elapsed time since the start of the migration.
    // The stake rate starts at stakeRateInitial and linearly decreases to 0 over the duration durationOfStakeMigrationPeriod.
    // After durationOfStakeMigrationPeriod, the stake rate remains at 0.
    function _returnCurrentStakeRate(
        uint256 _timestamp
    ) internal view returns (uint256 stakeRate_) {
        unchecked {
            // If the current timestamp is before the migration start time, return the initial stake rate.
            // This case might not be possible in practice since the migration wouldn't have started yet,
            // but it's handled here for completeness and to avoid underflow in subtraction below.
            if (_timestamp < startOfMigration) {
                // revert("OPNMigration: migration not started yet");
                return 1e18; // return 100% but inreality should probably revert
            }

            // If the current timestamp is after the end of the stake migration duration, return 0 as the stake rate.
            if (
                _timestamp > startOfMigration + durationOfStakeMigrationPeriod
            ) {
                return 0;
            }

            // Calculate the elapsed time since the start of the migration.
            uint256 elapsedTime_ = _timestamp - startOfMigration;

            // Calculate the remaining duration of the migration.
            uint256 remainingDuration_ = durationOfStakeMigrationPeriod -
                elapsedTime_;

            // Calculate the current stake rate based on the linear decrease over time.
            // This calculation uses the proportion of the remaining duration to the total duration,
            // multiplied by the initial stake rate, to find the current rate.
            stakeRate_ = uint256(
                (stakeRateInitial * remainingDuration_) /
                    durationOfStakeMigrationPeriod
            );

            return stakeRate_;
        }
    }

    /**
     * @dev Calculates the expected returns for migrating liquid GET tokens.
     * This function provides a preview of the migration results for liquid GET tokens without performing the actual migration.
     * It calculates the total OPN tokens to be minted from the GET tokens, the portion of OPN tokens to be staked, and the corresponding amount of XOPN tokens to be allocated to the user.
     * @param _amountGET The amount of GET tokens to be migrated.
     * @return amountOPNToUserForGETMigration_ The net amount of OPN tokens allocated to the user after staking a portion.
     * @return amountOPNStakedForGETMigration_ The amount of OPN tokens to be staked.
     * @return amountXOPNToUserForGETMigration_ The amount of XOPN tokens allocated to the user based on the staked OPN tokens.
     */
    function _checkLiquidMigrationReturn(
        uint256 _amountGET
    )
        internal
        view
        returns (
            uint256 amountOPNToUserForGETMigration_,
            uint256 amountOPNStakedForGETMigration_,
            uint256 amountXOPNToUserForGETMigration_
        )
    {
        // Calculate the total amount of OPN tokens to mint based on the GET to OPN ratio.
        uint256 amountOPNToMintGET_ = _amountGET * GET_TO_OPN_RATIO;

        // Calculate the amount of OPN to stake based on the current stake rate.
        amountOPNStakedForGETMigration_ =
            (amountOPNToMintGET_ * _returnCurrentStakeRate(block.timestamp)) /
            1e18;

        // Calculate the net OPN to allocate to the user after subtracting the staked amount.
        amountOPNToUserForGETMigration_ =
            amountOPNToMintGET_ -
            amountOPNStakedForGETMigration_;

        // Calculate the amount of XOPN tokens to be allocated to the user by depositing the staked OPN tokens in the xOPN contract.
        amountXOPNToUserForGETMigration_ = xOpenToken.previewDeposit(
            amountOPNStakedForGETMigration_
        );

        return (
            amountOPNToUserForGETMigration_,
            amountOPNStakedForGETMigration_,
            amountXOPNToUserForGETMigration_
        );
    }

    /**
     * @dev Calculates the expected returns when migrating staked XGET tokens.
     * This function provides a preview of the migration results for staked XGET tokens without performing the actual migration.
     * It calculates the amount of GET tokens that would be redeemed from the XGET tokens and the corresponding amount of XOPN tokens that would be allocated to the user.
     * @param _amountXGET The amount of XGET tokens to be migrated.
     * @return amountXOPNToUserForXGETMigration_ The amount of XOPN tokens that would be allocated to the user as a result of the migration.
     * @return amountGETRedeemedByXGET_ The amount of GET tokens redeemed from the XGET tokens.
     */
    function _checkStakedXGETMigrateReturns(
        uint256 _amountXGET
    )
        internal
        view
        returns (
            uint256 amountXOPNToUserForXGETMigration_,
            uint256 amountGETRedeemedByXGET_
        )
    {
        // Redeem XGET tokens for GET tokens based on the predefined rate in the stakedGETToken contract.
        amountGETRedeemedByXGET_ = stakedGETToken.previewRedeem(
            _amountXGET,
            address(this)
        );

        // Calculate the amount of OPN tokens to mint based on the redeemed GET tokens and the GET to OPN ratio.
        uint256 amountOPNToMintXGET_ = amountGETRedeemedByXGET_ *
            GET_TO_OPN_RATIO;

        // Calculate the amount of XOPN tokens to be allocated to the user by depositing the minted OPN tokens in the xOPN contract.
        amountXOPNToUserForXGETMigration_ = xOpenToken.previewDeposit(
            amountOPNToMintXGET_
        );

        return (amountXOPNToUserForXGETMigration_, amountGETRedeemedByXGET_);
    }

    function _isMigrationActive() internal view returns (bool) {
        // check the timestamp if it is greater than the start of migration, return bool
        return block.timestamp >= startOfMigration && isMigrationActive;
    }

    // Configuration functions

    /// @inheritdoc IOPNMigration
    function setAddressConfig(
        address _openToken,
        address _xOpenToken,
        address _opnMintManager
    ) external override onlyOwner {
        openToken = IOPNToken(_openToken);
        opnMintManager = IOPNMintManager(_opnMintManager);
        xOpenToken = IMigrationLockedRevenueDistributionToken(_xOpenToken);
        emit OPNTokenSet(_openToken);
        emit XOpenTokenSet(_xOpenToken);
        emit MintManagerSet(_opnMintManager);
    }

    /// @inheritdoc IOPNMigration
    function setStartOfMigration(
        uint256 _startOfMigration
    ) external override onlyOwner {
        startOfMigration = _startOfMigration;
        emit StartOfMigrationSet(_startOfMigration);
    }

    /// @inheritdoc IOPNMigration
    function setEndOfMigration(
        uint256 _endOfMigration
    ) external override onlyOwner {
        endOfMigration = _endOfMigration;
        emit EndOfMigrationSet(_endOfMigration);
    }

    /// @inheritdoc IOPNMigration
    function setStakeRateInitial(
        uint256 _stakeRateInitial
    ) external override onlyOwner {
        stakeRateInitial = _stakeRateInitial;
        emit StakeRateInitialSet(_stakeRateInitial);
    }

    /// @inheritdoc IOPNMigration
    function setDurationOfStakeMigrationPeriod(
        uint256 _durationOfStakeMigrationPeriod
    ) external override onlyOwner {
        durationOfStakeMigrationPeriod = _durationOfStakeMigrationPeriod;
        emit DurationOfStakeMigrationPeriodSet(_durationOfStakeMigrationPeriod);
    }

    /// @inheritdoc IOPNMigration
    function setMigrationActive(bool _setting) external override onlyOwner {
        if (_setting) {
            // check if the contract is fully configured
            // check that xOpenToken is not address(0)
            require(
                address(xOpenToken) != address(0),
                "OPNMigration: xOpenToken not set"
            );

            // check that openToken is not address(0)
            require(
                address(openToken) != address(0),
                "OPNMigration: openToken not set"
            );

            // check that opnMintManager is not address(0)
            require(
                address(opnMintManager) != address(0),
                "OPNMigration: opnMintManager not set"
            );
        }

        isMigrationActive = _setting;

        emit MigrationStatusSet(_setting);
    }

    // View functions

    /// @inheritdoc IOPNMigration
    function totalOPNStakedByTheMigration()
        external
        view
        override
        returns (uint256)
    {
        return totalOPNStakedByGETMigration;
    }

    /// @inheritdoc IOPNMigration
    function totalOPNMinted() external view override returns (uint256) {
        return totalOPNMintedByAllMigration;
    }

    /// @inheritdoc IOPNMigration
    function returnCurrentStakeRate() external view override returns (uint256) {
        return _returnCurrentStakeRate(block.timestamp);
    }

    /// @inheritdoc IOPNMigration
    function returnStakeRateAtTime(
        uint256 _timestamp
    ) external view override returns (uint256) {
        return _returnCurrentStakeRate(_timestamp);
    }

    /// @inheritdoc IOPNMigration
    function totalOPNSupply() external view override returns (uint256) {
        return openToken.totalSupply();
    }

    /// @inheritdoc IOPNMigration
    function totalXOPNSupply() external view override returns (uint256) {
        return xOpenToken.totalSupply();
    }

    /// @inheritdoc IOPNMigration
    function totalGETMigratedInTotal()
        external
        view
        override
        returns (uint256)
    {
        return totalLiquidGETMigrated + totalGETMigratedByXGETMigration;
    }

    /// @inheritdoc IOPNMigration
    function returnTotalAmountGETFromXGETRedemptionMigrated()
        external
        view
        override
        returns (uint256)
    {
        return totalGETMigratedByXGETMigration;
    }

    /// @inheritdoc IOPNMigration
    function totalXGETRedeemedInTotal()
        external
        view
        override
        returns (uint256)
    {
        return totalXGETRedeemed;
    }

    /// @inheritdoc IOPNMigration
    function returnMigrateDualTokenOutput(
        uint256 _amountGET,
        uint256 _amountXGET
    )
        external
        view
        override
        returns (
            uint256 amountOPNToUserForGETMigration_,
            uint256 amountXOPNToUserForXGETMigration_,
            uint256 amountOPNStakedForGETMigration_,
            uint256 amountXOPNToUserForGETMigration_,
            uint256 amountGETRedeemedByXGET_
        )
    {
        if (_amountGET == 0 && _amountXGET == 0) {
            return (0, 0, 0, 0, 0);
        }

        // Check returns of GET token migration.
        if (_amountGET > 0) {
            (
                amountOPNToUserForGETMigration_,
                amountOPNStakedForGETMigration_,
                amountXOPNToUserForGETMigration_
            ) = _checkLiquidMigrationReturn(_amountGET);
        }

        // Handle XGET token migration.
        if (_amountXGET > 0) {
            (
                amountXOPNToUserForXGETMigration_,
                amountGETRedeemedByXGET_
            ) = _checkStakedXGETMigrateReturns(_amountXGET);
        }

        return (
            amountOPNToUserForGETMigration_,
            amountXOPNToUserForXGETMigration_,
            amountOPNStakedForGETMigration_,
            amountXOPNToUserForGETMigration_,
            amountGETRedeemedByXGET_
        );
    }

    /// @inheritdoc IOPNMigration
    function previewDeposit(
        uint256 _assets
    ) external view override returns (uint256) {
        return xOpenToken.previewDeposit(_assets);
    }

    /// @inheritdoc IOPNMigration
    function previewRedeem(
        uint256 _shares
    ) external view override returns (uint256) {
        return xOpenToken.previewRedeem(_shares, address(this));
    }

    /// @inheritdoc IOPNMigration
    function depositRatioOfOPNtoXOPN()
        external
        view
        override
        returns (uint256)
    {
        return xOpenToken.previewDeposit(1e18);
    }
}

File 2 of 8 : IERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.7;

/// @title Interface of the ERC20 standard as defined in the EIP, including EIP-2612 permit functionality.
interface IERC20 {

    /**************/
    /*** Events ***/
    /**************/

    /**
     *  @dev   Emitted when one account has set the allowance of another account over their tokens.
     *  @param owner_   Account that tokens are approved from.
     *  @param spender_ Account that tokens are approved for.
     *  @param amount_  Amount of tokens that have been approved.
     */
    event Approval(address indexed owner_, address indexed spender_, uint256 amount_);

    /**
     *  @dev   Emitted when tokens have moved from one account to another.
     *  @param owner_     Account that tokens have moved from.
     *  @param recipient_ Account that tokens have moved to.
     *  @param amount_    Amount of tokens that have been transferred.
     */
    event Transfer(address indexed owner_, address indexed recipient_, uint256 amount_);

    /**************************/
    /*** External Functions ***/
    /**************************/

    /**
     *  @dev    Function that allows one account to set the allowance of another account over their tokens.
     *          Emits an {Approval} event.
     *  @param  spender_ Account that tokens are approved for.
     *  @param  amount_  Amount of tokens that have been approved.
     *  @return success_ Boolean indicating whether the operation succeeded.
     */
    function approve(address spender_, uint256 amount_) external returns (bool success_);

    /**
     *  @dev    Function that allows one account to decrease the allowance of another account over their tokens.
     *          Emits an {Approval} event.
     *  @param  spender_          Account that tokens are approved for.
     *  @param  subtractedAmount_ Amount to decrease approval by.
     *  @return success_          Boolean indicating whether the operation succeeded.
     */
    function decreaseAllowance(address spender_, uint256 subtractedAmount_) external returns (bool success_);

    /**
     *  @dev    Function that allows one account to increase the allowance of another account over their tokens.
     *          Emits an {Approval} event.
     *  @param  spender_     Account that tokens are approved for.
     *  @param  addedAmount_ Amount to increase approval by.
     *  @return success_     Boolean indicating whether the operation succeeded.
     */
    function increaseAllowance(address spender_, uint256 addedAmount_) external returns (bool success_);

    /**
     *  @dev   Approve by signature.
     *  @param owner_    Owner address that signed the permit.
     *  @param spender_  Spender of the permit.
     *  @param amount_   Permit approval spend limit.
     *  @param deadline_ Deadline after which the permit is invalid.
     *  @param v_        ECDSA signature v component.
     *  @param r_        ECDSA signature r component.
     *  @param s_        ECDSA signature s component.
     */
    function permit(address owner_, address spender_, uint amount_, uint deadline_, uint8 v_, bytes32 r_, bytes32 s_) external;

    /**
     *  @dev    Moves an amount of tokens from `msg.sender` to a specified account.
     *          Emits a {Transfer} event.
     *  @param  recipient_ Account that receives tokens.
     *  @param  amount_    Amount of tokens that are transferred.
     *  @return success_   Boolean indicating whether the operation succeeded.
     */
    function transfer(address recipient_, uint256 amount_) external returns (bool success_);

    /**
     *  @dev    Moves a pre-approved amount of tokens from a sender to a specified account.
     *          Emits a {Transfer} event.
     *          Emits an {Approval} event.
     *  @param  owner_     Account that tokens are moving from.
     *  @param  recipient_ Account that receives tokens.
     *  @param  amount_    Amount of tokens that are transferred.
     *  @return success_   Boolean indicating whether the operation succeeded.
     */
    function transferFrom(address owner_, address recipient_, uint256 amount_) external returns (bool success_);

    /**********************/
    /*** View Functions ***/
    /**********************/

    /**
     *  @dev    Returns the allowance that one account has given another over their tokens.
     *  @param  owner_     Account that tokens are approved from.
     *  @param  spender_   Account that tokens are approved for.
     *  @return allowance_ Allowance that one account has given another over their tokens.
     */
    function allowance(address owner_, address spender_) external view returns (uint256 allowance_);

    /**
     *  @dev    Returns the amount of tokens owned by a given account.
     *  @param  account_ Account that owns the tokens.
     *  @return balance_ Amount of tokens owned by a given account.
     */
    function balanceOf(address account_) external view returns (uint256 balance_);

    /**
     *  @dev    Returns the decimal precision used by the token.
     *  @return decimals_ The decimal precision used by the token.
     */
    function decimals() external view returns (uint8 decimals_);

    /**
     *  @dev    Returns the signature domain separator.
     *  @return domainSeparator_ The signature domain separator.
     */
    function DOMAIN_SEPARATOR() external view returns (bytes32 domainSeparator_);

    /**
     *  @dev    Returns the name of the token.
     *  @return name_ The name of the token.
     */
    function name() external view returns (string memory name_);

    /**
      *  @dev    Returns the nonce for the given owner.
      *  @param  owner_  The address of the owner account.
      *  @return nonce_ The nonce for the given owner.
     */
    function nonces(address owner_) external view returns (uint256 nonce_);

    /**
     *  @dev    Returns the symbol of the token.
     *  @return symbol_ The symbol of the token.
     */
    function symbol() external view returns (string memory symbol_);

    /**
     *  @dev    Returns the total amount of tokens in existence.
     *  @return totalSupply_ The total amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256 totalSupply_);

}

File 3 of 8 : Owned.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnershipTransferred(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

File 4 of 8 : IMigrationLockedRevenueDistributionToken.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

import {IERC20} from "erc20/interfaces/IERC20.sol";

interface IMigrationLockedRevenueDistributionToken is IERC20 {
    function deposit(uint256 assets_, address receiver_) external returns (uint256 shares_);

    function redeem(uint256 shares_, address receiver_, address owner_) external returns (uint256 assets_);

    function previewDeposit(uint256 assets_) external view returns (uint256 shares_);

    function previewRedeem(uint256 shares_, address owner_) external view returns (uint256 assets_);

    function totalAssets() external view returns (uint256 totalManagedAssets_);
}

File 5 of 8 : IGETToken.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

import {IERC20} from "erc20/interfaces/IERC20.sol";

interface IGETToken is IERC20 {
    function burn(uint256 amount) external;
}

File 6 of 8 : IOPNToken.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

import {IERC20} from "erc20/interfaces/IERC20.sol";

interface IOPNToken is IERC20 {
    /// @notice Mint function only callable by the DAO
    /// @dev this function will be only callable by a DAO governance contract that can only execute functions like these after a majority vote (with quorum) has been reached
    /// @param _to Address to which tokens will be minted.
    /// @param _amount Amount of tokens to mint
    function mintTokensByDAO(address _to, uint256 _amount) external;

    /// @notice Issues tokens during the migration process.
    /// @dev This function will be only callable by a migration manager contract(burning GET and minting OPN) that will be responsible for minting tokens during the migration process. After the migration the DAO can revoke the minting rights of the migration manager.
    /// @param _to Address to which tokens will be minted.
    /// @param _amount Amount of tokens to mint.
    function issueTokensMigration(address _to, uint256 _amount) external;

    /// @notice Mints tokens for Polygon inventory.
    /// @dev As to allow GET to be migrated on Polygon this function will be used to mint a certain amount of tokens to the Polygon inventory. This is not inflationary as the tokens are already minted on Ethereum and are just being moved to Polygon.
    /// @param _to Address to which tokens will be minted.
    /// @param _amount Amount of tokens to mint.
    function mintTokenPolygonInventory(address _to, uint256 _amount) external;

    /// @notice Allows token holders to burn their tokens.
    /// @param _amount Amount of tokens to burn.
    function burn(uint256 _amount) external;

    /// @notice Finalizes the migration process
    /// @dev this function disables the migration minting and revokes the minting rights of the migration manager. This function can only be called by the DAO.
    function finalizeMigration() external;

    /// @notice Sets a new DAO controller address
    /// @param _newDaoController The address of the new DAO controller.
    function setDAOControllerAddress(address _newDaoController) external;

    /// @notice Sets a new mint manager address
    /// @param _newMigrationManager The address of the new mint manager.
    function setMintManager(address _newMigrationManager) external;

    // View functions

    /// @notice Returns the address of the mint manager.
    /// @return address of the mint manager.
    function mintManagerAddress() external view returns (address);

    /// @notice Returns the address of the DAO controller.
    /// @return address of the DAO controller.
    function daoControllerAddress() external view returns (address);

    /// @notice Returns whether the migration issuance is disabled permanently
    function migrationIssuanceDisabledPermanently()
        external
        view
        returns (bool);

    // Events

    event TokensBurned(address indexed from, uint256 amount);

    event MigrationInventoryMint(address indexed to, uint256 amount);

    event MigrationManagerSet(address indexed newMigrationManager);

    event MigrationMint(address indexed to, uint256 amount);

    event DaoMint(address indexed to, uint256 amount);

    event DaoControllerSet(address _newDaoController);

    event MigrationConfigFinalized();
}

File 7 of 8 : IOPNMintManager.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

interface IOPNMintManager {
    // Events

    event MigrationMint(address indexed to, uint256 amount);

    event DaoMint(address indexed to, uint256 amount);

    event MigrationContractSet(address migrationContract);

    event DAOContractAddressSet(address daoContractAddress);

    event MintManagerSetInToken(address _newMigrationManager);

    // Functions

    function opnTokenAddress() external view returns (address);

    function issueTokensMigration(address _to, uint256 _amount) external;

    function mintTokenPolygonInventory(address _to, uint256 _amount) external;

    function setDaoContractAddress(address _daoContractAddress) external;

    function setMintManangerInToken(address _newMigrationManager) external;

    function withdrawOPN() external;

    function setMigrationContract(address _migrationContract) external;

    function withdrawTokens(address _tokenAddress, uint256 _amount) external;
}

File 8 of 8 : IOPNMigration.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

interface IOPNMigration {
    // Events
    event MintManagerSet(address indexed opnMintManager);

    event AdminSet(address indexed admin, bool setting);

    event XOpenTokenSet(address indexed xOpenToken);

    event OPNTokenSet(address indexed openToken);

    event MigrationStatusSet(bool setting);

    // The amount of GET tokens the user has migrated to OPN.
    // The amount of XGET tokens the user has migrated to XOPN.
    // The amount of OPN tokens allocated to the user after the migration of liquid GET tokens.
    // The amount of XOPN tokens sent to the user after the migration of XGET tokens (note this is not just x1000 the xGET tokens, because xGET redemption gives a certain amount of GET that varies over time, also the amount of XOPN also depends on if people do immediate withdraws in that contract)
    // The amount of OPN tokens staked during the migration of liquid GET tokens.
    // If the user migrates xGET then in the migratiion the contract has redeemed the XGET for GET, this value is the amount of GET  that was received, migrated and staked
    // amount of OPN that was minted (and then staked) in the migration of XGET, this is baically x1000 of the previous value
    event OPNMigrationComplete( // The address of the user who initiated the migration process.
        address indexed user,
        uint256 amountGET,
        uint256 amountXGET,
        uint256 amountOPNToUserForGETMigration,
        uint256 amountXOPNToUserForGETMigration,
        uint256 amountXOPNToUserForXGETMigration,
        uint256 amountOPNStakedForGETMigration,
        uint256 amountGETRedeemedByXGET,
        uint256 amountOPNMintedForXGETMigration
    );

    event StartOfMigrationSet(uint256 startOfMigration);

    event EndOfMigrationSet(uint256 endOfMigration);

    event StakeRateInitialSet(uint256 stakeRateInitial);

    event DurationOfStakeMigrationPeriodSet(uint256 durationOfStakeMigrationPeriod);

    // View functions

    /**
     * @notice Returns the total amount of GET tokens redeemed from XGET tokens during the migration process.
     * @dev This function provides a view into the total effectiveness and participation in the migration process, specifically focusing on the XGET to GET redemption aspect. It allows external entities to query the total amount of GET tokens that have been successfully redeemed from XGET tokens, offering insights into the volume of tokens processed in this part of the migration.
     * @return The total amount of GET tokens that have been redeemed from XGET tokens as part of the migration process. This includes all GET tokens obtained through the redemption of XGET tokens, across all participants in the migration.
     */
    function returnTotalAmountGETFromXGETRedemptionMigrated() external view returns (uint256);

    /**
     * @notice Calculates the total amount of OPN tokens that have been satked as a result of the migration.
     * @return totalOPNStaked_ The total amount of OPN tokens staked during the migration process.
     */
    function totalOPNStakedByTheMigration() external view returns (uint256 totalOPNStaked_);

    /**
     * @notice Provides the total amount of OPN tokens that have been minted during the migration process.
     * @return totalOPNMinted_ The total number of OPN tokens minted as a result of migration.
     */
    function totalOPNMinted() external view returns (uint256 totalOPNMinted_);

    /**
     * @notice Returns the current stake rate applied to tokens during the migration.
     * @return stakeRate_ The current stake rate, scaled by 1e18 for precision.
     */
    function returnCurrentStakeRate() external view returns (uint256 stakeRate_);

    /**
     * @notice Returns the stake rate at a specific timestamp during the migration process.
     * @param _timestamp The Unix timestamp for which the stake rate is requested.
     * @return stakeRate_ The stake rate at the specified timestamp, scaled by 1e18 for precision.
     */
    function returnStakeRateAtTime(uint256 _timestamp) external view returns (uint256 stakeRate_);

    /**
     * @notice Fetches the total supply of OPN tokens.
     * @return totalSupply_ The total supply of OPN tokens.
     */
    function totalOPNSupply() external view returns (uint256 totalSupply_);

    /**
     * @notice Retrieves the total supply of XOPN tokens.
     * @return totalSupply_ The total supply of XOPN tokens.
     */
    function totalXOPNSupply() external view returns (uint256 totalSupply_);

    /**
     * @notice Calculates the total amount of GET tokens that have been migrated to OPN.
     * @return totalGETMigrated_ The total amount of GET tokens migrated to OPN.
     */
    function totalGETMigratedInTotal() external view returns (uint256 totalGETMigrated_);

    /**
     * @notice Provides the total amount of XGET tokens that have been redeemed as part of the migration process.
     * @return totalXGETRedeemed_ The total number of XGET tokens redeemed during the migration process.
     */
    function totalXGETRedeemedInTotal() external view returns (uint256 totalXGETRedeemed_);

    function depositRatioOfOPNtoXOPN() external view returns (uint256);

    function previewRedeem(uint256 _shares) external view returns (uint256);

    function previewDeposit(uint256 _assets) external view returns (uint256);

    /**
     * @notice Calculates and returns the expected outputs for a dual token migration given specific amounts of GET and XGET tokens.
     * @dev This function provides a preview of the migration results without actually performing the migration. It's useful for users to understand the benefits of migrating their tokens.
     * @param _amountGET The amount of GET tokens the user intends to migrate.
     * @param _amountXGET The amount of XGET tokens the user intends to redeem and migrate.
     * @return amountOPNToUserForGETMigration_ The amount of OPN tokens the user will receive for the migration of GET tokens.
     * @return amountXOPNToUserForXGETMigration_ The amount of XOPN tokens the user will receive for the redemption and migration of XGET tokens.
     * @return amountOPNStakedForGETMigration_ The amount of OPN tokens that will be staked as a result of GET token migration.
     * @return amountXOPNToUserForGETMigration_ The amount of XOPN tokens allocated to the user as a result of GET token migration. This appears to be a duplicate or incorrectly named return value based on the provided context and might need correction.
     * @return amountGETRedeemedByXGET_ The amount of GET tokens redeemed from the XGET tokens provided.
     */
    function returnMigrateDualTokenOutput(uint256 _amountGET, uint256 _amountXGET)
        external
        view
        returns (
            uint256 amountOPNToUserForGETMigration_,
            uint256 amountXOPNToUserForXGETMigration_,
            uint256 amountOPNStakedForGETMigration_,
            uint256 amountXOPNToUserForGETMigration_,
            uint256 amountGETRedeemedByXGET_
        );

    /**
     * @notice Migrates specified amounts of GET and XGET tokens to OPN and XOPN tokens, respectively.
     * @dev This function performs the actual migration of tokens. It should handle the redemption of XGET tokens for GET, the conversion of GET to OPN, and the allocation of OPN and XOPN tokens to the user. Ensure proper security measures, such as reentrancy guards, are in place.
     * @param _amountGET The amount of GET tokens the user wishes to migrate.
     * @param _amountXGET The amount of XGET tokens the user wishes to redeem and migrate.
     * @return amountOPNToUserForGETMigration_ The amount of OPN tokens allocated to the user for the migration of GET tokens.
     * @return amountXOPNToUserForXGETMigration_ The amount of XOPN tokens allocated to the user for the redemption and migration of XGET tokens.
     * @return amountOPNStakedForGETMigration_ The amount of OPN tokens staked as a result of the migration of GET tokens.
     * @return amountXOPNToUserForGETMigration_ The amount of XOPN tokens allocated to the user as a result of GET token migration. This appears to be a duplicate or incorrectly named return value based on the provided context and might need correction.
     * @return amountGETRedeemedByXGET_ The total amount of GET tokens redeemed from the XGET tokens provided.
     */
    function migrateDualTokens(uint256 _amountGET, uint256 _amountXGET)
        external
        returns (
            uint256 amountOPNToUserForGETMigration_,
            uint256 amountXOPNToUserForXGETMigration_,
            uint256 amountOPNStakedForGETMigration_,
            uint256 amountXOPNToUserForGETMigration_,
            uint256 amountGETRedeemedByXGET_
        );

    /**
     * @notice Configures the addresses for the OPN token, xOPN token, and OPN Mint Manager contracts.
     * @dev This function is intended for administrative use to set up or update the contract addresses involved in the migration process. It allows for the configuration of the main OPN token address, the xOPN token address, and the OPN Mint Manager address in a single transaction.
     * @param _openToken The address of the OPN token contract. This token represents the primary asset being migrated.
     * @param _xOpenToken The address of the xOPN token contract. This token represents a secondary or derivative asset involved in the migration.
     * @param _opnMintManager The address of the OPN Mint Manager contract. This contract is responsible for managing the minting of OPN tokens during the migration process.
     */
    function setAddressConfig(address _openToken, address _xOpenToken, address _opnMintManager) external;

    /**
     * @notice Activates or deactivates the migration process.
     * @dev Only callable by the admin. Controls whether the migration is allowed to proceed.
     * @param _setting A boolean value to activate (`true`) or deactivate (`false`) the migration.
     */
    function setMigrationActive(bool _setting) external;

    function setStartOfMigration(uint256 _startOfMigration) external;

    function setEndOfMigration(uint256 _endOfMigration) external;

    function setStakeRateInitial(uint256 _stakeRateInitial) external;

    function setDurationOfStakeMigrationPeriod(uint256 _durationOfStakeMigrationPeriod) external;
}

Settings
{
  "remappings": [
    "@solmate/src/=lib/solmate/src/",
    "forge-std/=lib/forge-std/src/",
    "contract-test-utils/=lib/erc20-helper/lib/contract-test-utils/contracts/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc20-helper/=lib/erc20-helper/src/",
    "erc20/=lib/erc20/contracts/",
    "revenue-distribution-token/=lib/revenue-distribution-token/contracts/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_initialOwner","type":"address"},{"internalType":"address","name":"_liquidGETAddress","type":"address"},{"internalType":"address","name":"_stakedGETAddress","type":"address"},{"internalType":"uint256","name":"_startOfMigration","type":"uint256"},{"internalType":"uint256","name":"_startStakeRate","type":"uint256"},{"internalType":"uint256","name":"_durationOfStakeMigrationPeriod","type":"uint256"},{"internalType":"address","name":"_bridgeMigrationAddress","type":"address"},{"internalType":"uint256","name":"_chainId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bool","name":"setting","type":"bool"}],"name":"AdminSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"durationOfStakeMigrationPeriod","type":"uint256"}],"name":"DurationOfStakeMigrationPeriodSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"endOfMigration","type":"uint256"}],"name":"EndOfMigrationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"setting","type":"bool"}],"name":"MigrationStatusSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"opnMintManager","type":"address"}],"name":"MintManagerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountGET","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountXGET","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOPNToUserForGETMigration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountXOPNToUserForGETMigration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountXOPNToUserForXGETMigration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOPNStakedForGETMigration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountGETRedeemedByXGET","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOPNMintedForXGETMigration","type":"uint256"}],"name":"OPNMigrationComplete","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"openToken","type":"address"}],"name":"OPNTokenSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"stakeRateInitial","type":"uint256"}],"name":"StakeRateInitialSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"startOfMigration","type":"uint256"}],"name":"StartOfMigrationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"xOpenToken","type":"address"}],"name":"XOpenTokenSet","type":"event"},{"inputs":[],"name":"GET_TO_OPN_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIGRATION_AVAILABLE_UNTIL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositRatioOfOPNtoXOPN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"durationOfStakeMigrationPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endOfMigration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMigrationActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidGETToken","outputs":[{"internalType":"contract IGETToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountGET","type":"uint256"},{"internalType":"uint256","name":"_amountXGET","type":"uint256"}],"name":"migrateDualTokens","outputs":[{"internalType":"uint256","name":"amountOPNToUserForGETMigration_","type":"uint256"},{"internalType":"uint256","name":"amountXOPNToUserForXGETMigration_","type":"uint256"},{"internalType":"uint256","name":"amountOPNStakedForGETMigration_","type":"uint256"},{"internalType":"uint256","name":"amountXOPNToUserForGETMigration_","type":"uint256"},{"internalType":"uint256","name":"amountGETRedeemedByXGET_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrationDestinationAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openToken","outputs":[{"internalType":"contract IOPNToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"opnMintManager","outputs":[{"internalType":"contract IOPNMintManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"returnCurrentStakeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountGET","type":"uint256"},{"internalType":"uint256","name":"_amountXGET","type":"uint256"}],"name":"returnMigrateDualTokenOutput","outputs":[{"internalType":"uint256","name":"amountOPNToUserForGETMigration_","type":"uint256"},{"internalType":"uint256","name":"amountXOPNToUserForXGETMigration_","type":"uint256"},{"internalType":"uint256","name":"amountOPNStakedForGETMigration_","type":"uint256"},{"internalType":"uint256","name":"amountXOPNToUserForGETMigration_","type":"uint256"},{"internalType":"uint256","name":"amountGETRedeemedByXGET_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"returnStakeRateAtTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"returnTotalAmountGETFromXGETRedemptionMigrated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_openToken","type":"address"},{"internalType":"address","name":"_xOpenToken","type":"address"},{"internalType":"address","name":"_opnMintManager","type":"address"}],"name":"setAddressConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_durationOfStakeMigrationPeriod","type":"uint256"}],"name":"setDurationOfStakeMigrationPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_endOfMigration","type":"uint256"}],"name":"setEndOfMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_setting","type":"bool"}],"name":"setMigrationActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakeRateInitial","type":"uint256"}],"name":"setStakeRateInitial","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startOfMigration","type":"uint256"}],"name":"setStartOfMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeRateInitial","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakedGETToken","outputs":[{"internalType":"contract IMigrationLockedRevenueDistributionToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startOfMigration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalGETMigratedByXGETMigration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalGETMigratedInTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalLiquidGETMigrated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalOPNMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalOPNMintedByAllMigration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalOPNStakedByGETMigration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalOPNStakedByTheMigration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalOPNSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalXGETRedeemed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalXGETRedeemedInTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalXOPNSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"xOpenToken","outputs":[{"internalType":"contract IMigrationLockedRevenueDistributionToken","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

6101006040526009805460ff191690556001600a553480156200002157600080fd5b506040516200229038038062002290833981016040819052620000449162000222565b600080546001600160a01b0319166001600160a01b038a1690811782556040518a92907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600160601b0319606088811b821660a05287901b1660c052428511620001225760405162461bcd60e51b815260206004820152603660248201527f4f504e4d6967726174696f6e3a205374617274206f66206d6967726174696f6e60448201527f206d75737420626520696e20746865206675747572650000000000000000000060648201526084015b60405180910390fd5b600c85905562000137630317040086620002a6565b600d55600e84905563031704008310620001e05760405162461bcd60e51b815260206004820152605d60248201527f4f504e4d6967726174696f6e3a204475726174696f6e206f66207374616b652060448201527f6d6967726174696f6e20706572696f64206d757374206265206c65737320746860648201527f616e2074686520746f74616c206d6967726174696f6e20706572696f64000000608482015260a40162000119565b600b9290925560601b6001600160601b03191660e05260805250620002cd9350505050565b80516001600160a01b03811681146200021d57600080fd5b919050565b600080600080600080600080610100898b0312156200024057600080fd5b6200024b8962000205565b97506200025b60208a0162000205565b96506200026b60408a0162000205565b9550606089015194506080890151935060a089015192506200029060c08a0162000205565b915060e089015190509295985092959890939650565b60008219821115620002c857634e487b7160e01b600052601160045260246000fd5b500190565b60805160a05160601c60c05160601c60e05160601c611f2c620003646000396000818161028d0152611bff0152600081816103b001528181610ed9015281816117bb015281816118b0015281816119b00152611aae0152600081816104f3015281816114b9015281816115b5015281816116b301528181611b810152611c2e0152600081816104210152611b440152611f2c6000f3fe608060405234801561001057600080fd5b50600436106102535760003560e01c8063950bac2511610146578063c3aaeb26116100c3578063de53b73b11610087578063de53b73b146104d3578063ef8b30f7146104db578063f28d79ae146104ee578063f2fde38b14610515578063f5f4f20914610528578063fcc7419e1461053b57600080fd5b8063c3aaeb2614610493578063c6e0c0951461049b578063cdcf354d146104ae578063d67ff684146104c1578063d9ee8f6c146104ca57600080fd5b8063b31a42961161010a578063b31a429614610454578063b98b874a1461045c578063bcaf3aed1461046f578063bd2ecccb14610477578063bdf812301461048057600080fd5b8063950bac251461040a57806398295d8f146104135780639a8a05921461041c5780639fb217ef14610443578063a2dd9b6d1461044b57600080fd5b80634d6d9c5a116101d457806358814e621161019857806358814e62146103d25780636a28da74146103db578063718adb67146103e65780637c629cd0146103ef5780638da5cb5b146103f757600080fd5b80634d6d9c5a146103425780634e4b48e4146103555780634e9b83091461039057806352ed3abf146103a3578063543e32b7146103ab57600080fd5b80631c8d55471161021b5780631c8d5547146102f5578063279374a71461030a578063323aee8c146103135780633b2438b3146103265780634cdad5061461032f57600080fd5b8063046de85c146102585780630a5db1f5146102885780630bd87d99146102af5780630e913a6c146102c257806316417e08146102df575b600080fd5b60035461026b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61026b7f000000000000000000000000000000000000000000000000000000000000000081565b60025461026b906001600160a01b031681565b6009546102cf9060ff1681565b604051901515815260200161027f565b6102e7610543565b60405190815260200161027f565b610308610303366004611dd2565b6105c5565b005b6102e76103e881565b610308610321366004611dd2565b610634565b6102e760055481565b6102e761033d366004611dd2565b610693565b60015461026b906001600160a01b031681565b610368610363366004611e04565b61071d565b604080519586526020860194909452928401919091526060830152608082015260a00161027f565b61030861039e366004611dd2565b61077e565b6008546102e7565b61026b7f000000000000000000000000000000000000000000000000000000000000000081565b6102e760075481565b6102e7630317040081565b6102e7600c5481565b6006546102e7565b60005461026b906001600160a01b031681565b6102e760085481565b6102e7600b5481565b6102e77f000000000000000000000000000000000000000000000000000000000000000081565b6102e76107dd565b6102e760045481565b6102e76107e8565b61030861046a366004611dd2565b61082d565b6102e761088c565b6102e7600d5481565b61036861048e366004611e04565b6108d8565b6007546102e7565b6102e76104a9366004611dd2565b610aa1565b6103086104bc366004611d98565b610aac565b6102e760065481565b6102e7600e5481565b6005546102e7565b6102e76104e9366004611dd2565b610c31565b61026b7f000000000000000000000000000000000000000000000000000000000000000081565b610308610523366004611d33565b610c63565b610308610536366004611d55565b610cd8565b6102e7610dd3565b600354604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561058857600080fd5b505afa15801561059c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c09190611deb565b905090565b6000546001600160a01b031633146105f85760405162461bcd60e51b81526004016105ef90611e26565b60405180910390fd5b600d8190556040518181527f5517641de6b1335ddec71aaf252d22e25d01ae550bcf03dd1ab70dabff0294f7906020015b60405180910390a150565b6000546001600160a01b0316331461065e5760405162461bcd60e51b81526004016105ef90611e26565b600c8190556040518181527ff4f54bb8afdc04056006553a910fa184a1d469c12864eb3de384ab3dac268ec190602001610629565b600354604051631daea44360e01b8152600481018390523060248201526000916001600160a01b031690631daea443906044015b60206040518083038186803b1580156106df57600080fd5b505afa1580156106f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107179190611deb565b92915050565b6000808080808615801561072f575085155b1561074857506000935083925082915081905080610774565b861561075f5761075787610de5565b919650935091505b85156107745761076e86610eb0565b90945090505b9295509295909350565b6000546001600160a01b031633146107a85760405162461bcd60e51b81526004016105ef90611e26565b600e8190556040518181527f1b16f45e5bd5075a6a5e2a7275e8c255c9e3014fcd8253db388ed1642d1d805c90602001610629565b60006105c042610fe8565b600154604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561058857600080fd5b6000546001600160a01b031633146108575760405162461bcd60e51b81526004016105ef90611e26565b600b8190556040518181527fc310b2723151a0987892fe797393cd15ec5818c029b31f4338c1a5d9cf31265390602001610629565b60035460405163ef8b30f760e01b8152670de0b6b3a764000060048201526000916001600160a01b03169063ef8b30f79060240160206040518083038186803b15801561058857600080fd5b6000806000806000600a546001146109325760405162461bcd60e51b815260206004820152601c60248201527f4f504e4d6967726174696f6e3a205265656e7472616e742063616c6c0000000060448201526064016105ef565b6002600a5561093f611043565b6109965760405162461bcd60e51b815260206004820152602260248201527f4f504e4d6967726174696f6e3a204d6967726174696f6e206e6f742061637469604482015261766560f01b60648201526084016105ef565b60008711806109a55750600086115b6109f15760405162461bcd60e51b815260206004820181905260248201527f4f504e4d6967726174696f6e3a20426f746820616d6f756e747320617265203060448201526064016105ef565b8615610a0857610a008761105c565b919650935091505b8515610a1d57610a17866112ef565b90945090505b337f091004830132191e9dd7c86b4adefaaf7098de15f0de21434079b8cfde672b8088888886898988610a526103e882611e86565b604080519889526020890197909752958701949094526060860192909252608085015260a084015260c083015260e08201526101000160405180910390a26001600a5593969295509093509190565b600061071782610fe8565b6000546001600160a01b03163314610ad65760405162461bcd60e51b81526004016105ef90611e26565b8015610bf0576003546001600160a01b0316610b345760405162461bcd60e51b815260206004820181905260248201527f4f504e4d6967726174696f6e3a20784f70656e546f6b656e206e6f742073657460448201526064016105ef565b6001546001600160a01b0316610b8c5760405162461bcd60e51b815260206004820152601f60248201527f4f504e4d6967726174696f6e3a206f70656e546f6b656e206e6f74207365740060448201526064016105ef565b6002546001600160a01b0316610bf05760405162461bcd60e51b8152602060048201526024808201527f4f504e4d6967726174696f6e3a206f706e4d696e744d616e61676572206e6f74604482015263081cd95d60e21b60648201526084016105ef565b6009805460ff19168215159081179091556040519081527f8b9a2b3d88eb6afe031f6906dff44d741e3e147f55c1d93fb1ed30492e7a488490602001610629565b60035460405163ef8b30f760e01b8152600481018390526000916001600160a01b03169063ef8b30f7906024016106c7565b6000546001600160a01b03163314610c8d5760405162461bcd60e51b81526004016105ef90611e26565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b6000546001600160a01b03163314610d025760405162461bcd60e51b81526004016105ef90611e26565b600180546001600160a01b038086166001600160a01b031992831681179093556002805485831690841617905560038054918616919092161790556040517f2bead221d9ba47e926f473e6182be9c42681573e4fb7645b3df3bd2731a76fde90600090a26040516001600160a01b038316907fc05033ac9e8b990f526abfb217536f2a6acef89e9d17ac22c793d72fb1b7209190600090a26040516001600160a01b038216907f1d5842357c4a776fb6862c5c2e200a5298bf9273363ee80b93672a76a12ae7ec90600090a2505050565b60006006546004546105c09190611e4c565b6000808080610df66103e886611e86565b9050670de0b6b3a7640000610e0a42610fe8565b610e149083611e86565b610e1e9190611e64565b9250610e2a8382611ea5565b60035460405163ef8b30f760e01b8152600481018690529195506001600160a01b03169063ef8b30f79060240160206040518083038186803b158015610e6f57600080fd5b505afa158015610e83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea79190611deb565b93959294505050565b604051631daea44360e01b81526004810182905230602482015260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631daea4439060440160206040518083038186803b158015610f1b57600080fd5b505afa158015610f2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f539190611deb565b90506000610f636103e883611e86565b60035460405163ef8b30f760e01b8152600481018390529192506001600160a01b03169063ef8b30f79060240160206040518083038186803b158015610fa857600080fd5b505afa158015610fbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe09190611deb565b925050915091565b6000600c548210156110035750670de0b6b3a7640000919050565b600b54600c540182111561101957506000919050565b600c54600b54600e5491840391828203919082028161103a5761103a611ed2565b04949350505050565b6000600c5442101580156105c057505060095460ff1690565b600080600061106a846114a2565b836004600082825461107c9190611e4c565b90915550600090506110906103e886611e86565b905080600860008282546110a49190611e4c565b90915550600090506110b542610fe8565b9050806110cc578194506000925060009350611282565b670de0b6b3a76400006110df8284611e86565b6110e99190611e64565b93506110f58483611ea5565b945083600760008282546111099190611e4c565b90915550506002546040516329a4f43160e01b8152306004820152602481018690526001600160a01b03909116906329a4f43190604401600060405180830381600087803b15801561115a57600080fd5b505af115801561116e573d6000803e3d6000fd5b505060015460035460405163095ea7b360e01b81526001600160a01b039182166004820152602481018990529116925063095ea7b39150604401602060405180830381600087803b1580156111c257600080fd5b505af11580156111d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fa9190611db5565b50600354604051636e553f6560e01b8152600481018690523360248201526001600160a01b0390911690636e553f6590604401602060405180830381600087803b15801561124757600080fd5b505af115801561125b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127f9190611deb565b92505b6002546040516329a4f43160e01b8152336004820152602481018790526001600160a01b03909116906329a4f43190604401600060405180830381600087803b1580156112ce57600080fd5b505af11580156112e2573d6000803e3d6000fd5b5050505050509193909250565b6000806112fb83611799565b9050826005600082825461130f9190611e4c565b9250508190555080600660008282546113289190611e4c565b909155506000905061133c6103e883611e86565b905080600860008282546113509190611e4c565b90915550506002546040516329a4f43160e01b8152306004820152602481018390526001600160a01b03909116906329a4f43190604401600060405180830381600087803b1580156113a157600080fd5b505af11580156113b5573d6000803e3d6000fd5b505060015460035460405163095ea7b360e01b81526001600160a01b039182166004820152602481018690529116925063095ea7b39150604401602060405180830381600087803b15801561140957600080fd5b505af115801561141d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114419190611db5565b50600354604051636e553f6560e01b8152600481018390523360248201526001600160a01b0390911690636e553f6590604401602060405180830381600087803b15801561148e57600080fd5b505af1158015610fbc573d6000803e3d6000fd5b6040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561150357600080fd5b505afa158015611517573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061153b9190611deb565b10156115985760405162461bcd60e51b815260206004820152602660248201527f4f504e4d6967726174696f6e3a20496e73756666696369656e74204745542062604482015265616c616e636560d01b60648201526084016105ef565b604051636eb1769f60e11b815233600482015230602482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063dd62ed3e9060440160206040518083038186803b1580156115ff57600080fd5b505afa158015611613573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116379190611deb565b10156116915760405162461bcd60e51b8152602060048201526024808201527f4f504e4d6967726174696f6e3a20474554207370656e64206e6f7420617070726044820152631bdd995960e21b60648201526084016105ef565b6040516323b872dd60e01b8152336004820152306024820152604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156116ff57600080fd5b505af1158015611713573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117379190611db5565b61178d5760405162461bcd60e51b815260206004820152602160248201527f4f504e4d6967726174696f6e3a20474554207472616e73666572206661696c656044820152601960fa1b60648201526084016105ef565b61179681611b42565b50565b6040516370a0823160e01b815233600482015260009082906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b1580156117fd57600080fd5b505afa158015611811573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118359190611deb565b10156118935760405162461bcd60e51b815260206004820152602760248201527f4f504e4d6967726174696f6e3a20496e73756666696369656e7420584745542060448201526662616c616e636560c81b60648201526084016105ef565b604051636eb1769f60e11b815233600482015230602482015282907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063dd62ed3e9060440160206040518083038186803b1580156118fa57600080fd5b505afa15801561190e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119329190611deb565b101561198e5760405162461bcd60e51b815260206004820152602560248201527f4f504e4d6967726174696f6e3a2058474554207370656e64206e6f74206170706044820152641c9bdd995960da1b60648201526084016105ef565b6040516323b872dd60e01b8152336004820152306024820152604481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156119fc57600080fd5b505af1158015611a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a349190611db5565b611a8b5760405162461bcd60e51b815260206004820152602260248201527f4f504e4d6967726174696f6e3a2058474554207472616e73666572206661696c604482015261195960f21b60648201526084016105ef565b604051635d043b2960e11b815260048101839052306024820181905260448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ba08765290606401602060405180830381600087803b158015611afa57600080fd5b505af1158015611b0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b329190611deb565b9050611b3d81611b42565b919050565b7f000000000000000000000000000000000000000000000000000000000000000060011415611be857604051630852cd8d60e31b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342966c6890602401600060405180830381600087803b158015611bcd57600080fd5b505af1158015611be1573d6000803e3d6000fd5b5050505050565b60405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b158015611c7257600080fd5b505af1158015611c86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611caa9190611db5565b6117965760405162461bcd60e51b815260206004820152603a60248201527f4f504e4d6967726174696f6e3a20474554207472616e7366657220746f206d6960448201527f67726174696f6e2064657374696e6174696f6e206661696c656400000000000060648201526084016105ef565b80356001600160a01b0381168114611b3d57600080fd5b600060208284031215611d4557600080fd5b611d4e82611d1c565b9392505050565b600080600060608486031215611d6a57600080fd5b611d7384611d1c565b9250611d8160208501611d1c565b9150611d8f60408501611d1c565b90509250925092565b600060208284031215611daa57600080fd5b8135611d4e81611ee8565b600060208284031215611dc757600080fd5b8151611d4e81611ee8565b600060208284031215611de457600080fd5b5035919050565b600060208284031215611dfd57600080fd5b5051919050565b60008060408385031215611e1757600080fd5b50508035926020909101359150565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b60008219821115611e5f57611e5f611ebc565b500190565b600082611e8157634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615611ea057611ea0611ebc565b500290565b600082821015611eb757611eb7611ebc565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b801515811461179657600080fdfea264697066735822122016d8044825341a2d7bafa8e6cc3095e293a3e75ae6586bc693372d88ce35656b64736f6c63430008070033000000000000000000000000f7a171c168a35ae858fd18bec5bb7c28134b823f0000000000000000000000008a854288a5976036a725879164ca3e91d30c6a1b0000000000000000000000003e49e9c890cd5b015a18ed76e7a4093f569f1a040000000000000000000000000000000000000000000000000000000066068a1800000000000000000000000000000000000000000000000006f05b59d3b200000000000000000000000000000000000000000000000000000000000000278d00000000000000000000000000f7a171c168a35ae858fd18bec5bb7c28134b823f0000000000000000000000000000000000000000000000000000000000000001

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102535760003560e01c8063950bac2511610146578063c3aaeb26116100c3578063de53b73b11610087578063de53b73b146104d3578063ef8b30f7146104db578063f28d79ae146104ee578063f2fde38b14610515578063f5f4f20914610528578063fcc7419e1461053b57600080fd5b8063c3aaeb2614610493578063c6e0c0951461049b578063cdcf354d146104ae578063d67ff684146104c1578063d9ee8f6c146104ca57600080fd5b8063b31a42961161010a578063b31a429614610454578063b98b874a1461045c578063bcaf3aed1461046f578063bd2ecccb14610477578063bdf812301461048057600080fd5b8063950bac251461040a57806398295d8f146104135780639a8a05921461041c5780639fb217ef14610443578063a2dd9b6d1461044b57600080fd5b80634d6d9c5a116101d457806358814e621161019857806358814e62146103d25780636a28da74146103db578063718adb67146103e65780637c629cd0146103ef5780638da5cb5b146103f757600080fd5b80634d6d9c5a146103425780634e4b48e4146103555780634e9b83091461039057806352ed3abf146103a3578063543e32b7146103ab57600080fd5b80631c8d55471161021b5780631c8d5547146102f5578063279374a71461030a578063323aee8c146103135780633b2438b3146103265780634cdad5061461032f57600080fd5b8063046de85c146102585780630a5db1f5146102885780630bd87d99146102af5780630e913a6c146102c257806316417e08146102df575b600080fd5b60035461026b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61026b7f000000000000000000000000f7a171c168a35ae858fd18bec5bb7c28134b823f81565b60025461026b906001600160a01b031681565b6009546102cf9060ff1681565b604051901515815260200161027f565b6102e7610543565b60405190815260200161027f565b610308610303366004611dd2565b6105c5565b005b6102e76103e881565b610308610321366004611dd2565b610634565b6102e760055481565b6102e761033d366004611dd2565b610693565b60015461026b906001600160a01b031681565b610368610363366004611e04565b61071d565b604080519586526020860194909452928401919091526060830152608082015260a00161027f565b61030861039e366004611dd2565b61077e565b6008546102e7565b61026b7f0000000000000000000000003e49e9c890cd5b015a18ed76e7a4093f569f1a0481565b6102e760075481565b6102e7630317040081565b6102e7600c5481565b6006546102e7565b60005461026b906001600160a01b031681565b6102e760085481565b6102e7600b5481565b6102e77f000000000000000000000000000000000000000000000000000000000000000181565b6102e76107dd565b6102e760045481565b6102e76107e8565b61030861046a366004611dd2565b61082d565b6102e761088c565b6102e7600d5481565b61036861048e366004611e04565b6108d8565b6007546102e7565b6102e76104a9366004611dd2565b610aa1565b6103086104bc366004611d98565b610aac565b6102e760065481565b6102e7600e5481565b6005546102e7565b6102e76104e9366004611dd2565b610c31565b61026b7f0000000000000000000000008a854288a5976036a725879164ca3e91d30c6a1b81565b610308610523366004611d33565b610c63565b610308610536366004611d55565b610cd8565b6102e7610dd3565b600354604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561058857600080fd5b505afa15801561059c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c09190611deb565b905090565b6000546001600160a01b031633146105f85760405162461bcd60e51b81526004016105ef90611e26565b60405180910390fd5b600d8190556040518181527f5517641de6b1335ddec71aaf252d22e25d01ae550bcf03dd1ab70dabff0294f7906020015b60405180910390a150565b6000546001600160a01b0316331461065e5760405162461bcd60e51b81526004016105ef90611e26565b600c8190556040518181527ff4f54bb8afdc04056006553a910fa184a1d469c12864eb3de384ab3dac268ec190602001610629565b600354604051631daea44360e01b8152600481018390523060248201526000916001600160a01b031690631daea443906044015b60206040518083038186803b1580156106df57600080fd5b505afa1580156106f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107179190611deb565b92915050565b6000808080808615801561072f575085155b1561074857506000935083925082915081905080610774565b861561075f5761075787610de5565b919650935091505b85156107745761076e86610eb0565b90945090505b9295509295909350565b6000546001600160a01b031633146107a85760405162461bcd60e51b81526004016105ef90611e26565b600e8190556040518181527f1b16f45e5bd5075a6a5e2a7275e8c255c9e3014fcd8253db388ed1642d1d805c90602001610629565b60006105c042610fe8565b600154604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561058857600080fd5b6000546001600160a01b031633146108575760405162461bcd60e51b81526004016105ef90611e26565b600b8190556040518181527fc310b2723151a0987892fe797393cd15ec5818c029b31f4338c1a5d9cf31265390602001610629565b60035460405163ef8b30f760e01b8152670de0b6b3a764000060048201526000916001600160a01b03169063ef8b30f79060240160206040518083038186803b15801561058857600080fd5b6000806000806000600a546001146109325760405162461bcd60e51b815260206004820152601c60248201527f4f504e4d6967726174696f6e3a205265656e7472616e742063616c6c0000000060448201526064016105ef565b6002600a5561093f611043565b6109965760405162461bcd60e51b815260206004820152602260248201527f4f504e4d6967726174696f6e3a204d6967726174696f6e206e6f742061637469604482015261766560f01b60648201526084016105ef565b60008711806109a55750600086115b6109f15760405162461bcd60e51b815260206004820181905260248201527f4f504e4d6967726174696f6e3a20426f746820616d6f756e747320617265203060448201526064016105ef565b8615610a0857610a008761105c565b919650935091505b8515610a1d57610a17866112ef565b90945090505b337f091004830132191e9dd7c86b4adefaaf7098de15f0de21434079b8cfde672b8088888886898988610a526103e882611e86565b604080519889526020890197909752958701949094526060860192909252608085015260a084015260c083015260e08201526101000160405180910390a26001600a5593969295509093509190565b600061071782610fe8565b6000546001600160a01b03163314610ad65760405162461bcd60e51b81526004016105ef90611e26565b8015610bf0576003546001600160a01b0316610b345760405162461bcd60e51b815260206004820181905260248201527f4f504e4d6967726174696f6e3a20784f70656e546f6b656e206e6f742073657460448201526064016105ef565b6001546001600160a01b0316610b8c5760405162461bcd60e51b815260206004820152601f60248201527f4f504e4d6967726174696f6e3a206f70656e546f6b656e206e6f74207365740060448201526064016105ef565b6002546001600160a01b0316610bf05760405162461bcd60e51b8152602060048201526024808201527f4f504e4d6967726174696f6e3a206f706e4d696e744d616e61676572206e6f74604482015263081cd95d60e21b60648201526084016105ef565b6009805460ff19168215159081179091556040519081527f8b9a2b3d88eb6afe031f6906dff44d741e3e147f55c1d93fb1ed30492e7a488490602001610629565b60035460405163ef8b30f760e01b8152600481018390526000916001600160a01b03169063ef8b30f7906024016106c7565b6000546001600160a01b03163314610c8d5760405162461bcd60e51b81526004016105ef90611e26565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b6000546001600160a01b03163314610d025760405162461bcd60e51b81526004016105ef90611e26565b600180546001600160a01b038086166001600160a01b031992831681179093556002805485831690841617905560038054918616919092161790556040517f2bead221d9ba47e926f473e6182be9c42681573e4fb7645b3df3bd2731a76fde90600090a26040516001600160a01b038316907fc05033ac9e8b990f526abfb217536f2a6acef89e9d17ac22c793d72fb1b7209190600090a26040516001600160a01b038216907f1d5842357c4a776fb6862c5c2e200a5298bf9273363ee80b93672a76a12ae7ec90600090a2505050565b60006006546004546105c09190611e4c565b6000808080610df66103e886611e86565b9050670de0b6b3a7640000610e0a42610fe8565b610e149083611e86565b610e1e9190611e64565b9250610e2a8382611ea5565b60035460405163ef8b30f760e01b8152600481018690529195506001600160a01b03169063ef8b30f79060240160206040518083038186803b158015610e6f57600080fd5b505afa158015610e83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea79190611deb565b93959294505050565b604051631daea44360e01b81526004810182905230602482015260009081906001600160a01b037f0000000000000000000000003e49e9c890cd5b015a18ed76e7a4093f569f1a041690631daea4439060440160206040518083038186803b158015610f1b57600080fd5b505afa158015610f2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f539190611deb565b90506000610f636103e883611e86565b60035460405163ef8b30f760e01b8152600481018390529192506001600160a01b03169063ef8b30f79060240160206040518083038186803b158015610fa857600080fd5b505afa158015610fbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe09190611deb565b925050915091565b6000600c548210156110035750670de0b6b3a7640000919050565b600b54600c540182111561101957506000919050565b600c54600b54600e5491840391828203919082028161103a5761103a611ed2565b04949350505050565b6000600c5442101580156105c057505060095460ff1690565b600080600061106a846114a2565b836004600082825461107c9190611e4c565b90915550600090506110906103e886611e86565b905080600860008282546110a49190611e4c565b90915550600090506110b542610fe8565b9050806110cc578194506000925060009350611282565b670de0b6b3a76400006110df8284611e86565b6110e99190611e64565b93506110f58483611ea5565b945083600760008282546111099190611e4c565b90915550506002546040516329a4f43160e01b8152306004820152602481018690526001600160a01b03909116906329a4f43190604401600060405180830381600087803b15801561115a57600080fd5b505af115801561116e573d6000803e3d6000fd5b505060015460035460405163095ea7b360e01b81526001600160a01b039182166004820152602481018990529116925063095ea7b39150604401602060405180830381600087803b1580156111c257600080fd5b505af11580156111d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fa9190611db5565b50600354604051636e553f6560e01b8152600481018690523360248201526001600160a01b0390911690636e553f6590604401602060405180830381600087803b15801561124757600080fd5b505af115801561125b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127f9190611deb565b92505b6002546040516329a4f43160e01b8152336004820152602481018790526001600160a01b03909116906329a4f43190604401600060405180830381600087803b1580156112ce57600080fd5b505af11580156112e2573d6000803e3d6000fd5b5050505050509193909250565b6000806112fb83611799565b9050826005600082825461130f9190611e4c565b9250508190555080600660008282546113289190611e4c565b909155506000905061133c6103e883611e86565b905080600860008282546113509190611e4c565b90915550506002546040516329a4f43160e01b8152306004820152602481018390526001600160a01b03909116906329a4f43190604401600060405180830381600087803b1580156113a157600080fd5b505af11580156113b5573d6000803e3d6000fd5b505060015460035460405163095ea7b360e01b81526001600160a01b039182166004820152602481018690529116925063095ea7b39150604401602060405180830381600087803b15801561140957600080fd5b505af115801561141d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114419190611db5565b50600354604051636e553f6560e01b8152600481018390523360248201526001600160a01b0390911690636e553f6590604401602060405180830381600087803b15801561148e57600080fd5b505af1158015610fbc573d6000803e3d6000fd5b6040516370a0823160e01b815233600482015281907f0000000000000000000000008a854288a5976036a725879164ca3e91d30c6a1b6001600160a01b0316906370a082319060240160206040518083038186803b15801561150357600080fd5b505afa158015611517573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061153b9190611deb565b10156115985760405162461bcd60e51b815260206004820152602660248201527f4f504e4d6967726174696f6e3a20496e73756666696369656e74204745542062604482015265616c616e636560d01b60648201526084016105ef565b604051636eb1769f60e11b815233600482015230602482015281907f0000000000000000000000008a854288a5976036a725879164ca3e91d30c6a1b6001600160a01b03169063dd62ed3e9060440160206040518083038186803b1580156115ff57600080fd5b505afa158015611613573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116379190611deb565b10156116915760405162461bcd60e51b8152602060048201526024808201527f4f504e4d6967726174696f6e3a20474554207370656e64206e6f7420617070726044820152631bdd995960e21b60648201526084016105ef565b6040516323b872dd60e01b8152336004820152306024820152604481018290527f0000000000000000000000008a854288a5976036a725879164ca3e91d30c6a1b6001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156116ff57600080fd5b505af1158015611713573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117379190611db5565b61178d5760405162461bcd60e51b815260206004820152602160248201527f4f504e4d6967726174696f6e3a20474554207472616e73666572206661696c656044820152601960fa1b60648201526084016105ef565b61179681611b42565b50565b6040516370a0823160e01b815233600482015260009082906001600160a01b037f0000000000000000000000003e49e9c890cd5b015a18ed76e7a4093f569f1a0416906370a082319060240160206040518083038186803b1580156117fd57600080fd5b505afa158015611811573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118359190611deb565b10156118935760405162461bcd60e51b815260206004820152602760248201527f4f504e4d6967726174696f6e3a20496e73756666696369656e7420584745542060448201526662616c616e636560c81b60648201526084016105ef565b604051636eb1769f60e11b815233600482015230602482015282907f0000000000000000000000003e49e9c890cd5b015a18ed76e7a4093f569f1a046001600160a01b03169063dd62ed3e9060440160206040518083038186803b1580156118fa57600080fd5b505afa15801561190e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119329190611deb565b101561198e5760405162461bcd60e51b815260206004820152602560248201527f4f504e4d6967726174696f6e3a2058474554207370656e64206e6f74206170706044820152641c9bdd995960da1b60648201526084016105ef565b6040516323b872dd60e01b8152336004820152306024820152604481018390527f0000000000000000000000003e49e9c890cd5b015a18ed76e7a4093f569f1a046001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156119fc57600080fd5b505af1158015611a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a349190611db5565b611a8b5760405162461bcd60e51b815260206004820152602260248201527f4f504e4d6967726174696f6e3a2058474554207472616e73666572206661696c604482015261195960f21b60648201526084016105ef565b604051635d043b2960e11b815260048101839052306024820181905260448201527f0000000000000000000000003e49e9c890cd5b015a18ed76e7a4093f569f1a046001600160a01b03169063ba08765290606401602060405180830381600087803b158015611afa57600080fd5b505af1158015611b0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b329190611deb565b9050611b3d81611b42565b919050565b7f000000000000000000000000000000000000000000000000000000000000000160011415611be857604051630852cd8d60e31b8152600481018290527f0000000000000000000000008a854288a5976036a725879164ca3e91d30c6a1b6001600160a01b0316906342966c6890602401600060405180830381600087803b158015611bcd57600080fd5b505af1158015611be1573d6000803e3d6000fd5b5050505050565b60405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000f7a171c168a35ae858fd18bec5bb7c28134b823f81166004830152602482018390527f0000000000000000000000008a854288a5976036a725879164ca3e91d30c6a1b169063a9059cbb90604401602060405180830381600087803b158015611c7257600080fd5b505af1158015611c86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611caa9190611db5565b6117965760405162461bcd60e51b815260206004820152603a60248201527f4f504e4d6967726174696f6e3a20474554207472616e7366657220746f206d6960448201527f67726174696f6e2064657374696e6174696f6e206661696c656400000000000060648201526084016105ef565b80356001600160a01b0381168114611b3d57600080fd5b600060208284031215611d4557600080fd5b611d4e82611d1c565b9392505050565b600080600060608486031215611d6a57600080fd5b611d7384611d1c565b9250611d8160208501611d1c565b9150611d8f60408501611d1c565b90509250925092565b600060208284031215611daa57600080fd5b8135611d4e81611ee8565b600060208284031215611dc757600080fd5b8151611d4e81611ee8565b600060208284031215611de457600080fd5b5035919050565b600060208284031215611dfd57600080fd5b5051919050565b60008060408385031215611e1757600080fd5b50508035926020909101359150565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b60008219821115611e5f57611e5f611ebc565b500190565b600082611e8157634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615611ea057611ea0611ebc565b500290565b600082821015611eb757611eb7611ebc565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b801515811461179657600080fdfea264697066735822122016d8044825341a2d7bafa8e6cc3095e293a3e75ae6586bc693372d88ce35656b64736f6c63430008070033

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

000000000000000000000000f7a171c168a35ae858fd18bec5bb7c28134b823f0000000000000000000000008a854288a5976036a725879164ca3e91d30c6a1b0000000000000000000000003e49e9c890cd5b015a18ed76e7a4093f569f1a040000000000000000000000000000000000000000000000000000000066068a1800000000000000000000000000000000000000000000000006f05b59d3b200000000000000000000000000000000000000000000000000000000000000278d00000000000000000000000000f7a171c168a35ae858fd18bec5bb7c28134b823f0000000000000000000000000000000000000000000000000000000000000001

-----Decoded View---------------
Arg [0] : _initialOwner (address): 0xF7a171C168A35ae858FD18BEc5Bb7C28134B823F
Arg [1] : _liquidGETAddress (address): 0x8a854288a5976036A725879164Ca3e91d30c6A1B
Arg [2] : _stakedGETAddress (address): 0x3e49E9C890Cd5B015A18ed76E7A4093f569f1A04
Arg [3] : _startOfMigration (uint256): 1711704600
Arg [4] : _startStakeRate (uint256): 500000000000000000
Arg [5] : _durationOfStakeMigrationPeriod (uint256): 2592000
Arg [6] : _bridgeMigrationAddress (address): 0xF7a171C168A35ae858FD18BEc5Bb7C28134B823F
Arg [7] : _chainId (uint256): 1

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000f7a171c168a35ae858fd18bec5bb7c28134b823f
Arg [1] : 0000000000000000000000008a854288a5976036a725879164ca3e91d30c6a1b
Arg [2] : 0000000000000000000000003e49e9c890cd5b015a18ed76e7a4093f569f1a04
Arg [3] : 0000000000000000000000000000000000000000000000000000000066068a18
Arg [4] : 00000000000000000000000000000000000000000000000006f05b59d3b20000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000278d00
Arg [6] : 000000000000000000000000f7a171c168a35ae858fd18bec5bb7c28134b823f
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000001


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

OVERVIEW

This is the official migration contract for the GET Protocol(0x8a854288a5976036A725879164Ca3e91d30c6A1B) migration to OPN(0xc28eb2250d1AE32c7E74CFb6d6b86afC9BEb6509).

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.