ETH Price: $3,678.21 (-1.42%)

Contract

0xe09c7e9AEa5203EDCD143e7D2e292c66B5DBA793
 
Transaction Hash
Method
Block
From
To
Rebalance212109422024-11-18 0:13:3514 days ago1731888815IN
0xe09c7e9A...6B5DBA793
0 ETH0.004999737.35637028
Claim Rewards211070472024-11-03 12:14:2329 days ago1730636063IN
0xe09c7e9A...6B5DBA793
0 ETH0.000866883.81120359
Claim Rewards211070232024-11-03 12:09:3529 days ago1730635775IN
0xe09c7e9A...6B5DBA793
0 ETH0.000935833.81482847
Claim Rewards211070112024-11-03 12:07:1129 days ago1730635631IN
0xe09c7e9A...6B5DBA793
0 ETH0.00091814.02340289
Claim Rewards211070092024-11-03 12:06:4729 days ago1730635607IN
0xe09c7e9A...6B5DBA793
0 ETH0.001036744.01464047
Claim Rewards211069972024-11-03 12:04:2329 days ago1730635463IN
0xe09c7e9A...6B5DBA793
0 ETH0.001045724.0172167
Claim Rewards210711852024-10-29 12:06:5934 days ago1730203619IN
0xe09c7e9A...6B5DBA793
0 ETH0.002259049.20870255
Claim Rewards210711712024-10-29 12:04:1134 days ago1730203451IN
0xe09c7e9A...6B5DBA793
0 ETH0.002023888.89791599
Claim Rewards210711702024-10-29 12:03:5934 days ago1730203439IN
0xe09c7e9A...6B5DBA793
0 ETH0.002341149.0563224
Claim Rewards210711582024-10-29 12:01:3534 days ago1730203295IN
0xe09c7e9A...6B5DBA793
0 ETH0.002257788.6734199
Claim Rewards210354782024-10-24 12:32:2339 days ago1729773143IN
0xe09c7e9A...6B5DBA793
0 ETH0.002013168.85079288
Claim Rewards210354472024-10-24 12:26:1139 days ago1729772771IN
0xe09c7e9A...6B5DBA793
0 ETH0.002527829.71079664
Claim Rewards210354452024-10-24 12:25:4739 days ago1729772747IN
0xe09c7e9A...6B5DBA793
0 ETH0.002078299.84547363
Claim Rewards210353402024-10-24 12:04:3539 days ago1729771475IN
0xe09c7e9A...6B5DBA793
0 ETH0.0034213413.23492708
Claim Rewards210353392024-10-24 12:04:2339 days ago1729771463IN
0xe09c7e9A...6B5DBA793
0 ETH0.0030947412.61532629
Claim Rewards209997222024-10-19 12:49:4744 days ago1729342187IN
0xe09c7e9A...6B5DBA793
0 ETH0.0028015110.68677237
Claim Rewards209994972024-10-19 12:04:3544 days ago1729339475IN
0xe09c7e9A...6B5DBA793
0 ETH0.002003498.80825342
Claim Rewards209994952024-10-19 12:04:1144 days ago1729339451IN
0xe09c7e9A...6B5DBA793
0 ETH0.0019398.52476848
Claim Rewards209994932024-10-19 12:03:4744 days ago1729339427IN
0xe09c7e9A...6B5DBA793
0 ETH0.002198237.98366657
Claim Rewards209994872024-10-19 12:02:3544 days ago1729339355IN
0xe09c7e9A...6B5DBA793
0 ETH0.0021248.15949896
Claim Rewards209994852024-10-19 12:02:1144 days ago1729339331IN
0xe09c7e9A...6B5DBA793
0 ETH0.001770377.78336272
Rebalance209707542024-10-15 11:45:4748 days ago1728992747IN
0xe09c7e9A...6B5DBA793
0 ETH0.004298615.32512892
Rebalance209706022024-10-15 11:14:5948 days ago1728990899IN
0xe09c7e9A...6B5DBA793
0 ETH0.0049620218.39286624
Rebalance209704742024-10-15 10:49:1148 days ago1728989351IN
0xe09c7e9A...6B5DBA793
0 ETH0.0024456110.92216443
Claim Rewards209636852024-10-14 12:04:1149 days ago1728907451IN
0xe09c7e9A...6B5DBA793
0 ETH0.0105982940.46323001
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
203397992024-07-19 9:52:11136 days ago1721382731  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MeldFarmingManager

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
shanghai EvmVersion
File 1 of 12 : MeldFarmingManager.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IMeldFarming, IMeldFarmingManager} from "./interfaces/IMeldFarmingManager.sol";
import {ILockedAdapter} from "./interfaces/ILockedAdapter.sol";
import {IMeldBridgeReceiver} from "./interfaces/IMeldBridgeReceiver.sol";
import {Errors} from "./libraries/Errors.sol";

/**
 * @title Meld Farming Manager contract
 * @notice Contract that manages the yield farming adapters
 * @author MELD team
 */
contract MeldFarmingManager is IMeldFarmingManager {
    using SafeERC20 for IERC20;

    mapping(uint256 index => address adapterAddress) public override adapterAddresses;
    mapping(address adapterAddress => AdapterConfig config) private adapters;
    uint256 public override numAdapters;

    mapping(address => YieldAssetConfig) private yieldAssetConfigs;

    IMeldBridgeReceiver public override bridge;
    address public override treasury;

    /**
     * @notice Modifier to check that only the bridge can call the function
     */
    modifier onlyBridge() {
        require(msg.sender == address(bridge), Errors.MFM_ONLY_BRIDGE_ALLOWED);
        _;
    }

    /**
     * @notice Modifier to check that the caller has the required role
     * @dev It queries the bridge contract to check the role
     * @param _role Role required to call the function
     */
    modifier onlyRole(bytes32 _role) {
        bridge.checkRole(_role, msg.sender);
        _;
    }

    /**
     * @notice Constructor of the contract
     * @param _bridge Address of the Meld Bridge Receiver contract
     * @param _treasury Address of the treasury
     */
    constructor(address _bridge, address _treasury) {
        bridge = IMeldBridgeReceiver(_bridge);
        emit BridgeSet(msg.sender, _bridge);
        _setTreasury(_treasury);
    }

    /**
     * @inheritdoc IMeldFarmingManager
     */
    function addAdapter(
        string memory _adapterId,
        address _adapterAddress,
        bool _locked
    ) external override onlyRole(bridge.CONFIGURATION_ROLE()) {
        require(bytes(_adapterId).length > 0, Errors.MFM_INVALID_ADAPTER_ID);
        require(!adapters[_adapterAddress].exists, Errors.MFM_ADAPTER_ALREADY_EXISTS);
        require(_adapterAddress != address(0), Errors.INVALID_ADDRESS);
        IMeldFarming adapter = IMeldFarming(_adapterAddress);
        require(
            adapter.supportsInterface(type(IMeldFarming).interfaceId),
            Errors.MFM_ADAPTER_IS_NOT_MELD_FARMING
        );
        require(adapter.meldFarmingManager() == address(this), Errors.MFM_INVALID_ADAPTER_MFM);

        adapters[_adapterAddress] = AdapterConfig({
            adapterIdStr: _adapterId,
            enabled: true,
            locked: _locked,
            exists: true
        });
        adapterAddresses[numAdapters] = _adapterAddress;
        numAdapters++;
        emit AdapterAdded(msg.sender, _adapterId, _adapterAddress, _locked);
    }

    /**
     * @inheritdoc IMeldFarmingManager
     */
    function setAdapterEnabled(
        address _adapterAddress,
        bool _enabled
    ) external override onlyRole(bridge.CONFIGURATION_ROLE()) {
        AdapterConfig storage adapter = adapters[_adapterAddress];
        require(adapter.exists, Errors.MFM_ADAPTER_DOES_NOT_EXIST);
        adapter.enabled = _enabled;
        emit AdapterEnabled(msg.sender, _adapterAddress, _enabled);
    }

    /**
     * @inheritdoc IMeldFarmingManager
     */
    function configAsset(
        address _asset,
        address[] memory _adaptersAddresses
    ) external override onlyRole(bridge.CONFIGURATION_ROLE()) {
        YieldAssetConfig storage yaConfig = yieldAssetConfigs[_asset];

        address[] memory tempAdapterAddresses = new address[](
            yaConfig.numAdapters + _adaptersAddresses.length
        );
        address tempAdapterAddress;
        YieldAssetAdapter memory tempAdapter;
        uint256 tempNumAdapters = yaConfig.numAdapters;

        _safeApproveAll(IERC20(_asset), address(bridge));

        // We create an array of size oldList + newList of adapter ids
        // If the adapter already exists, we set its id in the same position
        // If the adapter doesn't exist, we set its id after the last position of the old list and update that pointer
        // Once that it's done, we have to reorganize the info to remove the empty spaces

        for (uint256 i = 0; i < _adaptersAddresses.length; i++) {
            require(adapters[_adaptersAddresses[i]].exists, Errors.MFM_ADAPTER_DOES_NOT_EXIST);
            // Iterate over the new list of adapters
            tempAdapterAddress = _adaptersAddresses[i];
            tempAdapter = yaConfig.adapters[tempAdapterAddress];
            if (tempAdapter.exists) {
                // If the adapter already exists, set its id in the tempAdapterAddresss
                tempAdapterAddresses[tempAdapter.index] = tempAdapterAddress;
            } else {
                // If the adapter doesn't exist, add it to the list
                tempAdapterAddresses[tempNumAdapters] = tempAdapterAddress;
                yaConfig.adapterIndex[tempNumAdapters] = tempAdapterAddress;
                yaConfig.adapters[tempAdapterAddress] = YieldAssetAdapter({
                    yieldDeposit: 0,
                    lastTimestampRewardsClaimed: 0,
                    index: tempNumAdapters,
                    exists: true
                });

                _safeApproveAll(IERC20(_asset), tempAdapterAddress);
                tempNumAdapters++;
            }
        }

        emit AssetConfigSet(msg.sender, _asset, _adaptersAddresses);
        if (tempNumAdapters == 0) {
            return;
        }

        uint256 rewardsClaimed = 0;
        uint256 tempRewards;

        for (uint256 i = 0; i < yaConfig.numAdapters; i++) {
            if (tempAdapterAddresses[i] != address(0)) {
                // Position not empty
                continue;
            }
            // Position empty

            // Withdraw all from the adapter

            address oldAdapterAddress = adapterAddresses[i];

            AdapterConfig memory adapterConfig = adapters[oldAdapterAddress];

            _checkAdapterEnabled(adapterConfig);

            uint256 adapterAssetDepositAmount = yaConfig.adapters[oldAdapterAddress].yieldDeposit;

            yaConfig.liquidDeposit += IMeldFarming(oldAdapterAddress).withdraw(
                _asset,
                adapterAssetDepositAmount,
                ""
            );
            tempRewards = IMeldFarming(oldAdapterAddress).claimRewards(_asset, "", false);
            rewardsClaimed += tempRewards;
            emit RewardsClaimed(msg.sender, _asset, oldAdapterAddress, tempRewards);

            // Remove old position
            delete yaConfig.adapters[oldAdapterAddress];
            for (; tempNumAdapters > i; tempNumAdapters--) {
                if (tempAdapterAddresses[tempNumAdapters - 1] == address(0)) {
                    // Last position empty
                    continue;
                }
                tempAdapterAddresses[i] = tempAdapterAddresses[tempNumAdapters - 1];
                yaConfig.adapters[tempAdapterAddresses[i]].index = i;
                yaConfig.adapterIndex[i] = tempAdapterAddresses[i];
                tempAdapterAddresses[tempNumAdapters - 1] = address(0);
                tempNumAdapters--;
                break;
            }
        }

        yaConfig.numAdapters = _adaptersAddresses.length;

        if (rewardsClaimed > 0) {
            IERC20(_asset).safeTransfer(treasury, rewardsClaimed);
        }
    }

    /**
     * @inheritdoc IMeldFarmingManager
     */
    function setTreasury(
        address _treasury
    ) external override onlyRole(bridge.CONFIGURATION_ROLE()) {
        _setTreasury(_treasury);
    }

    /**
     * @inheritdoc IMeldFarmingManager
     */
    function rebalance(
        RebalancingInfo[] calldata _rebalanceInfo
    ) external override onlyRole(bridge.REBALANCER_ROLE()) {
        require(_rebalanceInfo.length > 0, Errors.INVALID_ARRAY_LENGTH);
        for (uint256 i = 0; i < _rebalanceInfo.length; i++) {
            RebalancingInfo calldata rebalanceInfo = _rebalanceInfo[i];
            _checkAdapterEnabled(adapters[rebalanceInfo.adapterAddress]);
            IMeldFarming adapter = IMeldFarming(rebalanceInfo.adapterAddress);

            YieldAssetConfig storage yaConfig = yieldAssetConfigs[rebalanceInfo.asset];
            if (rebalanceInfo.action == RebalanceAction.DEPOSIT) {
                require(
                    rebalanceInfo.amount <= yaConfig.liquidDeposit,
                    Errors.MFM_NOT_ENOUGH_FUNDS
                );
                adapter.deposit(rebalanceInfo.asset, rebalanceInfo.amount, rebalanceInfo.extra);
                yaConfig.liquidDeposit -= rebalanceInfo.amount;
                yaConfig.adapters[rebalanceInfo.adapterAddress].yieldDeposit += rebalanceInfo
                    .amount;
            } else if (rebalanceInfo.action == RebalanceAction.WITHDRAW) {
                require(
                    rebalanceInfo.amount <=
                        yaConfig.adapters[rebalanceInfo.adapterAddress].yieldDeposit,
                    Errors.MFM_NOT_ENOUGH_FUNDS
                );
                uint256 amount = adapter.withdraw(
                    rebalanceInfo.asset,
                    rebalanceInfo.amount,
                    rebalanceInfo.extra
                );
                require(amount == rebalanceInfo.amount, Errors.MFM_AMOUNT_MISMATCH);
                yaConfig.liquidDeposit += rebalanceInfo.amount;
                yaConfig.adapters[rebalanceInfo.adapterAddress].yieldDeposit -= rebalanceInfo
                    .amount;
            } else if (rebalanceInfo.action == RebalanceAction.REQUEST_WITHDRAW) {
                ILockedAdapter(address(adapter)).requestWithdraw(
                    rebalanceInfo.asset,
                    rebalanceInfo.amount,
                    rebalanceInfo.extra
                );
            }
            emit Rebalanced(
                msg.sender,
                rebalanceInfo.asset,
                rebalanceInfo.adapterAddress,
                rebalanceInfo.amount,
                rebalanceInfo.action
            );
        }
    }

    /**
     * @inheritdoc IMeldFarming
     */
    function deposit(address _asset, uint256 _amount, bytes calldata) external override onlyBridge {
        YieldAssetConfig storage assetConfig = yieldAssetConfigs[_asset];

        assetConfig.liquidDeposit += _amount;

        emit Deposited(_asset, _amount);
    }

    /**
     * @inheritdoc IMeldFarming
     */
    function withdraw(
        address _asset,
        uint256 _amount,
        bytes calldata _extra
    ) external override onlyBridge returns (uint256) {
        YieldAssetConfig storage assetConfig = yieldAssetConfigs[_asset];
        uint256 remainingAmount = _amount;

        if (remainingAmount > assetConfig.liquidDeposit) {
            remainingAmount -= assetConfig.liquidDeposit;
            assetConfig.liquidDeposit = 0;
            for (uint256 i = 0; i < assetConfig.numAdapters; i++) {
                address adapterAddress = assetConfig.adapterIndex[i];
                IMeldFarming adapter = IMeldFarming(adapterAddress);
                YieldAssetAdapter storage yaAdapter = assetConfig.adapters[adapterAddress];
                AdapterConfig memory adapterConfig = adapters[adapterAddress];
                if (!adapterConfig.enabled) {
                    continue;
                }
                uint256 adapterAvailableLiquidity = adapter.getAvailableLiquidity(_asset);
                if (adapterAvailableLiquidity == 0) {
                    continue;
                }
                if (adapterAvailableLiquidity >= remainingAmount) {
                    adapter.withdraw(_asset, remainingAmount, _extra);
                    yaAdapter.yieldDeposit -= remainingAmount;
                    remainingAmount = 0;
                    break;
                } else {
                    adapter.withdraw(_asset, adapterAvailableLiquidity, _extra);
                    yaAdapter.yieldDeposit = 0;
                    remainingAmount -= adapterAvailableLiquidity;
                }
            }
            require(remainingAmount == 0, Errors.MFM_NOT_ENOUGH_FUNDS);
        } else {
            assetConfig.liquidDeposit -= remainingAmount;
        }
        emit Withdrawn(_asset, _amount);

        return _amount;
    }

    /**
     * @inheritdoc IMeldFarming
     */
    function claimRewards(
        address _asset,
        bytes calldata _extra,
        bool _withdrawOnlyAvailable
    ) external override onlyRole(bridge.REBALANCER_ROLE()) returns (uint256) {
        YieldAssetConfig storage assetConfig = yieldAssetConfigs[_asset];
        require(assetConfig.numAdapters > 0, Errors.MFM_NO_ADAPTERS_CONFIGURED);
        uint256 totalRewards;
        for (uint256 i = 0; i < assetConfig.numAdapters; i++) {
            address adapterAddress = assetConfig.adapterIndex[i];
            YieldAssetAdapter storage yaAdapter = assetConfig.adapters[adapterAddress];
            AdapterConfig memory adapterConfig = adapters[adapterAddress];
            if (!adapterConfig.enabled) {
                continue;
            }
            uint256 rewards = IMeldFarming(adapterAddress).claimRewards(
                _asset,
                _extra,
                _withdrawOnlyAvailable
            );
            if (rewards > 0) {
                totalRewards += rewards;
                yaAdapter.lastTimestampRewardsClaimed = block.timestamp;
            }
            emit RewardsClaimed(msg.sender, _asset, adapterAddress, rewards);
        }
        IERC20(_asset).safeTransfer(treasury, totalRewards);
        return totalRewards;
    }

    /**
     * @inheritdoc IMeldFarmingManager
     */
    function getAllAdapters() external view override returns (AdapterConfig[] memory) {
        AdapterConfig[] memory adaptersConfig = new AdapterConfig[](numAdapters);
        for (uint256 i = 0; i < numAdapters; i++) {
            adaptersConfig[i] = adapters[adapterAddresses[i]];
        }
        return adaptersConfig;
    }

    /**
     * @inheritdoc IMeldFarmingManager
     */
    function getAdapter(
        address _adapterAddress
    ) external view override returns (AdapterConfig memory) {
        return adapters[_adapterAddress];
    }

    /**
     * @inheritdoc IMeldFarmingManager
     */
    function getYieldAssetConfig(
        address _asset
    )
        external
        view
        override
        returns (
            string[] memory assetAdapterIds,
            address[] memory assetAdapterAddresses,
            uint256[] memory yieldDeposit,
            uint256[] memory lastTimestampRewardsClaimed,
            uint256 liquidDeposit,
            uint256 totalDeposit,
            uint256 totalAvailableLiquidity
        )
    {
        YieldAssetConfig storage assetConfig = yieldAssetConfigs[_asset];
        uint256 assetNumAdapters = assetConfig.numAdapters;
        liquidDeposit = assetConfig.liquidDeposit;
        totalDeposit = liquidDeposit;
        totalAvailableLiquidity = liquidDeposit;
        assetAdapterIds = new string[](assetNumAdapters);
        yieldDeposit = new uint256[](assetNumAdapters);
        lastTimestampRewardsClaimed = new uint256[](assetNumAdapters);
        assetAdapterAddresses = new address[](assetNumAdapters);
        address tempAdapterAddress;
        YieldAssetAdapter memory tempAdapter;
        for (uint256 i = 0; i < assetNumAdapters; i++) {
            tempAdapterAddress = assetConfig.adapterIndex[i];
            assetAdapterIds[i] = adapters[tempAdapterAddress].adapterIdStr;
            tempAdapter = assetConfig.adapters[tempAdapterAddress];
            yieldDeposit[i] = tempAdapter.yieldDeposit;
            totalDeposit += tempAdapter.yieldDeposit;
            totalAvailableLiquidity += IMeldFarming(tempAdapterAddress).getAvailableLiquidity(
                _asset
            );
            assetAdapterAddresses[i] = tempAdapterAddress;
            lastTimestampRewardsClaimed[i] = tempAdapter.lastTimestampRewardsClaimed;
        }
    }

    /**
     * @inheritdoc IMeldFarmingManager
     */
    function getTotalDeposit(address _asset) external view override returns (uint256) {
        YieldAssetConfig storage assetConfig = yieldAssetConfigs[_asset];
        uint256 total = assetConfig.liquidDeposit;
        address tempAdapterAddress;
        for (uint256 i = 0; i < assetConfig.numAdapters; i++) {
            tempAdapterAddress = assetConfig.adapterIndex[i];
            total += assetConfig.adapters[tempAdapterAddress].yieldDeposit;
        }
        return total;
    }

    /**
     * @inheritdoc IMeldFarming
     * @dev This includes the funds in the Meld Farming Manager plus the funds in the non-locked adapters
     */
    function getAvailableLiquidity(address _asset) external view override returns (uint256) {
        YieldAssetConfig storage assetConfig = yieldAssetConfigs[_asset];
        uint256 total = assetConfig.liquidDeposit;
        address tempAdapterAddress;
        for (uint256 i = 0; i < assetConfig.numAdapters; i++) {
            tempAdapterAddress = assetConfig.adapterIndex[i];
            if (!adapters[tempAdapterAddress].locked) {
                total += IMeldFarming(tempAdapterAddress).getAvailableLiquidity(_asset);
            }
        }
        return total;
    }

    /**
     * @inheritdoc IMeldFarming
     * @dev This is the sum of the rewards of the adapters configured for the asset
     */
    function getRewardsAmount(address _asset) external view override returns (uint256) {
        YieldAssetConfig storage assetConfig = yieldAssetConfigs[_asset];
        uint256 total;
        address tempAdapterAddress;
        for (uint256 i = 0; i < assetConfig.numAdapters; i++) {
            tempAdapterAddress = assetConfig.adapterIndex[i];
            total += IMeldFarming(tempAdapterAddress).getRewardsAmount(_asset);
        }
        return total;
    }

    /**
     * @inheritdoc IMeldFarming
     * @dev This function is intended for the Yield Adapters, but this contract must implement the same interface
     */
    function meldFarmingManager() external view override returns (address) {
        return address(this);
    }

    /**
     * @inheritdoc IERC165
     */
    function supportsInterface(bytes4 _interfaceId) public pure override returns (bool) {
        return _interfaceId == type(IMeldFarming).interfaceId;
    }

    /**
     * @notice Private function to set the treasury address
     * @param _treasury Address of the treasury
     */
    function _setTreasury(address _treasury) private {
        require(_treasury != address(0), Errors.INVALID_ADDRESS);
        emit TreasuryUpdated(msg.sender, treasury, _treasury);
        treasury = _treasury;
    }

    /**
     * @notice Private function to safe approve all the tokens to the spender
     * @param _token Token to approve
     * @param _spender Spender to approve
     */
    function _safeApproveAll(IERC20 _token, address _spender) private {
        uint256 allowance = _token.allowance(address(this), _spender);
        uint256 increaseAllowance = type(uint256).max - allowance;
        if (increaseAllowance > 0) {
            _token.safeIncreaseAllowance(_spender, increaseAllowance);
        }
    }

    /**
     * @notice Private function to check if the adapter is enabled
     * @dev It reverts if the adapter is not enabled
     * @param _adapter Adapter configuration
     */
    function _checkAdapterEnabled(AdapterConfig memory _adapter) private pure {
        require(_adapter.enabled, Errors.MFM_ADAPTER_DISABLED);
    }
}

File 2 of 12 : IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * ==== Security Considerations
 *
 * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
 * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
 * considered as an intention to spend the allowance in any specific way. The second is that because permits have
 * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
 * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
 * generally recommended is:
 *
 * ```solidity
 * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
 *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
 *     doThing(..., value);
 * }
 *
 * function doThing(..., uint256 value) public {
 *     token.safeTransferFrom(msg.sender, address(this), value);
 *     ...
 * }
 * ```
 *
 * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
 * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
 * {SafeERC20-safeTransferFrom}).
 *
 * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
 * contracts should have entry points that don't rely on permit.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     *
     * CAUTION: See Security Considerations above.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 3 of 12 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

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

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

File 4 of 12 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
     * Revert on invalid signature.
     */
    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return
            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
    }
}

File 5 of 12 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

File 6 of 12 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 7 of 12 : ILockedAdapter.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

/**
 * @title Locked Adapter interface
 * @notice Interface for the locked adapters, to add the requestWithdraw function
 * @author MELD team
 */
interface ILockedAdapter {
    /**
     * @notice Request a withdraw from the adapter, so the funds can be withdrawn in the future
     * @param _asset Address of the asset to withdraw
     * @param _amount Amount to withdraw
     * @param _extra Extra data for the withdraw
     */
    function requestWithdraw(address _asset, uint256 _amount, bytes calldata _extra) external;
}

File 8 of 12 : IMeldBridgeBase.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

/**
 * @title Meld Bridge Base interface
 * @notice Interface for the Meld Bridge Base contract, to set supported tokens and check roles
 * @author MELD team
 */
interface IMeldBridgeBase {
    /**
     * @notice Emitted when a token is supported or unsupported
     * @param executedBy Address that executed the event
     * @param token Address of the token
     * @param supported True if the token is supported, false if unsupported
     */
    event SupportedTokenSet(address indexed executedBy, address indexed token, bool supported);

    /**
     * @notice Set the supported status of a token
     * @param _token Address of the token
     * @param _supported True if the token is supported, false if unsupported
     */
    function setSupportedToken(address _token, bool _supported) external;

    /**
     * @notice Check if an account has a role. Reverts if the account does not have the role
     * @param _role Role to check
     * @param _account Account to check
     */
    function checkRole(bytes32 _role, address _account) external view;

    /**
     * @notice Role for configuration
     * @return Role
     */
    function CONFIGURATION_ROLE() external view returns (bytes32); // solhint-disable-line func-name-mixedcase

    /**
     * @notice Role for execution of requests
     * @return Role
     */
    function EXECUTION_ROLE() external view returns (bytes32); // solhint-disable-line func-name-mixedcase

    /**
     * @notice Check if a token is supported
     * @param _token Address of the token
     * @return True if the token is supported
     */
    function supportedTokens(address _token) external view returns (bool);

    /**
     * @notice Check if a request has been processed
     * @param _requestId ID of the request
     * @return True if the request has been processed
     */
    function processedRequests(bytes32 _requestId) external view returns (bool);
}

File 9 of 12 : IMeldBridgeReceiver.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {IMeldBridgeBase} from "./IMeldBridgeBase.sol";

/**
 * @title Meld Bridge Receiver interface
 * @notice Interface for interacting with the Meld Bridge Receiver contract
 * @author MELD team
 */
interface IMeldBridgeReceiver is IMeldBridgeBase {
    /**
     * @notice Event emitted when a user requests to bridge tokens
     * @param user Address of the user
     * @param token Address of the token
     * @param amount Amount of tokens to bridge
     */
    event BridgeRequested(address indexed user, address indexed token, uint256 amount);

    /**
     * @notice Event emitted when the wETH address is set
     * @param executedBy Address that executed the action
     * @param wETH Address of the wETH contract
     */
    event WETHAddressSet(address indexed executedBy, address indexed wETH);

    /**
     * @notice Event emitted when the Meld Farming Manager is deployed
     * @param executedBy Address that executed the action
     * @param meldFarmingManagerAddress Address of the Meld Farming Manager
     */
    event MeldFarmingManagerDeployed(
        address indexed executedBy,
        address indexed meldFarmingManagerAddress
    );

    /**
     * @notice Event emitted when a user requests to bridge ERC721 tokens
     * @param user Address of the user
     * @param token Address of the token
     * @param tokenId Token ID to bridge
     */
    event BridgeERC721Requested(address indexed user, address indexed token, uint256 tokenId);

    /**
     * @notice Event emitted when a user requests to bridge ERC1155 tokens
     * @param user Address of the user
     * @param token Address of the token
     * @param tokenId Token ID to bridge
     * @param amount Amount of tokens to bridge
     */
    event BridgeERC1155Requested(
        address indexed user,
        address indexed token,
        uint256 tokenId,
        uint256 amount
    );

    /**
     * @notice Event emitted when ERC20 tokens are withdrawn to a user
     * @param token Address of the token
     * @param to Address of the user
     * @param amount Amount of tokens withdrawn
     * @param requestID ID of the request
     */
    event WithdrawnToUser(
        address indexed token,
        address indexed to,
        uint256 amount,
        bytes32 indexed requestID
    );

    /**
     * @notice Event emitted when ERC721 tokens are withdrawn to a user
     * @param token Address of the token
     * @param to Address of the user
     * @param tokenId Token ID withdrawn
     * @param requestID ID of the request
     */
    event WithdrawnERC721ToUser(
        address indexed token,
        address indexed to,
        uint256 tokenId,
        bytes32 indexed requestID
    );

    /**
     * @notice Event emitted when ERC1155 tokens are withdrawn to a user
     * @param token Address of the token
     * @param to Address of the user
     * @param tokenId Token ID withdrawn
     * @param amount Amount of tokens withdrawn
     * @param requestID ID of the request
     */
    event WithdrawnERC1155ToUser(
        address indexed token,
        address indexed to,
        uint256 tokenId,
        uint256 amount,
        bytes32 indexed requestID
    );

    /**
     * @notice Function called to bridge ERC20 tokens
     * @param _token Address of the token
     * @param _amount Amount of tokens to bridge
     */
    function bridge(address _token, uint256 _amount) external;

    /**
     * @notice Function called to bridge native tokens
     * @dev This function is payable so the amount of tokens to bridge is the value sent with the transaction
     */
    function bridgeNative() external payable;

    /**
     * @notice Function called to bridge ERC721 tokens
     * @param _token Address of the token
     * @param _tokenId Token ID to bridge
     */
    function bridgeERC721(address _token, uint256 _tokenId) external;

    /**
     * @notice Function called to bridge ERC1155 tokens
     * @param _token Address of the token
     * @param _tokenId Token ID to bridge
     * @param _amount Amount of tokens to bridge
     */
    function bridgeERC1155(address _token, uint256 _tokenId, uint256 _amount) external;

    /**
     * @notice Function called to withdraw tokens to a user
     * @param _token Address of the token
     * @param _to Address of the user
     * @param _amount Amount of tokens to withdraw
     * @param _requestID ID of the request
     * @param _extra Additional data
     */
    function withdrawToUser(
        address _token,
        address _to,
        uint256 _amount,
        bytes32 _requestID,
        bytes calldata _extra
    ) external;

    /**
     * @notice Function called to withdraw ERC721 tokens to a user
     * @param _token Address of the token
     * @param _to Address of the user
     * @param _tokenId Token ID to withdraw
     * @param _requestID ID of the request
     */
    function withdrawERC721ToUser(
        address _token,
        address _to,
        uint256 _tokenId,
        bytes32 _requestID
    ) external;

    /**
     * @notice Function called to withdraw ERC1155 tokens to a user
     * @param _token Address of the token
     * @param _to Address of the user
     * @param _tokenId Token ID to withdraw
     * @param _amount Amount of tokens to withdraw
     * @param _requestID ID of the request
     */
    function withdrawERC1155ToUser(
        address _token,
        address _to,
        uint256 _tokenId,
        uint256 _amount,
        bytes32 _requestID
    ) external;

    /**
     * @notice Function called to withdraw tokens to multiple users
     * @param _token Address of the token
     * @param _to Addresses of the users
     * @param _amount Amounts of tokens to withdraw
     * @param _requestID IDs of the requests
     * @param _extra Additional data
     */
    function withdrawToUsers(
        address _token,
        address[] calldata _to,
        uint256[] calldata _amount,
        bytes32[] calldata _requestID,
        bytes[] calldata _extra
    ) external;

    /**
     * @notice Function called to withdraw ERC721 tokens to multiple users
     * @param _token Address of the token
     * @param _to Addresses of the users
     * @param _tokenId Token IDs to withdraw
     * @param _requestID IDs of the requests
     */
    function withdrawERC721ToUsers(
        address _token,
        address[] calldata _to,
        uint256[] calldata _tokenId,
        bytes32[] calldata _requestID
    ) external;

    /**
     * @notice Function called to withdraw ERC1155 tokens to multiple users
     * @param _token Address of the token
     * @param _to Addresses of the users
     * @param _tokenId Token IDs to withdraw
     * @param _amount Amounts of tokens to withdraw
     * @param _requestID IDs of the requests
     */
    function withdrawERC1155ToUsers(
        address _token,
        address[] calldata _to,
        uint256[] calldata _tokenId,
        uint256[] calldata _amount,
        bytes32[] calldata _requestID
    ) external;

    /**
     * @notice Returns the bytes32 identifier for the REBALANCER_ROLE
     */
    function REBALANCER_ROLE() external view returns (bytes32); // solhint-disable-line func-name-mixedcase

    /**
     * @notice Returns the address of the wETH contract
     */
    function wETHAddress() external view returns (address payable);

    /**
     * @notice Returns the address of the Meld Farming Manager
     */
    function getFarmingManagerAddress() external view returns (address);
}

File 10 of 12 : IMeldFarming.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";

/**
 * @title Meld Farming interface
 * @notice Interface for the Meld Farming Manager contract as well as the adapters
 * @author MELD team
 */
interface IMeldFarming is IERC165 {
    /**
     * @notice Emitted when an asset is deposited
     * @param asset Address of the asset
     * @param amount Amount deposited
     */
    event Deposited(address indexed asset, uint256 amount);

    /**
     * @notice Emitted when an asset is withdrawn
     * @param asset Address of the asset
     * @param amount Amount withdrawn
     */
    event Withdrawn(address indexed asset, uint256 amount);

    /**
     * @notice Deposits funds into the Meld Farming Manager or the adapter
     * @param _asset Address of the asset to deposit
     * @param _amount Amount to deposit
     * @param _extra Extra data for the deposit
     */
    function deposit(address _asset, uint256 _amount, bytes calldata _extra) external;

    /**
     * @notice Withdraws funds from the Meld Farming Manager or the adapter
     * @param _asset Address of the asset to withdraw
     * @param _amount Amount to withdraw
     * @param _extra Extra data for the withdraw
     * @return Amount withdrawn
     */
    function withdraw(
        address _asset,
        uint256 _amount,
        bytes calldata _extra
    ) external returns (uint256);

    /**
     * @notice Claims rewards from the adapter
     * @param _asset Address of the asset to claim
     * @param _extra Extra data for the claim
     * @param _withdrawOnlyAvailable If true, only claims the rewards up to the available liquidity. If false and there's not enough liquidity, it reverts
     * @return Amount claimed
     */
    function claimRewards(
        address _asset,
        bytes calldata _extra,
        bool _withdrawOnlyAvailable
    ) external returns (uint256);

    /**
     * @notice Returns the total available liquidity for a given asset
     * @param _asset Address of the asset
     * @return Available liquidity
     */
    function getAvailableLiquidity(address _asset) external view returns (uint256);

    /**
     * @notice Returns the amount of rewards available for the `_asset`
     * @param _asset Address of the asset
     * @return Amount of rewards available
     */
    function getRewardsAmount(address _asset) external view returns (uint256);

    /**
     * @notice Returns the address of the Meld Farming Manager
     * @return Address of the Meld Farming Manager
     */
    function meldFarmingManager() external view returns (address);
}

File 11 of 12 : IMeldFarmingManager.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {IMeldFarming} from "./IMeldFarming.sol";
import {IMeldBridgeReceiver} from "./IMeldBridgeReceiver.sol";

/**
 * @title Meld Farming Manager interface
 * @notice Interface for the Meld Farming Manager contract
 * @dev This interface also includes the IMeldFarming interface
 * @author MELD team
 */
interface IMeldFarmingManager is IMeldFarming {
    struct AdapterConfig {
        string adapterIdStr;
        bool enabled;
        bool locked;
        bool exists;
    }

    struct YieldAssetAdapter {
        uint256 yieldDeposit;
        uint256 index;
        uint256 lastTimestampRewardsClaimed;
        bool exists;
    }

    struct YieldAssetConfig {
        uint256 liquidDeposit;
        mapping(uint256 index => address adapterAddress) adapterIndex;
        mapping(address adapterAddress => YieldAssetAdapter) adapters;
        uint256 numAdapters;
    }

    struct RebalancingInfo {
        address asset;
        address adapterAddress;
        uint256 amount;
        RebalanceAction action;
        bytes extra;
    }

    enum RebalanceAction {
        NONE,
        DEPOSIT,
        WITHDRAW,
        REQUEST_WITHDRAW
    }

    /**
     * @notice Emitted when the Meld Bridge Receiver contract is set
     * @param bridge Address of the Meld Bridge Receiver contract
     */
    event BridgeSet(address indexed executedBy, address bridge);

    /**
     * @notice Emitted when the treasury address is updated
     * @param executedBy Address that executed the function
     * @param oldTreasury Address of the old treasury
     * @param newTreasury Address of the new treasury
     */
    event TreasuryUpdated(
        address indexed executedBy,
        address indexed oldTreasury,
        address indexed newTreasury
    );

    /**
     * @notice Emitted when a new adapter is added
     * @param executedBy Address that executed the function
     * @param adapterIdStr String ID of the adapter
     * @param adapterAddress Address of the adapter
     * @param locked Boolean indicating if the adapter is locked
     */
    event AdapterAdded(
        address executedBy,
        string indexed adapterIdStr,
        address indexed adapterAddress,
        bool locked
    );

    /**
     * @notice Emitted when an adapter is enabled or disabled
     * @param executedBy Address that executed the function
     * @param adapterAddress Address of the adapter
     * @param enabled Boolean indicating if the adapter is enabled
     */
    event AdapterEnabled(address indexed executedBy, address indexed adapterAddress, bool enabled);

    /**
     * @notice Emitted when an asset is configured with adapters
     * @param executedBy Address that executed the function
     * @param asset Address of the asset
     * @param adapterAddresses Array of adapter addresses
     */
    event AssetConfigSet(
        address indexed executedBy,
        address indexed asset,
        address[] adapterAddresses
    );

    /**
     * @notice Emitted when rewards are claimed
     * @param executedBy Address that executed the function
     * @param asset Address of the asset
     * @param adapterAddress Address of the adapter
     * @param amount Amount claimed
     */
    event RewardsClaimed(
        address indexed executedBy,
        address indexed asset,
        address indexed adapterAddress,
        uint256 amount
    );

    /**
     * @notice Emitted when a rebalance is executed
     * @param executedBy Address that executed the function
     * @param asset Address of the asset
     * @param adapterAddress Address of the adapter
     * @param amount Amount rebalanced
     * @param action Rebalance action. 0: None, 1: Deposit, 2: Withdraw, 3: Request Withdraw
     */
    event Rebalanced(
        address executedBy,
        address indexed asset,
        address indexed adapterAddress,
        uint256 amount,
        RebalanceAction indexed action
    );

    /**
     * @notice Adds a new adapter to the Meld Farming Manager
     * @param _adapterId String ID of the adapter
     * @param _adapterAddress Address of the adapter
     * @param _locked Boolean indicating if the adapter is locked
     */
    function addAdapter(string memory _adapterId, address _adapterAddress, bool _locked) external;

    /**
     * @notice Enables or disables an adapter
     * @param _adapterAddress Address of the adapter
     * @param _enabled Boolean indicating if the adapter is enabled
     */
    function setAdapterEnabled(address _adapterAddress, bool _enabled) external;

    /**
     * @notice Configures an asset with adapters
     * @dev The list of adapters will be the new one, so any previous configuration will be overwritten
     * @dev To remove all adapters, pass an empty array
     * @dev It is needed to call this function even if no adapters will be used for the asset
     * @param _asset Address of the asset
     * @param _adaptersAddresses Array of adapter addresses
     */
    function configAsset(address _asset, address[] memory _adaptersAddresses) external;

    /**
     * @notice Sets the treasury address that will receive the rewards
     * @param _treasury Address of the treasury
     */
    function setTreasury(address _treasury) external;

    /**
     * @notice Moves funds between the adapters and the Meld Farming Manager
     * @param _rebalanceInfo Array of RebalancingInfo, indicating the asset, adapter, amount and action
     */
    function rebalance(RebalancingInfo[] calldata _rebalanceInfo) external;

    /**
     * @notice Returns the adapter address for a given index
     * @param _index Index of the adapter
     * @return Adapter address
     */
    function adapterAddresses(uint256 _index) external view returns (address);

    /**
     * @notice Returns the number of adapters
     * @return Number of adapters
     */
    function numAdapters() external view returns (uint256);

    /**
     * @notice Returns the Meld Bridge Receiver contract address
     * @return Meld Bridge Receiver contract address
     */
    function bridge() external view returns (IMeldBridgeReceiver);

    /**
     * @notice Returns the treasury address
     * @return Treasury address
     */
    function treasury() external view returns (address);

    /**
     * @notice Returns the adapter configuration for a given ID
     * @param _adapterAddress Address of the adapter
     * @return Adapter configuration
     */
    function getAdapter(address _adapterAddress) external view returns (AdapterConfig memory);

    /**
     * @notice Returns the adapter configuration for all adapters
     * @return Array of every Adapter configuration
     */
    function getAllAdapters() external view returns (AdapterConfig[] memory);

    /**
     * @notice Returns the asset configuration for a given asset
     * @param _asset Address of the asset
     * @return assetAdapterIds Array of the adapter IDs for each adapter
     * @return assetAdapterAddressess Array of the adapter addresses for each adapter
     * @return yieldDeposit Array of the yield deposit for each adapter
     * @return lastTimestampRewardsClaimed Array of the last timestamp rewards claimed for each adapter
     * @return liquidDeposit Liquid deposit for the asset
     * @return totalDeposit Total deposit for the asset
     * @return totalAvailableLiquidity Total available liquidity for the asset
     */
    function getYieldAssetConfig(
        address _asset
    )
        external
        view
        returns (
            string[] memory assetAdapterIds,
            address[] memory assetAdapterAddressess,
            uint256[] memory yieldDeposit,
            uint256[] memory lastTimestampRewardsClaimed,
            uint256 liquidDeposit,
            uint256 totalDeposit,
            uint256 totalAvailableLiquidity
        );

    /**
     * @notice Returns the total deposit for a given asset
     * @param _asset Address of the asset
     * @return Total deposit
     */
    function getTotalDeposit(address _asset) external view returns (uint256);
}

File 12 of 12 : Errors.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

/**
 * @title Errors library
 * @notice Defines the error messages emitted by the different contracts of the Meld Bridge
 * @dev Error messages prefix glossary:
 * - MBP: Meld Bridge Panoptic
 * - MBR: Meld Bridge Receiver
 * - MFM: Meld Farming Manager
 * - BYA: Base Yield Adapter
 * @author MELD team
 */
library Errors {
    string public constant INVALID_ARRAY_LENGTH = "Invalid array length";
    string public constant TOKEN_NOT_SUPPORTED = "Token is not supported";
    string public constant REQUEST_ALREADY_PROCESSED = "Request already processed";
    string public constant INVALID_ADDRESS = "Invalid address";
    string public constant INVALID_AMOUNT = "Invalid amount";

    string public constant MBP_REQUEST_NOT_PROCESSED = "MeldBridgePanoptic: Request not processed";
    string public constant MBP_NETWORK_NOT_SUPPORTED =
        "MeldBridgePanoptic: Network is not supported for this token";
    string public constant MBP_INSUFFICIENT_FEE = "MeldBridgePanoptic: Insufficient fee";
    string public constant MBP_TRANSFERRING_FEE_FAILED =
        "MeldBridgePanoptic: Transferring fee failed";
    string public constant MBP_SIGNATURE_EXPIRED = "MeldBridgePanoptic: Signature is expired";

    string public constant MBR_ONLY_WETH_ALLOWED =
        "MeldBridgeReceiver: Only WETH can deposit ETH directly to the contract";
    string public constant MBR_NATIVE_NOT_SUPPORTED =
        "MeldBridgeReceiver: Native Token is not supported";
    string public constant MBR_NATIVE_WRAPPING_FAILED =
        "MeldBridgeReceiver: Native wrapping failed";
    string public constant MBR_NATIVE_TOKEN_NOT_WETH =
        "MeldBridgeReceiver: Native token withdraw is not WETH";

    string public constant MFM_ONLY_BRIDGE_ALLOWED =
        "MeldFarmingManager: Only bridge can call this function";
    string public constant MFM_ADAPTER_ALREADY_EXISTS =
        "MeldFarmingManager: Adapter already exists";
    string public constant MFM_ADAPTER_ADDRESS_ALREADY_EXISTS =
        "MeldFarmingManager: Adapter address already exists";
    string public constant MFM_ADAPTER_DOES_NOT_EXIST =
        "MeldFarmingManager: Adapter does not exist";
    string public constant MFM_ADAPTER_DISABLED = "MeldFarmingManager: Adapter is disabled";
    string public constant MFM_AMOUNT_MISMATCH = "MeldFarmingManager: Amount mismatch";
    string public constant MFM_NOT_ENOUGH_FUNDS = "MeldFarmingManager: Not enough funds";
    string public constant MFM_INVALID_ADAPTER_ID = "MeldFarmingManager: Invalid adapter ID";
    string public constant MFM_NO_ADAPTERS_CONFIGURED =
        "MeldFarmingManager: No adapters configured";
    string public constant MFM_INVALID_ADAPTER_MFM =
        "MeldFarmingManager: Invalid adapter MeldFarmingManager address";
    string public constant MFM_ADAPTER_IS_NOT_MELD_FARMING =
        "MeldFarmingManager: Adapter does not implement IMeldFarming";

    string public constant RT_NO_TOKENS_TO_RESCUE = "RescueTokens: No tokens to rescue";
    string public constant RT_RESCUER_NOT_OWNER =
        "RescueTokens: Contract is not the owner of the token";

    string public constant BYA_ONLY_FARMING_MANAGER_ALLOWED =
        "BaseYieldAdapter: Only MeldFarmingManager can call this function";

    string public constant AAVE_ADAPTER_INCONSISTENT_ATOKEN_BALANCE =
        "AaveAdapter: Inconsistent aToken balance";
    string public constant AAVE_ADAPTER_INVALID_WITHDRAWN_AMOUNT =
        "AaveAdapter: Invalid withdrawn amount";

    string public constant GOGOPOOL_ONLY_WAVAX_ALLOWED = "GoGoPoolAdapter: Only WAVAX is allowed";
    string public constant GOGOPOOL_AVAX_RECEIVED_OUTSIDE_WINDOW =
        "GoGoPoolAdapter: AVAX received outside window";
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "evmVersion": "shanghai",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_bridge","type":"address"},{"internalType":"address","name":"_treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"executedBy","type":"address"},{"indexed":true,"internalType":"string","name":"adapterIdStr","type":"string"},{"indexed":true,"internalType":"address","name":"adapterAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"locked","type":"bool"}],"name":"AdapterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executedBy","type":"address"},{"indexed":true,"internalType":"address","name":"adapterAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"AdapterEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executedBy","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"address[]","name":"adapterAddresses","type":"address[]"}],"name":"AssetConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executedBy","type":"address"},{"indexed":false,"internalType":"address","name":"bridge","type":"address"}],"name":"BridgeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"executedBy","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"adapterAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"enum IMeldFarmingManager.RebalanceAction","name":"action","type":"uint8"}],"name":"Rebalanced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executedBy","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"adapterAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executedBy","type":"address"},{"indexed":true,"internalType":"address","name":"oldTreasury","type":"address"},{"indexed":true,"internalType":"address","name":"newTreasury","type":"address"}],"name":"TreasuryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"adapterAddresses","outputs":[{"internalType":"address","name":"adapterAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_adapterId","type":"string"},{"internalType":"address","name":"_adapterAddress","type":"address"},{"internalType":"bool","name":"_locked","type":"bool"}],"name":"addAdapter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"contract IMeldBridgeReceiver","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"bytes","name":"_extra","type":"bytes"},{"internalType":"bool","name":"_withdrawOnlyAvailable","type":"bool"}],"name":"claimRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"address[]","name":"_adaptersAddresses","type":"address[]"}],"name":"configAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_adapterAddress","type":"address"}],"name":"getAdapter","outputs":[{"components":[{"internalType":"string","name":"adapterIdStr","type":"string"},{"internalType":"bool","name":"enabled","type":"bool"},{"internalType":"bool","name":"locked","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"internalType":"struct IMeldFarmingManager.AdapterConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllAdapters","outputs":[{"components":[{"internalType":"string","name":"adapterIdStr","type":"string"},{"internalType":"bool","name":"enabled","type":"bool"},{"internalType":"bool","name":"locked","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"internalType":"struct IMeldFarmingManager.AdapterConfig[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getAvailableLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getRewardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getTotalDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getYieldAssetConfig","outputs":[{"internalType":"string[]","name":"assetAdapterIds","type":"string[]"},{"internalType":"address[]","name":"assetAdapterAddresses","type":"address[]"},{"internalType":"uint256[]","name":"yieldDeposit","type":"uint256[]"},{"internalType":"uint256[]","name":"lastTimestampRewardsClaimed","type":"uint256[]"},{"internalType":"uint256","name":"liquidDeposit","type":"uint256"},{"internalType":"uint256","name":"totalDeposit","type":"uint256"},{"internalType":"uint256","name":"totalAvailableLiquidity","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"meldFarmingManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numAdapters","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"adapterAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum IMeldFarmingManager.RebalanceAction","name":"action","type":"uint8"},{"internalType":"bytes","name":"extra","type":"bytes"}],"internalType":"struct IMeldFarmingManager.RebalancingInfo[]","name":"_rebalanceInfo","type":"tuple[]"}],"name":"rebalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_adapterAddress","type":"address"},{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setAdapterEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_extra","type":"bytes"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]

608060405234801562000010575f80fd5b5060405162003bdf38038062003bdf83398101604081905262000033916200016c565b600480546001600160a01b0319166001600160a01b03841690811790915560405190815233907fc0634c245ce7b7b309744c30c030a783629555dc9f0c2c4cb54bdc9d9812d6209060200160405180910390a2620000918162000099565b5050620001f0565b60408051808201909152600f81526e496e76616c6964206164647265737360881b60208201526001600160a01b038216620000f25760405162461bcd60e51b8152600401620000e99190620001a2565b60405180910390fd5b506005546040516001600160a01b0380841692169033907f23c12d5579081c5f1077c04a6b1c114d0f3de239e81a436836d30ecb099ffa13905f90a4600580546001600160a01b0319166001600160a01b0392909216919091179055565b80516001600160a01b038116811462000167575f80fd5b919050565b5f80604083850312156200017e575f80fd5b620001898362000150565b9150620001996020840162000150565b90509250929050565b5f602080835283518060208501525f5b81811015620001d057858101830151858201604001528201620001b2565b505f604082860101526040601f19601f8301168501019250505092915050565b6139e180620001fe5f395ff3fe608060405234801561000f575f80fd5b5060043610610127575f3560e01c8063b732a36e116100a9578063dbe934511161006e578063dbe93451146102a1578063dff07da2146102b4578063e31ada97146102da578063e78cea92146102ef578063f0f4426014610302575f80fd5b8063b732a36e14610242578063b74d3b1514610255578063c157c57c14610268578063c876d28114610288578063c9637cc31461029b575f80fd5b8063776941a2116100ef578063776941a2146101d85780637c917038146101eb578063857184d1146102135780638ba1b28414610226578063a87461b514610239575f80fd5b806301ffc9a71461012b578063266e2bd81461016457806331f092651461018557806349bdc2b81461019857806361d027b3146101ad575b5f80fd5b61014f610139366004612e69565b6001600160e01b03191663fb9b90f960e01b1490565b60405190151581526020015b60405180910390f35b610177610172366004612ebe565b610315565b60405190815260200161015b565b610177610193366004612f1d565b6103fc565b6101ab6101a6366004612f1d565b610802565b005b6005546101c0906001600160a01b031681565b6040516001600160a01b03909116815260200161015b565b6101ab6101e6366004612fb8565b6108bf565b6101c06101f9366004613079565b5f602081905290815260409020546001600160a01b031681565b610177610221366004612ebe565b611188565b6101ab6102343660046130a8565b6111f1565b61017760025481565b6101776102503660046130df565b611371565b6101ab610263366004613142565b6116e2565b61027b610276366004612ebe565b611b26565b60405161015b9190613281565b6101ab610296366004613293565b611c30565b306101c0565b6101776102af366004612ebe565b612329565b6102c76102c2366004612ebe565b6123e1565b60405161015b9796959493929190613373565b6102e2612793565b60405161015b9190613427565b6004546101c0906001600160a01b031681565b6101ab610310366004612ebe565b612928565b6001600160a01b0381165f908152600360205260408120805482805b83600301548110156103f2575f818152600185810160209081526040808420546001600160a01b0316808552918390529092200154909250610100900460ff166103ea576040516304cdc57b60e31b81526001600160a01b03878116600483015283169063266e2bd890602401602060405180830381865afa1580156103b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103dd9190613489565b6103e790846134b4565b92505b600101610331565b5090949350505050565b600454604080516060810190915260368082525f926001600160a01b0316331491906138eb60208301399061044d5760405162461bcd60e51b815260040161044491906134cd565b60405180910390fd5b506001600160a01b0385165f9081526003602052604090208054859081111561079957815461047c90826134df565b5f8084559091505b8260030154811015610758575f818152600180850160209081526040808420546001600160a01b0316808552600288018352818520939092528084208151608081019092528054929485949390929190829082906104e1906134f2565b80601f016020809104026020016040519081016040528092919081815260200182805461050d906134f2565b80156105585780601f1061052f57610100808354040283529160200191610558565b820191905f5260205f20905b81548152906001019060200180831161053b57829003601f168201915b50505091835250506001919091015460ff80821615156020808501919091526101008304821615156040850152620100009092041615156060909201919091528101519091506105ab5750505050610750565b6040516304cdc57b60e31b81526001600160a01b038d811660048301525f919085169063266e2bd890602401602060405180830381865afa1580156105f2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106169190613489565b9050805f03610629575050505050610750565b8681106106c857836001600160a01b03166331f092658e898e8e6040518563ffffffff1660e01b8152600401610662949392919061354c565b6020604051808303815f875af115801561067e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106a29190613489565b5086835f015f8282546106b591906134df565b909155505f975061075895505050505050565b836001600160a01b03166331f092658e838e8e6040518563ffffffff1660e01b81526004016106fa949392919061354c565b6020604051808303815f875af1158015610716573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073a9190613489565b505f835561074881886134df565b965050505050505b600101610484565b50805f1460405180606001604052806024815260200161386260249139906107935760405162461bcd60e51b815260040161044491906134cd565b506107b1565b80825f015f8282546107ab91906134df565b90915550505b866001600160a01b03167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5876040516107ec91815260200190565b60405180910390a285925050505b949350505050565b600454604080516060810190915260368082526001600160a01b039092163314916138eb6020830139906108495760405162461bcd60e51b815260040161044491906134cd565b506001600160a01b0384165f9081526003602052604081208054909185918391906108759084906134b4565b90915550506040518481526001600160a01b038616907f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c49060200160405180910390a25050505050565b60048054604080516358976a2f60e11b815290516001600160a01b039092169263b12ed45e9282820192602092908290030181865afa158015610904573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109289190613489565b600480546040516312d9a6ad60e01b81529182018390523360248301526001600160a01b0316906312d9a6ad906044015f6040518083038186803b15801561096e575f80fd5b505afa158015610980573d5f803e3d5ffd5b5050506001600160a01b0384165f90815260036020819052604082208551918101549093506109af91906134b4565b6001600160401b038111156109c6576109c6612f74565b6040519080825280602002602001820160405280156109ef578160200160208202803683370190505b5090505f610a1c60405180608001604052805f81526020015f81526020015f81526020015f151581525090565b6003840154600454610a389089906001600160a01b03166129fa565b5f5b8751811015610c425760015f898381518110610a5857610a5861357d565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2060010160029054906101000a900460ff166040518060600160405280602a8152602001613838602a913990610ac75760405162461bcd60e51b815260040161044491906134cd565b50878181518110610ada57610ada61357d565b6020908102919091018101516001600160a01b0381165f9081526002808a01845260409182902082516080810184528154815260018201549581019590955290810154918401919091526003015460ff161580156060840152909550909350610b79578385846020015181518110610b5457610b5461357d565b60200260200101906001600160a01b031690816001600160a01b031681525050610c3a565b83858381518110610b8c57610b8c61357d565b6001600160a01b039283166020918202929092018101919091525f84815260018981018352604080832080546001600160a01b031916958a1695861790558051608081018252838152808501888152818301858152606083018581529786526002808f019097529290942090518155925191830191909155519181019190915590516003909101805460ff1916911515919091179055610c2c89856129fa565b81610c3681613591565b9250505b600101610a3a565b50876001600160a01b0316336001600160a01b03167f78a6368a6b0bcb8891b5e0283fa8cb2add1faf3bd518bba5d2954cf46d3c1c1989604051610c8691906135a9565b60405180910390a3805f03610c9f575050505050505050565b5f80805b8760030154811015611153575f6001600160a01b0316878281518110610ccb57610ccb61357d565b60200260200101516001600160a01b03160361114b575f81815260208181526040808320546001600160a01b03168084526001909252808320815160808101909252805492939282908290610d1f906134f2565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4b906134f2565b8015610d965780601f10610d6d57610100808354040283529160200191610d96565b820191905f5260205f20905b815481529060010190602001808311610d7957829003601f168201915b50505091835250506001919091015460ff808216151560208401526101008204811615156040840152620100009091041615156060909101529050610dda81612a95565b5f8a6002015f846001600160a01b03166001600160a01b031681526020019081526020015f205f01549050826001600160a01b03166331f092658f836040518363ffffffff1660e01b8152600401610e559291906001600160a01b0392909216825260208201526060604082018190525f9082015260800190565b6020604051808303815f875af1158015610e71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e959190613489565b8b5f015f828254610ea691906134b4565b9091555050604051635b9951b760e11b81526001600160a01b038f81166004830152606060248301525f60648301819052604483015284169063b732a36e906084016020604051808303815f875af1158015610f04573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f289190613489565b9450610f3485876134b4565b9550826001600160a01b03168e6001600160a01b0316336001600160a01b03167f5637d7f962248a7f05a7ab69eec6446e31f3d0a299d997f135a65c62806e789188604051610f8591815260200190565b60405180910390a46001600160a01b0383165f9081526002808d01602052604082208281556001810183905590810191909155600301805460ff191690555b83871115611147575f8a610fd960018a6134df565b81518110610fe957610fe961357d565b60200260200101516001600160a01b03160315611135578961100c6001896134df565b8151811061101c5761101c61357d565b60200260200101518a85815181106110365761103661357d565b60200260200101906001600160a01b031690816001600160a01b031681525050838b6002015f8c878151811061106e5761106e61357d565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f20600101819055508984815181106110ae576110ae61357d565b60200260200101518b6001015f8681526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505f8a6001896110fb91906134df565b8151811061110b5761110b61357d565b6001600160a01b03909216602092830291909101909101528661112d816135bb565b975050611147565b8661113f816135bb565b975050610fc4565b5050505b600101610ca3565b5088516003880155811561117b5760055461117b906001600160a01b038c8116911684612ad1565b505050505050505b505050565b6001600160a01b0381165f908152600360205260408120805482805b83600301548110156103f2575f8181526001850160209081526040808320546001600160a01b031680845260028801909252909120549092506111e790846134b4565b92506001016111a4565b60048054604080516358976a2f60e11b815290516001600160a01b039092169263b12ed45e9282820192602092908290030181865afa158015611236573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061125a9190613489565b600480546040516312d9a6ad60e01b81529182018390523360248301526001600160a01b0316906312d9a6ad906044015f6040518083038186803b1580156112a0575f80fd5b505afa1580156112b2573d5f803e3d5ffd5b5050506001600160a01b0384165f9081526001602081815260409283902091820154835160608101909452602a80855292945060ff620100009091041692919061383890830139906113175760405162461bcd60e51b815260040161044491906134cd565b5060018101805460ff19168415159081179091556040519081526001600160a01b0385169033907f62b76bfed3e25f37ab2de632c70377774c2945b0ff78df201c44268cc04a73ce9060200160405180910390a350505050565b5f60045f9054906101000a90046001600160a01b03166001600160a01b031663490b48f86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113c2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113e69190613489565b600480546040516312d9a6ad60e01b81529182018390523360248301526001600160a01b0316906312d9a6ad906044015f6040518083038186803b15801561142c575f80fd5b505afa15801561143e573d5f803e3d5ffd5b505050505f60035f886001600160a01b03166001600160a01b031681526020019081526020015f2090505f8160030154116040518060600160405280602a81526020016138c1602a9139906114a65760405162461bcd60e51b815260040161044491906134cd565b505f805b82600301548110156116bc575f818152600180850160209081526040808420546001600160a01b031680855260028801835281852093909252808420815160808101909252805492949282908290611501906134f2565b80601f016020809104026020016040519081016040528092919081815260200182805461152d906134f2565b80156115785780601f1061154f57610100808354040283529160200191611578565b820191905f5260205f20905b81548152906001019060200180831161155b57829003601f168201915b50505091835250506001919091015460ff80821615156020808501919091526101008304821615156040850152620100009092041615156060909201919091528101519091506115ca575050506116b4565b5f836001600160a01b031663b732a36e8e8e8e8e6040518563ffffffff1660e01b81526004016115fd94939291906135d0565b6020604051808303815f875af1158015611619573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061163d9190613489565b905080156116585761164f81876134b4565b42600285015595505b836001600160a01b03168d6001600160a01b0316336001600160a01b03167f5637d7f962248a7f05a7ab69eec6446e31f3d0a299d997f135a65c62806e7891846040516116a791815260200190565b60405180910390a4505050505b6001016114aa565b506005546116d7906001600160a01b038a8116911683612ad1565b979650505050505050565b60048054604080516358976a2f60e11b815290516001600160a01b039092169263b12ed45e9282820192602092908290030181865afa158015611727573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061174b9190613489565b600480546040516312d9a6ad60e01b81529182018390523360248301526001600160a01b0316906312d9a6ad906044015f6040518083038186803b158015611791575f80fd5b505afa1580156117a3573d5f803e3d5ffd5b505050505f84511160405180606001604052806026815260200161394860269139906117e25760405162461bcd60e51b815260040161044491906134cd565b5060015f846001600160a01b03166001600160a01b031681526020019081526020015f2060010160029054906101000a900460ff16156040518060600160405280602a81526020016137eb602a91399061184f5760405162461bcd60e51b815260040161044491906134cd565b5060408051808201909152600f81526e496e76616c6964206164647265737360881b60208201526001600160a01b03841661189d5760405162461bcd60e51b815260040161044491906134cd565b506040516301ffc9a760e01b815263fb9b90f960e01b600482015283906001600160a01b038216906301ffc9a790602401602060405180830381865afa1580156118e9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061190d9190613607565b6040518060600160405280603b8152602001613886603b9139906119445760405162461bcd60e51b815260040161044491906134cd565b50306001600160a01b0316816001600160a01b031663c9637cc36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561198b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119af9190613622565b6001600160a01b0316146040518060600160405280603e815260200161396e603e9139906119f05760405162461bcd60e51b815260040161044491906134cd565b50604080516080810182528681526001602080830182905286151583850152606083018290526001600160a01b0388165f9081529190529190912081518190611a399082613688565b50602082810151600190920180546040808601516060909601511515620100000262ff0000199615156101000261ff00199615159690961661ffff1990931692909217949094179490941693909317909255600280545f9081529283905290822080546001600160a01b0388166001600160a01b0319909116179055805491611ac183613591565b9190505550836001600160a01b031685604051611ade9190613747565b604080519182900382203383528615156020840152917ffeb85e1b59a8e75692b36f1d1165bbd12f7b43da4c5b8281e2fba4ba1315a963910160405180910390a35050505050565b6040805160808101825260608082525f602083018190529282018390528101919091526001600160a01b0382165f9081526001602052604090819020815160808101909252805482908290611b7a906134f2565b80601f0160208091040260200160405190810160405280929190818152602001828054611ba6906134f2565b8015611bf15780601f10611bc857610100808354040283529160200191611bf1565b820191905f5260205f20905b815481529060010190602001808311611bd457829003601f168201915b50505091835250506001919091015460ff8082161515602084015261010082048116151560408401526201000090910416151560609091015292915050565b6004805460408051630921691f60e31b815290516001600160a01b039092169263490b48f89282820192602092908290030181865afa158015611c75573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c999190613489565b600480546040516312d9a6ad60e01b81529182018390523360248301526001600160a01b0316906312d9a6ad906044015f6040518083038186803b158015611cdf575f80fd5b505afa158015611cf1573d5f803e3d5ffd5b5050604080518082019091526014815273092dcecc2d8d2c840c2e4e4c2f240d8cadccee8d60631b602082015291505082611d3f5760405162461bcd60e51b815260040161044491906134cd565b505f5b828110156123235736848483818110611d5d57611d5d61357d565b9050602002810190611d6f9190613762565b9050611e7560015f611d876040850160208601612ebe565b6001600160a01b03166001600160a01b031681526020019081526020015f206040518060800160405290815f82018054611dc0906134f2565b80601f0160208091040260200160405190810160405280929190818152602001828054611dec906134f2565b8015611e375780601f10611e0e57610100808354040283529160200191611e37565b820191905f5260205f20905b815481529060010190602001808311611e1a57829003601f168201915b50505091835250506001919091015460ff80821615156020840152610100820481161515604084015262010000909104161515606090910152612a95565b5f611e866040830160208401612ebe565b90505f600381611e996020860186612ebe565b6001600160a01b0316815260208101919091526040015f2090506001611ec5608085016060860161378a565b6003811115611ed657611ed6613776565b0361200857805f0154836040013511156040518060600160405280602481526020016138626024913990611f1d5760405162461bcd60e51b815260040161044491906134cd565b506001600160a01b0382166349bdc2b8611f3a6020860186612ebe565b6040860135611f4c60808801886137a8565b6040518563ffffffff1660e01b8152600401611f6b949392919061354c565b5f604051808303815f87803b158015611f82575f80fd5b505af1158015611f94573d5f803e3d5ffd5b505050508260400135815f015f828254611fae91906134df565b90915550506040830180359060028301905f90611fce9060208801612ebe565b6001600160a01b03166001600160a01b031681526020019081526020015f205f015f828254611ffd91906134b4565b909155506122899050565b600261201a608085016060860161378a565b600381111561202b5761202b613776565b036121e657600281015f6120456040860160208701612ebe565b6001600160a01b03166001600160a01b031681526020019081526020015f205f01548360400135111560405180606001604052806024815260200161386260249139906120a55760405162461bcd60e51b815260040161044491906134cd565b505f6001600160a01b0383166331f092656120c36020870187612ebe565b60408701356120d560808901896137a8565b6040518563ffffffff1660e01b81526004016120f4949392919061354c565b6020604051808303815f875af1158015612110573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121349190613489565b90508360400135811460405180606001604052806023815260200161381560239139906121745760405162461bcd60e51b815260040161044491906134cd565b508360400135825f015f82825461218b91906134b4565b90915550506040840180359060028401905f906121ab9060208901612ebe565b6001600160a01b03166001600160a01b031681526020019081526020015f205f015f8282546121da91906134df565b90915550612289915050565b60036121f8608085016060860161378a565b600381111561220957612209613776565b03612289576001600160a01b038216630f51fc2661222a6020860186612ebe565b604086013561223c60808801886137a8565b6040518563ffffffff1660e01b815260040161225b949392919061354c565b5f604051808303815f87803b158015612272575f80fd5b505af1158015612284573d5f803e3d5ffd5b505050505b612299608084016060850161378a565b60038111156122aa576122aa613776565b6122ba6040850160208601612ebe565b6001600160a01b03166122d06020860186612ebe565b604080513381528188013560208201526001600160a01b0392909216917fa742c9be7d2f68dbf5362a00c7acaf4297dc2764f3d57430595235925d76afe6910160405180910390a4505050600101611d42565b50505050565b6001600160a01b0381165f9081526003602052604081208180805b83600301548110156103f2575f8181526001850160205260409081902054905163dbe9345160e01b81526001600160a01b0388811660048301529091169250829063dbe9345190602401602060405180830381865afa1580156123a9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123cd9190613489565b6123d790846134b4565b9250600101612344565b6001600160a01b0381165f908152600360208190526040909120908101548154606092839283928392909182918291806001600160401b0381111561242857612428612f74565b60405190808252806020026020018201604052801561245b57816020015b60608152602001906001900390816124465790505b509850806001600160401b0381111561247657612476612f74565b60405190808252806020026020018201604052801561249f578160200160208202803683370190505b509650806001600160401b038111156124ba576124ba612f74565b6040519080825280602002602001820160405280156124e3578160200160208202803683370190505b509550806001600160401b038111156124fe576124fe612f74565b604051908082528060200260200182016040528015612527578160200160208202803683370190505b5097505f61255460405180608001604052805f81526020015f81526020015f81526020015f151581525090565b5f5b83811015612783575f818152600180870160209081526040808420546001600160a01b031680855292909152909120805491945090612594906134f2565b80601f01602080910402602001604051908101604052809291908181526020018280546125c0906134f2565b801561260b5780601f106125e25761010080835404028352916020019161260b565b820191905f5260205f20905b8154815290600101906020018083116125ee57829003601f168201915b50505050508c82815181106126225761262261357d565b6020908102919091018101919091526001600160a01b0384165f9081526002808801835260409182902082516080810184528154808252600183015495820195909552918101549282019290925260039091015460ff16151560608201528b519093508b90839081106126975761269761357d565b602090810291909101015281516126ae90886134b4565b6040516304cdc57b60e31b81526001600160a01b038f811660048301529198509084169063266e2bd890602401602060405180830381865afa1580156126f6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061271a9190613489565b61272490876134b4565b9550828b82815181106127395761273961357d565b60200260200101906001600160a01b031690816001600160a01b03168152505081604001518982815181106127705761277061357d565b6020908102919091010152600101612556565b5050505050919395979092949650565b60605f6002546001600160401b038111156127b0576127b0612f74565b60405190808252806020026020018201604052801561280157816020015b6040805160808101825260608082525f60208084018290529383018190529082015282525f199092019101816127ce5790505b5090505f5b600254811015612922575f81815260208181526040808320546001600160a01b0316835260019091529081902081516080810190925280548290829061284b906134f2565b80601f0160208091040260200160405190810160405280929190818152602001828054612877906134f2565b80156128c25780601f10612899576101008083540402835291602001916128c2565b820191905f5260205f20905b8154815290600101906020018083116128a557829003601f168201915b50505091835250506001919091015460ff80821615156020840152610100820481161515604084015262010000909104161515606090910152825183908390811061290f5761290f61357d565b6020908102919091010152600101612806565b50919050565b60048054604080516358976a2f60e11b815290516001600160a01b039092169263b12ed45e9282820192602092908290030181865afa15801561296d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129919190613489565b600480546040516312d9a6ad60e01b81529182018390523360248301526001600160a01b0316906312d9a6ad906044015f6040518083038186803b1580156129d7575f80fd5b505afa1580156129e9573d5f803e3d5ffd5b505050506129f682612b34565b5050565b604051636eb1769f60e11b81523060048201526001600160a01b0382811660248301525f919084169063dd62ed3e90604401602060405180830381865afa158015612a47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a6b9190613489565b90505f612a79825f196134df565b90508015612323576123236001600160a01b0385168483612bdf565b806020015160405180606001604052806027815260200161392160279139906129f65760405162461bcd60e51b815260040161044491906134cd565b6040516001600160a01b03831660248201526044810182905261118390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612c89565b60408051808201909152600f81526e496e76616c6964206164647265737360881b60208201526001600160a01b038216612b815760405162461bcd60e51b815260040161044491906134cd565b506005546040516001600160a01b0380841692169033907f23c12d5579081c5f1077c04a6b1c114d0f3de239e81a436836d30ecb099ffa13905f90a4600580546001600160a01b0319166001600160a01b0392909216919091179055565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa158015612c2c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c509190613489565b90506123238463095ea7b360e01b85612c6986866134b4565b6040516001600160a01b0390921660248301526044820152606401612afd565b5f612cdd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612d5c9092919063ffffffff16565b905080515f1480612cfd575080806020019051810190612cfd9190613607565b6111835760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610444565b60606107fa84845f85855f80866001600160a01b03168587604051612d819190613747565b5f6040518083038185875af1925050503d805f8114612dbb576040519150601f19603f3d011682016040523d82523d5f602084013e612dc0565b606091505b50915091506116d78783838760608315612e3a5782515f03612e33576001600160a01b0385163b612e335760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610444565b50816107fa565b6107fa8383815115612e4f5781518083602001fd5b8060405162461bcd60e51b815260040161044491906134cd565b5f60208284031215612e79575f80fd5b81356001600160e01b031981168114612e90575f80fd5b9392505050565b6001600160a01b0381168114612eab575f80fd5b50565b8035612eb981612e97565b919050565b5f60208284031215612ece575f80fd5b8135612e9081612e97565b5f8083601f840112612ee9575f80fd5b5081356001600160401b03811115612eff575f80fd5b602083019150836020828501011115612f16575f80fd5b9250929050565b5f805f8060608587031215612f30575f80fd5b8435612f3b81612e97565b93506020850135925060408501356001600160401b03811115612f5c575f80fd5b612f6887828801612ed9565b95989497509550505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715612fb057612fb0612f74565b604052919050565b5f8060408385031215612fc9575f80fd5b8235612fd481612e97565b91506020838101356001600160401b0380821115612ff0575f80fd5b818601915086601f830112613003575f80fd5b81358181111561301557613015612f74565b8060051b9150613026848301612f88565b818152918301840191848101908984111561303f575f80fd5b938501935b83851015613069578435925061305983612e97565b8282529385019390850190613044565b8096505050505050509250929050565b5f60208284031215613089575f80fd5b5035919050565b8015158114612eab575f80fd5b8035612eb981613090565b5f80604083850312156130b9575f80fd5b82356130c481612e97565b915060208301356130d481613090565b809150509250929050565b5f805f80606085870312156130f2575f80fd5b84356130fd81612e97565b935060208501356001600160401b03811115613117575f80fd5b61312387828801612ed9565b909450925050604085013561313781613090565b939692955090935050565b5f805f60608486031215613154575f80fd5b83356001600160401b038082111561316a575f80fd5b818601915086601f83011261317d575f80fd5b813560208282111561319157613191612f74565b6131a3601f8301601f19168201612f88565b925081835288818386010111156131b8575f80fd5b81818501828501375f8183850101528296506131d5818901612eae565b9550505050506131e76040850161309d565b90509250925092565b5f5b8381101561320a5781810151838201526020016131f2565b50505f910152565b5f81518084526132298160208601602086016131f0565b601f01601f19169290920160200192915050565b5f8151608084526132516080850182613212565b90506020830151151560208501526040830151151560408501526060830151151560608501528091505092915050565b602081525f612e90602083018461323d565b5f80602083850312156132a4575f80fd5b82356001600160401b03808211156132ba575f80fd5b818501915085601f8301126132cd575f80fd5b8135818111156132db575f80fd5b8660208260051b85010111156132ef575f80fd5b60209290920196919550909350505050565b5f815180845260208085019450602084015f5b838110156133395781516001600160a01b031687529582019590820190600101613314565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561333957815187529582019590820190600101613357565b60e080825288519082018190525f90610100600582901b8401810191908401906020808d01855b838110156133c85760ff198887030185526133b6868351613212565b9550938201939082019060010161339a565b505050505082810360208401526133df818a613301565b905082810360408401526133f38189613344565b905082810360608401526134078188613344565b6080840196909652505060a081019290925260c090910152949350505050565b5f60208083016020845280855180835260408601915060408160051b8701019250602087015f5b8281101561347c57603f1988860301845261346a85835161323d565b9450928501929085019060010161344e565b5092979650505050505050565b5f60208284031215613499575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156134c7576134c76134a0565b92915050565b602081525f612e906020830184613212565b818103818111156134c7576134c76134a0565b600181811c9082168061350657607f821691505b60208210810361292257634e487b7160e01b5f52602260045260245ffd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60018060a01b0385168152836020820152606060408201525f613573606083018486613524565b9695505050505050565b634e487b7160e01b5f52603260045260245ffd5b5f600182016135a2576135a26134a0565b5060010190565b602081525f612e906020830184613301565b5f816135c9576135c96134a0565b505f190190565b6001600160a01b03851681526060602082018190525f906135f49083018587613524565b9050821515604083015295945050505050565b5f60208284031215613617575f80fd5b8151612e9081613090565b5f60208284031215613632575f80fd5b8151612e9081612e97565b601f82111561118357805f5260205f20601f840160051c810160208510156136625750805b601f840160051c820191505b81811015613681575f815560010161366e565b5050505050565b81516001600160401b038111156136a1576136a1612f74565b6136b5816136af84546134f2565b8461363d565b602080601f8311600181146136e8575f84156136d15750858301515b5f19600386901b1c1916600185901b17855561373f565b5f85815260208120601f198616915b82811015613716578886015182559484019460019091019084016136f7565b508582101561373357878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b5f82516137588184602087016131f0565b9190910192915050565b5f8235609e19833603018112613758575f80fd5b634e487b7160e01b5f52602160045260245ffd5b5f6020828403121561379a575f80fd5b813560048110612e90575f80fd5b5f808335601e198436030181126137bd575f80fd5b8301803591506001600160401b038211156137d6575f80fd5b602001915036819003821315612f16575f80fdfe4d656c644661726d696e674d616e616765723a204164617074657220616c7265616479206578697374734d656c644661726d696e674d616e616765723a20416d6f756e74206d69736d617463684d656c644661726d696e674d616e616765723a204164617074657220646f6573206e6f742065786973744d656c644661726d696e674d616e616765723a204e6f7420656e6f7567682066756e64734d656c644661726d696e674d616e616765723a204164617074657220646f6573206e6f7420696d706c656d656e7420494d656c644661726d696e674d656c644661726d696e674d616e616765723a204e6f20616461707465727320636f6e666967757265644d656c644661726d696e674d616e616765723a204f6e6c79206272696467652063616e2063616c6c20746869732066756e6374696f6e4d656c644661726d696e674d616e616765723a20416461707465722069732064697361626c65644d656c644661726d696e674d616e616765723a20496e76616c696420616461707465722049444d656c644661726d696e674d616e616765723a20496e76616c69642061646170746572204d656c644661726d696e674d616e616765722061646472657373a26469706673582212205ee36ba130fb8af85ab458a0a570c8006f53cfae391a19a35fc832c709683d8364736f6c63430008180033000000000000000000000000c9ced87b7073297ceb12453c0d65329d496fc0b4000000000000000000000000303b3d643753b86f2045f08b1df0f910f42cb200

Deployed Bytecode

0x608060405234801561000f575f80fd5b5060043610610127575f3560e01c8063b732a36e116100a9578063dbe934511161006e578063dbe93451146102a1578063dff07da2146102b4578063e31ada97146102da578063e78cea92146102ef578063f0f4426014610302575f80fd5b8063b732a36e14610242578063b74d3b1514610255578063c157c57c14610268578063c876d28114610288578063c9637cc31461029b575f80fd5b8063776941a2116100ef578063776941a2146101d85780637c917038146101eb578063857184d1146102135780638ba1b28414610226578063a87461b514610239575f80fd5b806301ffc9a71461012b578063266e2bd81461016457806331f092651461018557806349bdc2b81461019857806361d027b3146101ad575b5f80fd5b61014f610139366004612e69565b6001600160e01b03191663fb9b90f960e01b1490565b60405190151581526020015b60405180910390f35b610177610172366004612ebe565b610315565b60405190815260200161015b565b610177610193366004612f1d565b6103fc565b6101ab6101a6366004612f1d565b610802565b005b6005546101c0906001600160a01b031681565b6040516001600160a01b03909116815260200161015b565b6101ab6101e6366004612fb8565b6108bf565b6101c06101f9366004613079565b5f602081905290815260409020546001600160a01b031681565b610177610221366004612ebe565b611188565b6101ab6102343660046130a8565b6111f1565b61017760025481565b6101776102503660046130df565b611371565b6101ab610263366004613142565b6116e2565b61027b610276366004612ebe565b611b26565b60405161015b9190613281565b6101ab610296366004613293565b611c30565b306101c0565b6101776102af366004612ebe565b612329565b6102c76102c2366004612ebe565b6123e1565b60405161015b9796959493929190613373565b6102e2612793565b60405161015b9190613427565b6004546101c0906001600160a01b031681565b6101ab610310366004612ebe565b612928565b6001600160a01b0381165f908152600360205260408120805482805b83600301548110156103f2575f818152600185810160209081526040808420546001600160a01b0316808552918390529092200154909250610100900460ff166103ea576040516304cdc57b60e31b81526001600160a01b03878116600483015283169063266e2bd890602401602060405180830381865afa1580156103b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103dd9190613489565b6103e790846134b4565b92505b600101610331565b5090949350505050565b600454604080516060810190915260368082525f926001600160a01b0316331491906138eb60208301399061044d5760405162461bcd60e51b815260040161044491906134cd565b60405180910390fd5b506001600160a01b0385165f9081526003602052604090208054859081111561079957815461047c90826134df565b5f8084559091505b8260030154811015610758575f818152600180850160209081526040808420546001600160a01b0316808552600288018352818520939092528084208151608081019092528054929485949390929190829082906104e1906134f2565b80601f016020809104026020016040519081016040528092919081815260200182805461050d906134f2565b80156105585780601f1061052f57610100808354040283529160200191610558565b820191905f5260205f20905b81548152906001019060200180831161053b57829003601f168201915b50505091835250506001919091015460ff80821615156020808501919091526101008304821615156040850152620100009092041615156060909201919091528101519091506105ab5750505050610750565b6040516304cdc57b60e31b81526001600160a01b038d811660048301525f919085169063266e2bd890602401602060405180830381865afa1580156105f2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106169190613489565b9050805f03610629575050505050610750565b8681106106c857836001600160a01b03166331f092658e898e8e6040518563ffffffff1660e01b8152600401610662949392919061354c565b6020604051808303815f875af115801561067e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106a29190613489565b5086835f015f8282546106b591906134df565b909155505f975061075895505050505050565b836001600160a01b03166331f092658e838e8e6040518563ffffffff1660e01b81526004016106fa949392919061354c565b6020604051808303815f875af1158015610716573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073a9190613489565b505f835561074881886134df565b965050505050505b600101610484565b50805f1460405180606001604052806024815260200161386260249139906107935760405162461bcd60e51b815260040161044491906134cd565b506107b1565b80825f015f8282546107ab91906134df565b90915550505b866001600160a01b03167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5876040516107ec91815260200190565b60405180910390a285925050505b949350505050565b600454604080516060810190915260368082526001600160a01b039092163314916138eb6020830139906108495760405162461bcd60e51b815260040161044491906134cd565b506001600160a01b0384165f9081526003602052604081208054909185918391906108759084906134b4565b90915550506040518481526001600160a01b038616907f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c49060200160405180910390a25050505050565b60048054604080516358976a2f60e11b815290516001600160a01b039092169263b12ed45e9282820192602092908290030181865afa158015610904573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109289190613489565b600480546040516312d9a6ad60e01b81529182018390523360248301526001600160a01b0316906312d9a6ad906044015f6040518083038186803b15801561096e575f80fd5b505afa158015610980573d5f803e3d5ffd5b5050506001600160a01b0384165f90815260036020819052604082208551918101549093506109af91906134b4565b6001600160401b038111156109c6576109c6612f74565b6040519080825280602002602001820160405280156109ef578160200160208202803683370190505b5090505f610a1c60405180608001604052805f81526020015f81526020015f81526020015f151581525090565b6003840154600454610a389089906001600160a01b03166129fa565b5f5b8751811015610c425760015f898381518110610a5857610a5861357d565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2060010160029054906101000a900460ff166040518060600160405280602a8152602001613838602a913990610ac75760405162461bcd60e51b815260040161044491906134cd565b50878181518110610ada57610ada61357d565b6020908102919091018101516001600160a01b0381165f9081526002808a01845260409182902082516080810184528154815260018201549581019590955290810154918401919091526003015460ff161580156060840152909550909350610b79578385846020015181518110610b5457610b5461357d565b60200260200101906001600160a01b031690816001600160a01b031681525050610c3a565b83858381518110610b8c57610b8c61357d565b6001600160a01b039283166020918202929092018101919091525f84815260018981018352604080832080546001600160a01b031916958a1695861790558051608081018252838152808501888152818301858152606083018581529786526002808f019097529290942090518155925191830191909155519181019190915590516003909101805460ff1916911515919091179055610c2c89856129fa565b81610c3681613591565b9250505b600101610a3a565b50876001600160a01b0316336001600160a01b03167f78a6368a6b0bcb8891b5e0283fa8cb2add1faf3bd518bba5d2954cf46d3c1c1989604051610c8691906135a9565b60405180910390a3805f03610c9f575050505050505050565b5f80805b8760030154811015611153575f6001600160a01b0316878281518110610ccb57610ccb61357d565b60200260200101516001600160a01b03160361114b575f81815260208181526040808320546001600160a01b03168084526001909252808320815160808101909252805492939282908290610d1f906134f2565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4b906134f2565b8015610d965780601f10610d6d57610100808354040283529160200191610d96565b820191905f5260205f20905b815481529060010190602001808311610d7957829003601f168201915b50505091835250506001919091015460ff808216151560208401526101008204811615156040840152620100009091041615156060909101529050610dda81612a95565b5f8a6002015f846001600160a01b03166001600160a01b031681526020019081526020015f205f01549050826001600160a01b03166331f092658f836040518363ffffffff1660e01b8152600401610e559291906001600160a01b0392909216825260208201526060604082018190525f9082015260800190565b6020604051808303815f875af1158015610e71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e959190613489565b8b5f015f828254610ea691906134b4565b9091555050604051635b9951b760e11b81526001600160a01b038f81166004830152606060248301525f60648301819052604483015284169063b732a36e906084016020604051808303815f875af1158015610f04573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f289190613489565b9450610f3485876134b4565b9550826001600160a01b03168e6001600160a01b0316336001600160a01b03167f5637d7f962248a7f05a7ab69eec6446e31f3d0a299d997f135a65c62806e789188604051610f8591815260200190565b60405180910390a46001600160a01b0383165f9081526002808d01602052604082208281556001810183905590810191909155600301805460ff191690555b83871115611147575f8a610fd960018a6134df565b81518110610fe957610fe961357d565b60200260200101516001600160a01b03160315611135578961100c6001896134df565b8151811061101c5761101c61357d565b60200260200101518a85815181106110365761103661357d565b60200260200101906001600160a01b031690816001600160a01b031681525050838b6002015f8c878151811061106e5761106e61357d565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f20600101819055508984815181106110ae576110ae61357d565b60200260200101518b6001015f8681526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505f8a6001896110fb91906134df565b8151811061110b5761110b61357d565b6001600160a01b03909216602092830291909101909101528661112d816135bb565b975050611147565b8661113f816135bb565b975050610fc4565b5050505b600101610ca3565b5088516003880155811561117b5760055461117b906001600160a01b038c8116911684612ad1565b505050505050505b505050565b6001600160a01b0381165f908152600360205260408120805482805b83600301548110156103f2575f8181526001850160209081526040808320546001600160a01b031680845260028801909252909120549092506111e790846134b4565b92506001016111a4565b60048054604080516358976a2f60e11b815290516001600160a01b039092169263b12ed45e9282820192602092908290030181865afa158015611236573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061125a9190613489565b600480546040516312d9a6ad60e01b81529182018390523360248301526001600160a01b0316906312d9a6ad906044015f6040518083038186803b1580156112a0575f80fd5b505afa1580156112b2573d5f803e3d5ffd5b5050506001600160a01b0384165f9081526001602081815260409283902091820154835160608101909452602a80855292945060ff620100009091041692919061383890830139906113175760405162461bcd60e51b815260040161044491906134cd565b5060018101805460ff19168415159081179091556040519081526001600160a01b0385169033907f62b76bfed3e25f37ab2de632c70377774c2945b0ff78df201c44268cc04a73ce9060200160405180910390a350505050565b5f60045f9054906101000a90046001600160a01b03166001600160a01b031663490b48f86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113c2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113e69190613489565b600480546040516312d9a6ad60e01b81529182018390523360248301526001600160a01b0316906312d9a6ad906044015f6040518083038186803b15801561142c575f80fd5b505afa15801561143e573d5f803e3d5ffd5b505050505f60035f886001600160a01b03166001600160a01b031681526020019081526020015f2090505f8160030154116040518060600160405280602a81526020016138c1602a9139906114a65760405162461bcd60e51b815260040161044491906134cd565b505f805b82600301548110156116bc575f818152600180850160209081526040808420546001600160a01b031680855260028801835281852093909252808420815160808101909252805492949282908290611501906134f2565b80601f016020809104026020016040519081016040528092919081815260200182805461152d906134f2565b80156115785780601f1061154f57610100808354040283529160200191611578565b820191905f5260205f20905b81548152906001019060200180831161155b57829003601f168201915b50505091835250506001919091015460ff80821615156020808501919091526101008304821615156040850152620100009092041615156060909201919091528101519091506115ca575050506116b4565b5f836001600160a01b031663b732a36e8e8e8e8e6040518563ffffffff1660e01b81526004016115fd94939291906135d0565b6020604051808303815f875af1158015611619573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061163d9190613489565b905080156116585761164f81876134b4565b42600285015595505b836001600160a01b03168d6001600160a01b0316336001600160a01b03167f5637d7f962248a7f05a7ab69eec6446e31f3d0a299d997f135a65c62806e7891846040516116a791815260200190565b60405180910390a4505050505b6001016114aa565b506005546116d7906001600160a01b038a8116911683612ad1565b979650505050505050565b60048054604080516358976a2f60e11b815290516001600160a01b039092169263b12ed45e9282820192602092908290030181865afa158015611727573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061174b9190613489565b600480546040516312d9a6ad60e01b81529182018390523360248301526001600160a01b0316906312d9a6ad906044015f6040518083038186803b158015611791575f80fd5b505afa1580156117a3573d5f803e3d5ffd5b505050505f84511160405180606001604052806026815260200161394860269139906117e25760405162461bcd60e51b815260040161044491906134cd565b5060015f846001600160a01b03166001600160a01b031681526020019081526020015f2060010160029054906101000a900460ff16156040518060600160405280602a81526020016137eb602a91399061184f5760405162461bcd60e51b815260040161044491906134cd565b5060408051808201909152600f81526e496e76616c6964206164647265737360881b60208201526001600160a01b03841661189d5760405162461bcd60e51b815260040161044491906134cd565b506040516301ffc9a760e01b815263fb9b90f960e01b600482015283906001600160a01b038216906301ffc9a790602401602060405180830381865afa1580156118e9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061190d9190613607565b6040518060600160405280603b8152602001613886603b9139906119445760405162461bcd60e51b815260040161044491906134cd565b50306001600160a01b0316816001600160a01b031663c9637cc36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561198b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119af9190613622565b6001600160a01b0316146040518060600160405280603e815260200161396e603e9139906119f05760405162461bcd60e51b815260040161044491906134cd565b50604080516080810182528681526001602080830182905286151583850152606083018290526001600160a01b0388165f9081529190529190912081518190611a399082613688565b50602082810151600190920180546040808601516060909601511515620100000262ff0000199615156101000261ff00199615159690961661ffff1990931692909217949094179490941693909317909255600280545f9081529283905290822080546001600160a01b0388166001600160a01b0319909116179055805491611ac183613591565b9190505550836001600160a01b031685604051611ade9190613747565b604080519182900382203383528615156020840152917ffeb85e1b59a8e75692b36f1d1165bbd12f7b43da4c5b8281e2fba4ba1315a963910160405180910390a35050505050565b6040805160808101825260608082525f602083018190529282018390528101919091526001600160a01b0382165f9081526001602052604090819020815160808101909252805482908290611b7a906134f2565b80601f0160208091040260200160405190810160405280929190818152602001828054611ba6906134f2565b8015611bf15780601f10611bc857610100808354040283529160200191611bf1565b820191905f5260205f20905b815481529060010190602001808311611bd457829003601f168201915b50505091835250506001919091015460ff8082161515602084015261010082048116151560408401526201000090910416151560609091015292915050565b6004805460408051630921691f60e31b815290516001600160a01b039092169263490b48f89282820192602092908290030181865afa158015611c75573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c999190613489565b600480546040516312d9a6ad60e01b81529182018390523360248301526001600160a01b0316906312d9a6ad906044015f6040518083038186803b158015611cdf575f80fd5b505afa158015611cf1573d5f803e3d5ffd5b5050604080518082019091526014815273092dcecc2d8d2c840c2e4e4c2f240d8cadccee8d60631b602082015291505082611d3f5760405162461bcd60e51b815260040161044491906134cd565b505f5b828110156123235736848483818110611d5d57611d5d61357d565b9050602002810190611d6f9190613762565b9050611e7560015f611d876040850160208601612ebe565b6001600160a01b03166001600160a01b031681526020019081526020015f206040518060800160405290815f82018054611dc0906134f2565b80601f0160208091040260200160405190810160405280929190818152602001828054611dec906134f2565b8015611e375780601f10611e0e57610100808354040283529160200191611e37565b820191905f5260205f20905b815481529060010190602001808311611e1a57829003601f168201915b50505091835250506001919091015460ff80821615156020840152610100820481161515604084015262010000909104161515606090910152612a95565b5f611e866040830160208401612ebe565b90505f600381611e996020860186612ebe565b6001600160a01b0316815260208101919091526040015f2090506001611ec5608085016060860161378a565b6003811115611ed657611ed6613776565b0361200857805f0154836040013511156040518060600160405280602481526020016138626024913990611f1d5760405162461bcd60e51b815260040161044491906134cd565b506001600160a01b0382166349bdc2b8611f3a6020860186612ebe565b6040860135611f4c60808801886137a8565b6040518563ffffffff1660e01b8152600401611f6b949392919061354c565b5f604051808303815f87803b158015611f82575f80fd5b505af1158015611f94573d5f803e3d5ffd5b505050508260400135815f015f828254611fae91906134df565b90915550506040830180359060028301905f90611fce9060208801612ebe565b6001600160a01b03166001600160a01b031681526020019081526020015f205f015f828254611ffd91906134b4565b909155506122899050565b600261201a608085016060860161378a565b600381111561202b5761202b613776565b036121e657600281015f6120456040860160208701612ebe565b6001600160a01b03166001600160a01b031681526020019081526020015f205f01548360400135111560405180606001604052806024815260200161386260249139906120a55760405162461bcd60e51b815260040161044491906134cd565b505f6001600160a01b0383166331f092656120c36020870187612ebe565b60408701356120d560808901896137a8565b6040518563ffffffff1660e01b81526004016120f4949392919061354c565b6020604051808303815f875af1158015612110573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121349190613489565b90508360400135811460405180606001604052806023815260200161381560239139906121745760405162461bcd60e51b815260040161044491906134cd565b508360400135825f015f82825461218b91906134b4565b90915550506040840180359060028401905f906121ab9060208901612ebe565b6001600160a01b03166001600160a01b031681526020019081526020015f205f015f8282546121da91906134df565b90915550612289915050565b60036121f8608085016060860161378a565b600381111561220957612209613776565b03612289576001600160a01b038216630f51fc2661222a6020860186612ebe565b604086013561223c60808801886137a8565b6040518563ffffffff1660e01b815260040161225b949392919061354c565b5f604051808303815f87803b158015612272575f80fd5b505af1158015612284573d5f803e3d5ffd5b505050505b612299608084016060850161378a565b60038111156122aa576122aa613776565b6122ba6040850160208601612ebe565b6001600160a01b03166122d06020860186612ebe565b604080513381528188013560208201526001600160a01b0392909216917fa742c9be7d2f68dbf5362a00c7acaf4297dc2764f3d57430595235925d76afe6910160405180910390a4505050600101611d42565b50505050565b6001600160a01b0381165f9081526003602052604081208180805b83600301548110156103f2575f8181526001850160205260409081902054905163dbe9345160e01b81526001600160a01b0388811660048301529091169250829063dbe9345190602401602060405180830381865afa1580156123a9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123cd9190613489565b6123d790846134b4565b9250600101612344565b6001600160a01b0381165f908152600360208190526040909120908101548154606092839283928392909182918291806001600160401b0381111561242857612428612f74565b60405190808252806020026020018201604052801561245b57816020015b60608152602001906001900390816124465790505b509850806001600160401b0381111561247657612476612f74565b60405190808252806020026020018201604052801561249f578160200160208202803683370190505b509650806001600160401b038111156124ba576124ba612f74565b6040519080825280602002602001820160405280156124e3578160200160208202803683370190505b509550806001600160401b038111156124fe576124fe612f74565b604051908082528060200260200182016040528015612527578160200160208202803683370190505b5097505f61255460405180608001604052805f81526020015f81526020015f81526020015f151581525090565b5f5b83811015612783575f818152600180870160209081526040808420546001600160a01b031680855292909152909120805491945090612594906134f2565b80601f01602080910402602001604051908101604052809291908181526020018280546125c0906134f2565b801561260b5780601f106125e25761010080835404028352916020019161260b565b820191905f5260205f20905b8154815290600101906020018083116125ee57829003601f168201915b50505050508c82815181106126225761262261357d565b6020908102919091018101919091526001600160a01b0384165f9081526002808801835260409182902082516080810184528154808252600183015495820195909552918101549282019290925260039091015460ff16151560608201528b519093508b90839081106126975761269761357d565b602090810291909101015281516126ae90886134b4565b6040516304cdc57b60e31b81526001600160a01b038f811660048301529198509084169063266e2bd890602401602060405180830381865afa1580156126f6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061271a9190613489565b61272490876134b4565b9550828b82815181106127395761273961357d565b60200260200101906001600160a01b031690816001600160a01b03168152505081604001518982815181106127705761277061357d565b6020908102919091010152600101612556565b5050505050919395979092949650565b60605f6002546001600160401b038111156127b0576127b0612f74565b60405190808252806020026020018201604052801561280157816020015b6040805160808101825260608082525f60208084018290529383018190529082015282525f199092019101816127ce5790505b5090505f5b600254811015612922575f81815260208181526040808320546001600160a01b0316835260019091529081902081516080810190925280548290829061284b906134f2565b80601f0160208091040260200160405190810160405280929190818152602001828054612877906134f2565b80156128c25780601f10612899576101008083540402835291602001916128c2565b820191905f5260205f20905b8154815290600101906020018083116128a557829003601f168201915b50505091835250506001919091015460ff80821615156020840152610100820481161515604084015262010000909104161515606090910152825183908390811061290f5761290f61357d565b6020908102919091010152600101612806565b50919050565b60048054604080516358976a2f60e11b815290516001600160a01b039092169263b12ed45e9282820192602092908290030181865afa15801561296d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129919190613489565b600480546040516312d9a6ad60e01b81529182018390523360248301526001600160a01b0316906312d9a6ad906044015f6040518083038186803b1580156129d7575f80fd5b505afa1580156129e9573d5f803e3d5ffd5b505050506129f682612b34565b5050565b604051636eb1769f60e11b81523060048201526001600160a01b0382811660248301525f919084169063dd62ed3e90604401602060405180830381865afa158015612a47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a6b9190613489565b90505f612a79825f196134df565b90508015612323576123236001600160a01b0385168483612bdf565b806020015160405180606001604052806027815260200161392160279139906129f65760405162461bcd60e51b815260040161044491906134cd565b6040516001600160a01b03831660248201526044810182905261118390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612c89565b60408051808201909152600f81526e496e76616c6964206164647265737360881b60208201526001600160a01b038216612b815760405162461bcd60e51b815260040161044491906134cd565b506005546040516001600160a01b0380841692169033907f23c12d5579081c5f1077c04a6b1c114d0f3de239e81a436836d30ecb099ffa13905f90a4600580546001600160a01b0319166001600160a01b0392909216919091179055565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa158015612c2c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c509190613489565b90506123238463095ea7b360e01b85612c6986866134b4565b6040516001600160a01b0390921660248301526044820152606401612afd565b5f612cdd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612d5c9092919063ffffffff16565b905080515f1480612cfd575080806020019051810190612cfd9190613607565b6111835760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610444565b60606107fa84845f85855f80866001600160a01b03168587604051612d819190613747565b5f6040518083038185875af1925050503d805f8114612dbb576040519150601f19603f3d011682016040523d82523d5f602084013e612dc0565b606091505b50915091506116d78783838760608315612e3a5782515f03612e33576001600160a01b0385163b612e335760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610444565b50816107fa565b6107fa8383815115612e4f5781518083602001fd5b8060405162461bcd60e51b815260040161044491906134cd565b5f60208284031215612e79575f80fd5b81356001600160e01b031981168114612e90575f80fd5b9392505050565b6001600160a01b0381168114612eab575f80fd5b50565b8035612eb981612e97565b919050565b5f60208284031215612ece575f80fd5b8135612e9081612e97565b5f8083601f840112612ee9575f80fd5b5081356001600160401b03811115612eff575f80fd5b602083019150836020828501011115612f16575f80fd5b9250929050565b5f805f8060608587031215612f30575f80fd5b8435612f3b81612e97565b93506020850135925060408501356001600160401b03811115612f5c575f80fd5b612f6887828801612ed9565b95989497509550505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715612fb057612fb0612f74565b604052919050565b5f8060408385031215612fc9575f80fd5b8235612fd481612e97565b91506020838101356001600160401b0380821115612ff0575f80fd5b818601915086601f830112613003575f80fd5b81358181111561301557613015612f74565b8060051b9150613026848301612f88565b818152918301840191848101908984111561303f575f80fd5b938501935b83851015613069578435925061305983612e97565b8282529385019390850190613044565b8096505050505050509250929050565b5f60208284031215613089575f80fd5b5035919050565b8015158114612eab575f80fd5b8035612eb981613090565b5f80604083850312156130b9575f80fd5b82356130c481612e97565b915060208301356130d481613090565b809150509250929050565b5f805f80606085870312156130f2575f80fd5b84356130fd81612e97565b935060208501356001600160401b03811115613117575f80fd5b61312387828801612ed9565b909450925050604085013561313781613090565b939692955090935050565b5f805f60608486031215613154575f80fd5b83356001600160401b038082111561316a575f80fd5b818601915086601f83011261317d575f80fd5b813560208282111561319157613191612f74565b6131a3601f8301601f19168201612f88565b925081835288818386010111156131b8575f80fd5b81818501828501375f8183850101528296506131d5818901612eae565b9550505050506131e76040850161309d565b90509250925092565b5f5b8381101561320a5781810151838201526020016131f2565b50505f910152565b5f81518084526132298160208601602086016131f0565b601f01601f19169290920160200192915050565b5f8151608084526132516080850182613212565b90506020830151151560208501526040830151151560408501526060830151151560608501528091505092915050565b602081525f612e90602083018461323d565b5f80602083850312156132a4575f80fd5b82356001600160401b03808211156132ba575f80fd5b818501915085601f8301126132cd575f80fd5b8135818111156132db575f80fd5b8660208260051b85010111156132ef575f80fd5b60209290920196919550909350505050565b5f815180845260208085019450602084015f5b838110156133395781516001600160a01b031687529582019590820190600101613314565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561333957815187529582019590820190600101613357565b60e080825288519082018190525f90610100600582901b8401810191908401906020808d01855b838110156133c85760ff198887030185526133b6868351613212565b9550938201939082019060010161339a565b505050505082810360208401526133df818a613301565b905082810360408401526133f38189613344565b905082810360608401526134078188613344565b6080840196909652505060a081019290925260c090910152949350505050565b5f60208083016020845280855180835260408601915060408160051b8701019250602087015f5b8281101561347c57603f1988860301845261346a85835161323d565b9450928501929085019060010161344e565b5092979650505050505050565b5f60208284031215613499575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156134c7576134c76134a0565b92915050565b602081525f612e906020830184613212565b818103818111156134c7576134c76134a0565b600181811c9082168061350657607f821691505b60208210810361292257634e487b7160e01b5f52602260045260245ffd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60018060a01b0385168152836020820152606060408201525f613573606083018486613524565b9695505050505050565b634e487b7160e01b5f52603260045260245ffd5b5f600182016135a2576135a26134a0565b5060010190565b602081525f612e906020830184613301565b5f816135c9576135c96134a0565b505f190190565b6001600160a01b03851681526060602082018190525f906135f49083018587613524565b9050821515604083015295945050505050565b5f60208284031215613617575f80fd5b8151612e9081613090565b5f60208284031215613632575f80fd5b8151612e9081612e97565b601f82111561118357805f5260205f20601f840160051c810160208510156136625750805b601f840160051c820191505b81811015613681575f815560010161366e565b5050505050565b81516001600160401b038111156136a1576136a1612f74565b6136b5816136af84546134f2565b8461363d565b602080601f8311600181146136e8575f84156136d15750858301515b5f19600386901b1c1916600185901b17855561373f565b5f85815260208120601f198616915b82811015613716578886015182559484019460019091019084016136f7565b508582101561373357878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b5f82516137588184602087016131f0565b9190910192915050565b5f8235609e19833603018112613758575f80fd5b634e487b7160e01b5f52602160045260245ffd5b5f6020828403121561379a575f80fd5b813560048110612e90575f80fd5b5f808335601e198436030181126137bd575f80fd5b8301803591506001600160401b038211156137d6575f80fd5b602001915036819003821315612f16575f80fdfe4d656c644661726d696e674d616e616765723a204164617074657220616c7265616479206578697374734d656c644661726d696e674d616e616765723a20416d6f756e74206d69736d617463684d656c644661726d696e674d616e616765723a204164617074657220646f6573206e6f742065786973744d656c644661726d696e674d616e616765723a204e6f7420656e6f7567682066756e64734d656c644661726d696e674d616e616765723a204164617074657220646f6573206e6f7420696d706c656d656e7420494d656c644661726d696e674d656c644661726d696e674d616e616765723a204e6f20616461707465727320636f6e666967757265644d656c644661726d696e674d616e616765723a204f6e6c79206272696467652063616e2063616c6c20746869732066756e6374696f6e4d656c644661726d696e674d616e616765723a20416461707465722069732064697361626c65644d656c644661726d696e674d616e616765723a20496e76616c696420616461707465722049444d656c644661726d696e674d616e616765723a20496e76616c69642061646170746572204d656c644661726d696e674d616e616765722061646472657373a26469706673582212205ee36ba130fb8af85ab458a0a570c8006f53cfae391a19a35fc832c709683d8364736f6c63430008180033

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

000000000000000000000000c9ced87b7073297ceb12453c0d65329d496fc0b4000000000000000000000000303b3d643753b86f2045f08b1df0f910f42cb200

-----Decoded View---------------
Arg [0] : _bridge (address): 0xc9cED87b7073297cEB12453C0D65329D496fc0B4
Arg [1] : _treasury (address): 0x303b3D643753b86F2045F08b1dF0f910F42cB200

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000c9ced87b7073297ceb12453c0d65329d496fc0b4
Arg [1] : 000000000000000000000000303b3d643753b86f2045f08b1df0f910f42cb200


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ 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.