ETH Price: $2,710.68 (+0.03%)

Contract

0x915a2afCde5E4D524e46A541e4019ad37A3A4116
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x18CfB667...d14c8fc11
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
CompoundManager

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 999 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity Multiple files format)

File 1 of 11: CompoundManager.sol
// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.6.12;

import "./BaseFeature.sol";
import "./ICompoundRegistry.sol";

interface IComptroller {
    function enterMarkets(address[] calldata _cTokens) external returns (uint[] memory);
    function exitMarket(address _cToken) external returns (uint);
    function getAssetsIn(address _account) external view returns (address[] memory);
    function getAccountLiquidity(address _account) external view returns (uint, uint, uint);
    function checkMembership(address account, ICToken cToken) external view returns (bool);
}

interface ICToken {
    function comptroller() external view returns (address);
    function underlying() external view returns (address);
    function symbol() external view returns (string memory);
    function exchangeRateCurrent() external returns (uint256);
    function exchangeRateStored() external view returns (uint256);
    function balanceOf(address _account) external view returns (uint256);
    function borrowBalanceCurrent(address _account) external returns (uint256);
    function borrowBalanceStored(address _account) external view returns (uint256);
}

/**
 * @title CompoundManager
 * @notice Module to invest and borrow tokens with CompoundV2
 * @author Julien Niset - <[email protected]>
 */
contract CompoundManager is BaseFeature{

    bytes32 constant NAME = "CompoundManager";

    // The Compound IComptroller contract
    IComptroller public comptroller;
    // The registry mapping underlying with cTokens
    ICompoundRegistry public compoundRegistry;

    event InvestmentAdded(address indexed _wallet, address _token, uint256 _invested, uint256 _period);
    event InvestmentRemoved(address indexed _wallet, address _token, uint256 _fraction);
    event LoanOpened(
        address indexed _wallet,
        bytes32 indexed _loanId,
        address _collateral,
        uint256 _collateralAmount,
        address _debtToken,
        uint256 _debtAmount);
    event LoanClosed(address indexed _wallet, bytes32 indexed _loanId);
    event CollateralAdded(address indexed _wallet, bytes32 indexed _loanId, address _collateral, uint256 _collateralAmount);
    event CollateralRemoved(address indexed _wallet, bytes32 indexed _loanId, address _collateral, uint256 _collateralAmount);
    event DebtAdded(address indexed _wallet, bytes32 indexed _loanId, address _debtToken, uint256 _debtAmount);
    event DebtRemoved(address indexed _wallet, bytes32 indexed _loanId, address _debtToken, uint256 _debtAmount);

    using SafeMath for uint256;

    constructor(
        ILockStorage _lockStorage,
        IComptroller _comptroller,
        ICompoundRegistry _compoundRegistry,
        IVersionManager _versionManager
    )
        BaseFeature(_lockStorage, _versionManager, NAME)
        public
    {
        comptroller = _comptroller;
        compoundRegistry = _compoundRegistry;
    }

    /**
     * @inheritdoc IFeature
     */
    function getRequiredSignatures(address, bytes calldata) external view override returns (uint256, OwnerSignature) {
        return (1, OwnerSignature.Required);
    }

    /* ********************************** Implementation of Loan ************************************* */

    /**
     * @notice Opens a collateralized loan.
     * @param _wallet The target wallet.
     * @param _collateral The token used as a collateral.
     * @param _collateralAmount The amount of collateral token provided.
     * @param _debtToken The token borrowed.
     * @param _debtAmount The amount of tokens borrowed.
     * @return _loanId bytes32(0) as Compound does not allow the creation of multiple loans.
     */
    function openLoan(
        address _wallet,
        address _collateral,
        uint256 _collateralAmount,
        address _debtToken,
        uint256 _debtAmount
    )
        external
        onlyWalletOwnerOrFeature(_wallet)
        onlyWhenUnlocked(_wallet)
        returns (bytes32 _loanId)
    {
        address[] memory markets = new address[](2);
        markets[0] = compoundRegistry.getCToken(_collateral);
        markets[1] = compoundRegistry.getCToken(_debtToken);
        invokeWallet(_wallet, address(comptroller), 0, abi.encodeWithSignature("enterMarkets(address[])", markets));
        mint(_wallet, markets[0], _collateral, _collateralAmount);
        borrow(_wallet, _debtToken, markets[1], _debtAmount);
        emit LoanOpened(_wallet, _loanId, _collateral, _collateralAmount, _debtToken, _debtAmount);
    }

    /**
     * @notice Closes the collateralized loan in all markets by repaying all debts (plus interest). Note that it does not redeem the collateral.
     * @param _wallet The target wallet.
     * @param _loanId bytes32(0) as Compound does not allow the creation of multiple loans.
     */
    function closeLoan(
        address _wallet,
        bytes32 _loanId
    )
        external
        onlyWalletOwnerOrFeature(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        address[] memory markets = comptroller.getAssetsIn(_wallet);
        for (uint i = 0; i < markets.length; i++) {
            address cToken = markets[i];
            uint debt = ICToken(cToken).borrowBalanceCurrent(_wallet);
            if (debt > 0) {
                repayBorrow(_wallet, cToken, debt);
                uint collateral = ICToken(cToken).balanceOf(_wallet);
                if (collateral == 0) {
                    invokeWallet(
                        _wallet,
                        address(comptroller),
                        0,
                        abi.encodeWithSignature("exitMarket(address)", address(cToken))
                    );
                }
            }
        }
        emit LoanClosed(_wallet, _loanId);
    }

    /**
     * @notice Adds collateral to a loan identified by its ID.
     * @param _wallet The target wallet.
     * @param _loanId bytes32(0) as Compound does not allow the creation of multiple loans.
     * @param _collateral The token used as a collateral.
     * @param _collateralAmount The amount of collateral to add.
     */
    function addCollateral(
        address _wallet,
        bytes32 _loanId,
        address _collateral,
        uint256 _collateralAmount
    )
        external
        onlyWalletOwnerOrFeature(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        address cToken = compoundRegistry.getCToken(_collateral);
        enterMarketIfNeeded(_wallet, cToken, address(comptroller));
        mint(_wallet, cToken, _collateral, _collateralAmount);
        emit CollateralAdded(_wallet, _loanId, _collateral, _collateralAmount);
    }

    /**
     * @notice Removes collateral from a loan identified by its ID.
     * @param _wallet The target wallet.
     * @param _loanId bytes32(0) as Compound does not allow the creation of multiple loans.
     * @param _collateral The token used as a collateral.
     * @param _collateralAmount The amount of collateral to remove.
     */
    function removeCollateral(
        address _wallet,
        bytes32 _loanId,
        address _collateral,
        uint256 _collateralAmount
    )
        external
        onlyWalletOwnerOrFeature(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        address cToken = compoundRegistry.getCToken(_collateral);
        redeemUnderlying(_wallet, cToken, _collateralAmount);
        exitMarketIfNeeded(_wallet, cToken, address(comptroller));
        emit CollateralRemoved(_wallet, _loanId, _collateral, _collateralAmount);
    }

    /**
     * @notice Increases the debt by borrowing more token from a loan identified by its ID.
     * @param _wallet The target wallet.
     * @param _loanId bytes32(0) as Compound does not allow the creation of multiple loans.
     * @param _debtToken The token borrowed.
     * @param _debtAmount The amount of token to borrow.
     */
    function addDebt(
        address _wallet,
        bytes32 _loanId,
        address _debtToken,
        uint256 _debtAmount
    )
        external
        onlyWalletOwnerOrFeature(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        address dToken = compoundRegistry.getCToken(_debtToken);
        enterMarketIfNeeded(_wallet, dToken, address(comptroller));
        borrow(_wallet, _debtToken, dToken, _debtAmount);
        emit DebtAdded(_wallet, _loanId, _debtToken, _debtAmount);
    }

    /**
     * @notice Decreases the debt by repaying some token from a loan identified by its ID.
     * @param _wallet The target wallet.
     * @param _loanId bytes32(0) as Compound does not allow the creation of multiple loans.
     * @param _debtToken The token to repay.
     * @param _debtAmount The amount of token to repay.
     */
    function removeDebt(
        address _wallet,
        bytes32 _loanId,
        address _debtToken,
        uint256 _debtAmount
    )
        external
        onlyWalletOwnerOrFeature(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        address dToken = compoundRegistry.getCToken(_debtToken);
        repayBorrow(_wallet, dToken, _debtAmount);
        exitMarketIfNeeded(_wallet, dToken, address(comptroller));
        emit DebtRemoved(_wallet, _loanId, _debtToken, _debtAmount);
    }

    /**
     * @notice Gets information about the loan status on Compound.
     * @param _wallet The target wallet.
     * @return _status Status [0: no loan, 1: loan is safe, 2: loan is unsafe and can be liquidated]
     * @return _ethValue Value (in ETH) representing the value that could still be borrowed when status = 1; or the value of the collateral
     * that should be added to avoid liquidation when status = 2.
     */
    function getLoan(
        address _wallet,
        bytes32 /* _loanId */
    )
        external
        view
        returns (uint8 _status, uint256 _ethValue)
    {
        (uint error, uint liquidity, uint shortfall) = comptroller.getAccountLiquidity(_wallet);
        require(error == 0, "CM: failed to get account liquidity");
        if (liquidity > 0) {
            return (1, liquidity);
        }
        if (shortfall > 0) {
            return (2, shortfall);
        }
        return (0,0);
    }

    /* ********************************** Implementation of Invest ************************************* */

    /**
     * @notice Invest tokens for a given period.
     * @param _wallet The target wallet.
     * @param _token The token address.
     * @param _amount The amount of tokens to invest.
     * @param _period The period over which the tokens may be locked in the investment (optional).
     * @return _invested The exact amount of tokens that have been invested.
     */
    function addInvestment(
        address _wallet,
        address _token,
        uint256 _amount,
        uint256 _period
    )
        external
        onlyWalletOwnerOrFeature(_wallet)
        onlyWhenUnlocked(_wallet)
        returns (uint256 _invested)
    {
        address cToken = compoundRegistry.getCToken(_token);
        mint(_wallet, cToken, _token, _amount);
        _invested = _amount;
        emit InvestmentAdded(_wallet, _token, _amount, _period);
    }

    /**
     * @notice Exit invested postions.
     * @param _wallet The target wallet.
     * @param _token The token address.
     * @param _fraction The fraction of invested tokens to exit in per 10000.
     */
    function removeInvestment(
        address _wallet,
        address _token,
        uint256 _fraction
    )
        external
        onlyWalletOwnerOrFeature(_wallet)
        onlyWhenUnlocked(_wallet)
    {
        require(_fraction <= 10000, "CM: invalid fraction value");
        address cToken = compoundRegistry.getCToken(_token);
        uint shares = ICToken(cToken).balanceOf(_wallet);
        redeem(_wallet, cToken, shares.mul(_fraction).div(10000));
        emit InvestmentRemoved(_wallet, _token, _fraction);
    }

    /**
     * @notice Get the amount of investment in a given token.
     * @param _wallet The target wallet.
     * @param _token The token address.
     * @return _tokenValue The value in tokens of the investment (including interests).
     * @return _periodEnd The time at which the investment can be removed.
     */
    function getInvestment(
        address _wallet,
        address _token
    )
        external
        view
        returns (uint256 _tokenValue, uint256 _periodEnd)
    {
        address cToken = compoundRegistry.getCToken(_token);
        uint amount = ICToken(cToken).balanceOf(_wallet);
        uint exchangeRateMantissa = ICToken(cToken).exchangeRateStored();
        _tokenValue = amount.mul(exchangeRateMantissa).div(10 ** 18);
        _periodEnd = 0;
    }

    /* ****************************************** Compound wrappers ******************************************* */

    /**
     * @notice Adds underlying tokens to a cToken contract.
     * @param _wallet The target wallet.
     * @param _cToken The cToken contract.
     * @param _token The underlying token.
     * @param _amount The amount of underlying token to add.
     */
    function mint(address _wallet, address _cToken, address _token, uint256 _amount) internal {
        require(_cToken != address(0), "CM: No market for target token");
        require(_amount > 0, "CM: amount cannot be 0");
        uint256 initialCTokenAmount = ERC20(_cToken).balanceOf(_wallet);
        if (_token == ETH_TOKEN) {
            invokeWallet(_wallet, _cToken, _amount, abi.encodeWithSignature("mint()"));
        } else {
            invokeWallet(_wallet, _token, 0, abi.encodeWithSignature("approve(address,uint256)", _cToken, _amount));
            invokeWallet(_wallet, _cToken, 0, abi.encodeWithSignature("mint(uint256)", _amount));
        }
        require(ERC20(_cToken).balanceOf(_wallet) > initialCTokenAmount, "CM: mint failed");
    }

    /**
     * @notice Redeems underlying tokens from a cToken contract.
     * @param _wallet The target wallet.
     * @param _cToken The cToken contract.
     * @param _amount The amount of cToken to redeem.
     */
    function redeem(address _wallet, address _cToken, uint256 _amount) internal {
        // The following commented `require()` is not necessary as `ICToken(cToken).balanceOf(_wallet)` in `removeInvestment()`
        // would have reverted if `_cToken == address(0)`
        // It is however left as a comment as a reminder to include it if `removeInvestment()` is changed to use amounts instead of fractions.
        // require(_cToken != address(0), "CM: No market for target token");
        require(_amount > 0, "CM: amount cannot be 0");
        uint256 initialCTokenAmount = ERC20(_cToken).balanceOf(_wallet);
        invokeWallet(_wallet, _cToken, 0, abi.encodeWithSignature("redeem(uint256)", _amount));
        require(ERC20(_cToken).balanceOf(_wallet) < initialCTokenAmount, "CM: redeem failed");
    }

    /**
     * @notice Redeems underlying tokens from a cToken contract.
     * @param _wallet The target wallet.
     * @param _cToken The cToken contract.
     * @param _amount The amount of underlying token to redeem.
     */
    function redeemUnderlying(address _wallet, address _cToken, uint256 _amount) internal {
        require(_cToken != address(0), "CM: No market for target token");
        require(_amount > 0, "CM: amount cannot be 0");
        uint256 initialCTokenAmount = ERC20(_cToken).balanceOf(_wallet);
        invokeWallet(_wallet, _cToken, 0, abi.encodeWithSignature("redeemUnderlying(uint256)", _amount));
        require(ERC20(_cToken).balanceOf(_wallet) < initialCTokenAmount, "CM: redeemUnderlying failed");
    }

    /**
     * @notice Borrows underlying tokens from a cToken contract.
     * @param _wallet The target wallet.
     * @param _token The token contract.
     * @param _cToken The cToken contract.
     * @param _amount The amount of underlying tokens to borrow.
     */
    function borrow(address _wallet, address _token, address _cToken, uint256 _amount) internal {
        require(_cToken != address(0), "CM: No market for target token");
        require(_amount > 0, "CM: amount cannot be 0");
        uint256 initialTokenAmount = _token == ETH_TOKEN ? _wallet.balance : ERC20(_token).balanceOf(_wallet);
        invokeWallet(_wallet, _cToken, 0, abi.encodeWithSignature("borrow(uint256)", _amount));
        uint256 finalTokenAmount = _token == ETH_TOKEN ? _wallet.balance : ERC20(_token).balanceOf(_wallet);
        require(finalTokenAmount > initialTokenAmount, "CM: borrow failed");
    }

    /**
     * @notice Repays some borrowed underlying tokens to a cToken contract.
     * @param _wallet The target wallet.
     * @param _cToken The cToken contract.
     * @param _amount The amount of underlying to repay.
     */
    function repayBorrow(address _wallet, address _cToken, uint256 _amount) internal {
        require(_cToken != address(0), "CM: No market for target token");
        require(_amount > 0, "CM: amount cannot be 0");
        string memory symbol = ICToken(_cToken).symbol();
        uint256 initialTokenAmount;
        uint256 finalTokenAmount;
        if (keccak256(abi.encodePacked(symbol)) == keccak256(abi.encodePacked("cETH"))) {
            initialTokenAmount = _wallet.balance;
            invokeWallet(_wallet, _cToken, _amount, abi.encodeWithSignature("repayBorrow()"));
            finalTokenAmount = _wallet.balance;
        } else {
            address token = ICToken(_cToken).underlying();
            initialTokenAmount = ERC20(token).balanceOf(_wallet);
            invokeWallet(_wallet, token, 0, abi.encodeWithSignature("approve(address,uint256)", _cToken, _amount));
            invokeWallet(_wallet, _cToken, 0, abi.encodeWithSignature("repayBorrow(uint256)", _amount));
            finalTokenAmount = ERC20(token).balanceOf(_wallet);
        }
        require(finalTokenAmount < initialTokenAmount, "CM: repayBorrow failed");
    }

    /**
     * @notice Enters a cToken market if it was not entered before.
     * @param _wallet The target wallet.
     * @param _cToken The cToken contract.
     * @param _comptroller The comptroller contract.
     */
    function enterMarketIfNeeded(address _wallet, address _cToken, address _comptroller) internal {
        bool isEntered = IComptroller(_comptroller).checkMembership(_wallet, ICToken(_cToken));
        if (!isEntered) {
            address[] memory market = new address[](1);
            market[0] = _cToken;
            invokeWallet(_wallet, _comptroller, 0, abi.encodeWithSignature("enterMarkets(address[])", market));
        }
    }

    /**
     * @notice Exits a cToken market if there is no more collateral and debt.
     * @param _wallet The target wallet.
     * @param _cToken The cToken contract.
     * @param _comptroller The comptroller contract.
     */
    function exitMarketIfNeeded(address _wallet, address _cToken, address _comptroller) internal {
        uint collateral = ICToken(_cToken).balanceOf(_wallet);
        uint debt = ICToken(_cToken).borrowBalanceStored(_wallet);
        if (collateral == 0 && debt == 0) {
            invokeWallet(_wallet, _comptroller, 0, abi.encodeWithSignature("exitMarket(address)", _cToken));
        }
    }
}

File 2 of 11: BaseFeature.sol
// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.s

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.6.12;

import "./SafeMath.sol";
import "./IWallet.sol";
import "./IModuleRegistry.sol";
import "./ILockStorage.sol";
import "./IFeature.sol";
import "./ERC20.sol";
import "./IVersionManager.sol";

/**
 * @title BaseFeature
 * @notice Base Feature contract that contains methods common to all Feature contracts.
 * @author Julien Niset - <[email protected]>, Olivier VDB - <[email protected]>
 */
contract BaseFeature is IFeature {

    // Empty calldata
    bytes constant internal EMPTY_BYTES = "";
    // Mock token address for ETH
    address constant internal ETH_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
    // The address of the Lock storage
    ILockStorage internal lockStorage;
    // The address of the Version Manager
    IVersionManager internal versionManager;

    event FeatureCreated(bytes32 name);

    /**
     * @notice Throws if the wallet is locked.
     */
    modifier onlyWhenUnlocked(address _wallet) {
        require(!lockStorage.isLocked(_wallet), "BF: wallet locked");
        _;
    }

    /**
     * @notice Throws if the sender is not the VersionManager.
     */
    modifier onlyVersionManager() {
        require(msg.sender == address(versionManager), "BF: caller must be VersionManager");
        _;
    }

    /**
     * @notice Throws if the sender is not the owner of the target wallet.
     */
    modifier onlyWalletOwner(address _wallet) {
        require(isOwner(_wallet, msg.sender), "BF: must be wallet owner");
        _;
    }

    /**
     * @notice Throws if the sender is not an authorised feature of the target wallet.
     */
    modifier onlyWalletFeature(address _wallet) {
        require(versionManager.isFeatureAuthorised(_wallet, msg.sender), "BF: must be a wallet feature");
        _;
    }

    /**
     * @notice Throws if the sender is not the owner of the target wallet or the feature itself.
     */
    modifier onlyWalletOwnerOrFeature(address _wallet) {
        // Wrapping in an internal method reduces deployment cost by avoiding duplication of inlined code
        verifyOwnerOrAuthorisedFeature(_wallet, msg.sender);
        _;
    }

    constructor(
        ILockStorage _lockStorage,
        IVersionManager _versionManager,
        bytes32 _name
    ) public {
        lockStorage = _lockStorage;
        versionManager = _versionManager;
        emit FeatureCreated(_name);
    }

    /**
    * @inheritdoc IFeature
    */
    function recoverToken(address _token) external virtual override {
        uint total = ERC20(_token).balanceOf(address(this));
        _token.call(abi.encodeWithSelector(ERC20(_token).transfer.selector, address(versionManager), total));
    }

    /**
     * @notice Inits the feature for a wallet by doing nothing.
     * @dev !! Overriding methods need make sure `init()` can only be called by the VersionManager !!
     * @param _wallet The wallet.
     */
    function init(address _wallet) external virtual override  {}

    /**
     * @inheritdoc IFeature
     */
    function getRequiredSignatures(address, bytes calldata) external virtual view override returns (uint256, OwnerSignature) {
        revert("BF: disabled method");
    }

    /**
     * @inheritdoc IFeature
     */
    function getStaticCallSignatures() external virtual override view returns (bytes4[] memory _sigs) {}

    /**
     * @inheritdoc IFeature
     */
    function isFeatureAuthorisedInVersionManager(address _wallet, address _feature) public override view returns (bool) {
        return versionManager.isFeatureAuthorised(_wallet, _feature);
    }

    /**
    * @notice Checks that the wallet address provided as the first parameter of _data matches _wallet
    * @return false if the addresses are different.
    */
    function verifyData(address _wallet, bytes calldata _data) internal pure returns (bool) {
        require(_data.length >= 36, "RM: Invalid dataWallet");
        address dataWallet = abi.decode(_data[4:], (address));
        return dataWallet == _wallet;
    }
    
     /**
     * @notice Helper method to check if an address is the owner of a target wallet.
     * @param _wallet The target wallet.
     * @param _addr The address.
     */
    function isOwner(address _wallet, address _addr) internal view returns (bool) {
        return IWallet(_wallet).owner() == _addr;
    }

    /**
     * @notice Verify that the caller is an authorised feature or the wallet owner.
     * @param _wallet The target wallet.
     * @param _sender The caller.
     */
    function verifyOwnerOrAuthorisedFeature(address _wallet, address _sender) internal view {
        require(isFeatureAuthorisedInVersionManager(_wallet, _sender) || isOwner(_wallet, _sender), "BF: must be owner or feature");
    }

    /**
     * @notice Helper method to invoke a wallet.
     * @param _wallet The target wallet.
     * @param _to The target address for the transaction.
     * @param _value The value of the transaction.
     * @param _data The data of the transaction.
     */
    function invokeWallet(address _wallet, address _to, uint256 _value, bytes memory _data)
        internal
        returns (bytes memory _res) 
    {
        _res = versionManager.checkAuthorisedFeatureAndInvokeWallet(_wallet, _to, _value, _data);
    }

}

File 3 of 11: ERC20.sol
pragma solidity >=0.5.4 <0.7.0;

/**
 * ERC20 contract interface.
 */
interface ERC20 {
    function totalSupply() external view returns (uint);
    function decimals() external view returns (uint);
    function balanceOf(address tokenOwner) external view returns (uint balance);
    function allowance(address tokenOwner, address spender) external view returns (uint remaining);
    function transfer(address to, uint tokens) external returns (bool success);
    function approve(address spender, uint tokens) external returns (bool success);
    function transferFrom(address from, address to, uint tokens) external returns (bool success);
}

File 4 of 11: ICompoundRegistry.sol
// Copyright (C) 2020 Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.5.4 <0.7.0;

/**
 * @title ICompoundRegistry
 * @notice Interface for CompoundRegistry
 */
interface ICompoundRegistry {
    function addCToken(address _underlying, address _cToken) external;

    function removeCToken(address _underlying) external;

    function getCToken(address _underlying) external view returns (address);

    function listUnderlyings() external view returns (address[] memory);
}

File 5 of 11: IFeature.sol
// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.5.4 <0.7.0;

/**
 * @title IFeature
 * @notice Interface for a Feature.
 * @author Julien Niset - <[email protected]>, Olivier VDB - <[email protected]>
 */
interface IFeature {

    enum OwnerSignature {
        Anyone,             // Anyone
        Required,           // Owner required
        Optional,           // Owner and/or guardians
        Disallowed          // guardians only
    }

    /**
    * @notice Utility method to recover any ERC20 token that was sent to the Feature by mistake.
    * @param _token The token to recover.
    */
    function recoverToken(address _token) external;

    /**
     * @notice Inits a Feature for a wallet by e.g. setting some wallet specific parameters in storage.
     * @param _wallet The wallet.
     */
    function init(address _wallet) external;

    /**
     * @notice Helper method to check if an address is an authorised feature of a target wallet.
     * @param _wallet The target wallet.
     * @param _feature The address.
     */
    function isFeatureAuthorisedInVersionManager(address _wallet, address _feature) external view returns (bool);

    /**
    * @notice Gets the number of valid signatures that must be provided to execute a
    * specific relayed transaction.
    * @param _wallet The target wallet.
    * @param _data The data of the relayed transaction.
    * @return The number of required signatures and the wallet owner signature requirement.
    */
    function getRequiredSignatures(address _wallet, bytes calldata _data) external view returns (uint256, OwnerSignature);

    /**
    * @notice Gets the list of static call signatures that this feature responds to on behalf of wallets
    */
    function getStaticCallSignatures() external view returns (bytes4[] memory);
}

File 6 of 11: ILimitStorage.sol
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;

/**
 * @title ILimitStorage
 * @notice LimitStorage interface
 */
interface ILimitStorage {

    struct Limit {
        // the current limit
        uint128 current;
        // the pending limit if any
        uint128 pending;
        // when the pending limit becomes the current limit
        uint64 changeAfter;
    }

    struct DailySpent {
        // The amount already spent during the current period
        uint128 alreadySpent;
        // The end of the current period
        uint64 periodEnd;
    }

    function setLimit(address _wallet, Limit memory _limit) external;

    function getLimit(address _wallet) external view returns (Limit memory _limit);

    function setDailySpent(address _wallet, DailySpent memory _dailySpent) external;

    function getDailySpent(address _wallet) external view returns (DailySpent memory _dailySpent);

    function setLimitAndDailySpent(address _wallet, Limit memory _limit, DailySpent memory _dailySpent) external;

    function getLimitAndDailySpent(address _wallet) external view returns (Limit memory _limit, DailySpent memory _dailySpent);
}

File 7 of 11: ILockStorage.sol
// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.5.4 <0.7.0;

interface ILockStorage {
    function isLocked(address _wallet) external view returns (bool);

    function getLock(address _wallet) external view returns (uint256);

    function getLocker(address _wallet) external view returns (address);

    function setLock(address _wallet, address _locker, uint256 _releaseAfter) external;
}

File 8 of 11: IModuleRegistry.sol
// Copyright (C) 2020  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.5.4 <0.7.0;

/**
 * @title IModuleRegistry
 * @notice Interface for the registry of authorised modules.
 */
interface IModuleRegistry {
    function registerModule(address _module, bytes32 _name) external;

    function deregisterModule(address _module) external;

    function registerUpgrader(address _upgrader, bytes32 _name) external;

    function deregisterUpgrader(address _upgrader) external;

    function recoverToken(address _token) external;

    function moduleInfo(address _module) external view returns (bytes32);

    function upgraderInfo(address _upgrader) external view returns (bytes32);

    function isRegisteredModule(address _module) external view returns (bool);

    function isRegisteredModule(address[] calldata _modules) external view returns (bool);

    function isRegisteredUpgrader(address _upgrader) external view returns (bool);
}

File 9 of 11: IVersionManager.sol
// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.5.4 <0.7.0;
pragma experimental ABIEncoderV2;

import "./ILimitStorage.sol";

/**
 * @title IVersionManager
 * @notice Interface for the VersionManager module.
 * @author Olivier VDB - <[email protected]>
 */
interface IVersionManager {
    /**
     * @notice Returns true if the feature is authorised for the wallet
     * @param _wallet The target wallet.
     * @param _feature The feature.
     */
    function isFeatureAuthorised(address _wallet, address _feature) external view returns (bool);

    /**
     * @notice Lets a feature (caller) invoke a wallet.
     * @param _wallet The target wallet.
     * @param _to The target address for the transaction.
     * @param _value The value of the transaction.
     * @param _data The data of the transaction.
     */
    function checkAuthorisedFeatureAndInvokeWallet(
        address _wallet,
        address _to,
        uint256 _value,
        bytes calldata _data
    ) external returns (bytes memory _res);

    /* ******* Backward Compatibility with old Storages and BaseWallet *************** */

    /**
     * @notice Sets a new owner for the wallet.
     * @param _newOwner The new owner.
     */
    function setOwner(address _wallet, address _newOwner) external;

    /**
     * @notice Lets a feature write data to a storage contract.
     * @param _wallet The target wallet.
     * @param _storage The storage contract.
     * @param _data The data of the call
     */
    function invokeStorage(address _wallet, address _storage, bytes calldata _data) external;

    /**
     * @notice Upgrade a wallet to a new version.
     * @param _wallet the wallet to upgrade
     * @param _toVersion the new version
     */
    function upgradeWallet(address _wallet, uint256 _toVersion) external;
 
}

File 10 of 11: IWallet.sol
// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.5.4 <0.7.0;

/**
 * @title IWallet
 * @notice Interface for the BaseWallet
 */
interface IWallet {
    /**
     * @notice Returns the wallet owner.
     * @return The wallet owner address.
     */
    function owner() external view returns (address);

    /**
     * @notice Returns the number of authorised modules.
     * @return The number of authorised modules.
     */
    function modules() external view returns (uint);

    /**
     * @notice Sets a new owner for the wallet.
     * @param _newOwner The new owner.
     */
    function setOwner(address _newOwner) external;

    /**
     * @notice Checks if a module is authorised on the wallet.
     * @param _module The module address to check.
     * @return `true` if the module is authorised, otherwise `false`.
     */
    function authorised(address _module) external view returns (bool);

    /**
     * @notice Returns the module responsible for a static call redirection.
     * @param _sig The signature of the static call.
     * @return the module doing the redirection
     */
    function enabled(bytes4 _sig) external view returns (address);

    /**
     * @notice Enables/Disables a module.
     * @param _module The target module.
     * @param _value Set to `true` to authorise the module.
     */
    function authoriseModule(address _module, bool _value) external;

    /**
    * @notice Enables a static method by specifying the target module to which the call must be delegated.
    * @param _module The target module.
    * @param _method The static method signature.
    */
    function enableStaticCall(address _module, bytes4 _method) external;
}

File 11 of 11: SafeMath.sol
pragma solidity ^0.6.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract ILockStorage","name":"_lockStorage","type":"address"},{"internalType":"contract IComptroller","name":"_comptroller","type":"address"},{"internalType":"contract ICompoundRegistry","name":"_compoundRegistry","type":"address"},{"internalType":"contract IVersionManager","name":"_versionManager","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_wallet","type":"address"},{"indexed":true,"internalType":"bytes32","name":"_loanId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_collateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"_collateralAmount","type":"uint256"}],"name":"CollateralAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_wallet","type":"address"},{"indexed":true,"internalType":"bytes32","name":"_loanId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_collateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"_collateralAmount","type":"uint256"}],"name":"CollateralRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_wallet","type":"address"},{"indexed":true,"internalType":"bytes32","name":"_loanId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_debtToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_debtAmount","type":"uint256"}],"name":"DebtAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_wallet","type":"address"},{"indexed":true,"internalType":"bytes32","name":"_loanId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_debtToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_debtAmount","type":"uint256"}],"name":"DebtRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"FeatureCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_wallet","type":"address"},{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_invested","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_period","type":"uint256"}],"name":"InvestmentAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_wallet","type":"address"},{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_fraction","type":"uint256"}],"name":"InvestmentRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_wallet","type":"address"},{"indexed":true,"internalType":"bytes32","name":"_loanId","type":"bytes32"}],"name":"LoanClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_wallet","type":"address"},{"indexed":true,"internalType":"bytes32","name":"_loanId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_collateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"_collateralAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_debtToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_debtAmount","type":"uint256"}],"name":"LoanOpened","type":"event"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"bytes32","name":"_loanId","type":"bytes32"},{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"uint256","name":"_collateralAmount","type":"uint256"}],"name":"addCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"bytes32","name":"_loanId","type":"bytes32"},{"internalType":"address","name":"_debtToken","type":"address"},{"internalType":"uint256","name":"_debtAmount","type":"uint256"}],"name":"addDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_period","type":"uint256"}],"name":"addInvestment","outputs":[{"internalType":"uint256","name":"_invested","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"bytes32","name":"_loanId","type":"bytes32"}],"name":"closeLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"compoundRegistry","outputs":[{"internalType":"contract ICompoundRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"comptroller","outputs":[{"internalType":"contract IComptroller","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"getInvestment","outputs":[{"internalType":"uint256","name":"_tokenValue","type":"uint256"},{"internalType":"uint256","name":"_periodEnd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"getLoan","outputs":[{"internalType":"uint8","name":"_status","type":"uint8"},{"internalType":"uint256","name":"_ethValue","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"getRequiredSignatures","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"enum IFeature.OwnerSignature","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStaticCallSignatures","outputs":[{"internalType":"bytes4[]","name":"_sigs","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"address","name":"_feature","type":"address"}],"name":"isFeatureAuthorisedInVersionManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"uint256","name":"_collateralAmount","type":"uint256"},{"internalType":"address","name":"_debtToken","type":"address"},{"internalType":"uint256","name":"_debtAmount","type":"uint256"}],"name":"openLoan","outputs":[{"internalType":"bytes32","name":"_loanId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"recoverToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"bytes32","name":"_loanId","type":"bytes32"},{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"uint256","name":"_collateralAmount","type":"uint256"}],"name":"removeCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"bytes32","name":"_loanId","type":"bytes32"},{"internalType":"address","name":"_debtToken","type":"address"},{"internalType":"uint256","name":"_debtAmount","type":"uint256"}],"name":"removeDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_fraction","type":"uint256"}],"name":"removeInvestment","outputs":[],"stateMutability":"nonpayable","type":"function"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061011b5760003560e01c8063a287fdbd116100b2578063b352d4af11610081578063e8ca0ca311610066578063e8ca0ca31461047a578063ea2347e6146104b4578063ec9e13aa1461050c5761011b565b8063b352d4af146103f9578063cac7495c146104335761011b565b8063a287fdbd146102fb578063a90cf0af1461033d578063ac5f8d5114610369578063b02c808d146103a35761011b565b806381c44b5c116100ee57806381c44b5c1461021c57806385a13f381461026557806398d534281461029f5780639be65a60146102d55761011b565b806319ab453c146101205780633b73d67f1461014857806347eb8d43146101f05780635fe3b56714610214575b600080fd5b6101466004803603602081101561013657600080fd5b50356001600160a01b0316610548565b005b6101c86004803603604081101561015e57600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561018957600080fd5b82018360208201111561019b57600080fd5b803590602001918460018302840111640100000000831117156101bd57600080fd5b50909250905061054b565b604051808381526020018260038111156101de57fe5b81526020019250505060405180910390f35b6101f8610556565b604080516001600160a01b039092168252519081900360200190f35b6101f8610565565b6102486004803603604081101561023257600080fd5b506001600160a01b038135169060200135610574565b6040805160ff909316835260208301919091528051918290030190f35b6101466004803603608081101561027b57600080fd5b506001600160a01b0381358116916020810135916040820135169060600135610695565b610146600480360360608110156102b557600080fd5b506001600160a01b03813581169160208101359091169060400135610859565b610146600480360360208110156102eb57600080fd5b50356001600160a01b0316610ae7565b6103296004803603604081101561031157600080fd5b506001600160a01b0381358116916020013516610c66565b604080519115158252519081900360200190f35b6101466004803603604081101561035357600080fd5b506001600160a01b038135169060200135610d0d565b6101466004803603608081101561037f57600080fd5b506001600160a01b03813581169160208101359160408201351690606001356110e8565b6103e7600480360360a08110156103b957600080fd5b506001600160a01b0381358116916020810135821691604082013591606081013590911690608001356112aa565b60408051918252519081900360200190f35b6101466004803603608081101561040f57600080fd5b506001600160a01b038135811691602081013591604082013516906060013561161a565b6104616004803603604081101561044957600080fd5b506001600160a01b03813581169160200135166117de565b6040805192835260208301919091528051918290030190f35b6101466004803603608081101561049057600080fd5b506001600160a01b038135811691602081013591604082013516906060013561198a565b6104bc611b4c565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156104f85781810151838201526020016104e0565b505050509050019250505060405180910390f35b6103e76004803603608081101561052257600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611b51565b50565b600180935093915050565b6003546001600160a01b031681565b6002546001600160a01b031681565b6000806000806000600260009054906101000a90046001600160a01b03166001600160a01b0316635ec88c79886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060606040518083038186803b1580156105de57600080fd5b505afa1580156105f2573d6000803e3d6000fd5b505050506040513d606081101561060857600080fd5b50805160208201516040909201519094509092509050821561065b5760405162461bcd60e51b81526004018080602001828103825260238152602001806133966023913960400191505060405180910390fd5b811561066f575060019350915061068e9050565b80156106835760029450925061068e915050565b600080945094505050505b9250929050565b836106a08133611d07565b60005460408051631293efbb60e21b81526001600160a01b038089166004830152915188939290921691634a4fbeec91602480820192602092909190829003018186803b1580156106f057600080fd5b505afa158015610704573d6000803e3d6000fd5b505050506040513d602081101561071a57600080fd5b505115610762576040805162461bcd60e51b815260206004820152601160248201527010918e881dd85b1b195d081b1bd8dad959607a1b604482015290519081900360640190fd5b60035460408051637e5a4eb960e01b81526001600160a01b03878116600483015291516000939290921691637e5a4eb991602480820192602092909190829003018186803b1580156107b357600080fd5b505afa1580156107c7573d6000803e3d6000fd5b505050506040513d60208110156107dd57600080fd5b50516002549091506107fb90889083906001600160a01b0316611d76565b61080787868387611eac565b604080516001600160a01b0387811682526020820187905282518993918b16927ff6669d5e7ff92997c22e9fe3b54f53ed18448cf5fdccb3eb1dc5004798fbb41492908290030190a350505050505050565b826108648133611d07565b60005460408051631293efbb60e21b81526001600160a01b038088166004830152915187939290921691634a4fbeec91602480820192602092909190829003018186803b1580156108b457600080fd5b505afa1580156108c8573d6000803e3d6000fd5b505050506040513d60208110156108de57600080fd5b505115610926576040805162461bcd60e51b815260206004820152601160248201527010918e881dd85b1b195d081b1bd8dad959607a1b604482015290519081900360640190fd5b61271083111561097d576040805162461bcd60e51b815260206004820152601a60248201527f434d3a20696e76616c6964206672616374696f6e2076616c7565000000000000604482015290519081900360640190fd5b60035460408051637e5a4eb960e01b81526001600160a01b03878116600483015291516000939290921691637e5a4eb991602480820192602092909190829003018186803b1580156109ce57600080fd5b505afa1580156109e2573d6000803e3d6000fd5b505050506040513d60208110156109f857600080fd5b5051604080516370a0823160e01b81526001600160a01b0389811660048301529151929350600092918416916370a0823191602480820192602092909190829003018186803b158015610a4a57600080fd5b505afa158015610a5e573d6000803e3d6000fd5b505050506040513d6020811015610a7457600080fd5b50519050610a988783610a93612710610a8d868b612170565b906121d0565b612212565b604080516001600160a01b038881168252602082018890528251908a16927f9aa275f858ea6286ee2cacd32cd2ae55f918a310ee6d0320caad244ee9d6109e928290030190a250505050505050565b6000816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610b3657600080fd5b505afa158015610b4a573d6000803e3d6000fd5b505050506040513d6020811015610b6057600080fd5b5051600154604080516001600160a01b039283166024820152604480820185905282518083039091018152606490910182526020810180516001600160e01b03167fa9059cbb00000000000000000000000000000000000000000000000000000000178152915181519495509286169390929182918083835b60208310610bf85780518252601f199092019160209182019101610bd9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610c5a576040519150601f19603f3d011682016040523d82523d6000602084013e610c5f565b606091505b5050505050565b600154604080517f5a51fd430000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152848116602483015291516000939290921691635a51fd4391604480820192602092909190829003018186803b158015610cd857600080fd5b505afa158015610cec573d6000803e3d6000fd5b505050506040513d6020811015610d0257600080fd5b505190505b92915050565b81610d188133611d07565b60005460408051631293efbb60e21b81526001600160a01b038087166004830152915186939290921691634a4fbeec91602480820192602092909190829003018186803b158015610d6857600080fd5b505afa158015610d7c573d6000803e3d6000fd5b505050506040513d6020811015610d9257600080fd5b505115610dda576040805162461bcd60e51b815260206004820152601160248201527010918e881dd85b1b195d081b1bd8dad959607a1b604482015290519081900360640190fd5b600254604080517fabfceffc0000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301529151606093929092169163abfceffc91602480820192600092909190829003018186803b158015610e4457600080fd5b505afa158015610e58573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610e8157600080fd5b8101908080516040519392919084640100000000821115610ea157600080fd5b908301906020820185811115610eb657600080fd5b8251866020820283011164010000000082111715610ed357600080fd5b82525081516020918201928201910280838360005b83811015610f00578181015183820152602001610ee8565b50505050905001604052505050905060005b81518110156110aa576000828281518110610f2957fe5b602002602001015190506000816001600160a01b03166317bfdfbc896040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b158015610f8457600080fd5b505af1158015610f98573d6000803e3d6000fd5b505050506040513d6020811015610fae57600080fd5b5051905080156110a057610fc388838361240c565b6000826001600160a01b03166370a082318a6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561101257600080fd5b505afa158015611026573d6000803e3d6000fd5b505050506040513d602081101561103c57600080fd5b505190508061109e57600254604080516001600160a01b038681166024808401919091528351808403909101815260449092019092526020810180516001600160e01b0316630ede4edd60e41b17905261109c928c92169060009061297b565b505b505b5050600101610f12565b5060405184906001600160a01b038716907f07e4a0c6f06275f83bcf78e5a10eb7f5515574d593bce993377961f4133b951c90600090a35050505050565b836110f38133611d07565b60005460408051631293efbb60e21b81526001600160a01b038089166004830152915188939290921691634a4fbeec91602480820192602092909190829003018186803b15801561114357600080fd5b505afa158015611157573d6000803e3d6000fd5b505050506040513d602081101561116d57600080fd5b5051156111b5576040805162461bcd60e51b815260206004820152601160248201527010918e881dd85b1b195d081b1bd8dad959607a1b604482015290519081900360640190fd5b60035460408051637e5a4eb960e01b81526001600160a01b03878116600483015291516000939290921691637e5a4eb991602480820192602092909190829003018186803b15801561120657600080fd5b505afa15801561121a573d6000803e3d6000fd5b505050506040513d602081101561123057600080fd5b5051905061123f878286612b5c565b60025461125890889083906001600160a01b0316612db1565b604080516001600160a01b0387811682526020820187905282518993918b16927ff1dec7a92ef063b16d2098bb05803ed604936a7ff30f0d245fe881baf96e8e6b92908290030190a350505050505050565b6000856112b78133611d07565b60005460408051631293efbb60e21b81526001600160a01b03808b16600483015291518a939290921691634a4fbeec91602480820192602092909190829003018186803b15801561130757600080fd5b505afa15801561131b573d6000803e3d6000fd5b505050506040513d602081101561133157600080fd5b505115611379576040805162461bcd60e51b815260206004820152601160248201527010918e881dd85b1b195d081b1bd8dad959607a1b604482015290519081900360640190fd5b6040805160028082526060808301845292602083019080368337505060035460408051637e5a4eb960e01b81526001600160a01b038d811660048301529151949550911692637e5a4eb992506024808301926020929190829003018186803b1580156113e457600080fd5b505afa1580156113f8573d6000803e3d6000fd5b505050506040513d602081101561140e57600080fd5b50518151829060009061141d57fe5b6001600160a01b0392831660209182029290920181019190915260035460408051637e5a4eb960e01b81528a8516600482015290519190931692637e5a4eb9926024808301939192829003018186803b15801561147957600080fd5b505afa15801561148d573d6000803e3d6000fd5b505050506040513d60208110156114a357600080fd5b50518151829060019081106114b457fe5b6001600160a01b0392831660209182029290920181019190915260025460405160248101838152855160448301528551611575958f9594169360009388939283926064909201918581019102808383895b8381101561151d578181015183820152602001611505565b50506040805193909501838103601f19018452909452506020810180517fc2998238000000000000000000000000000000000000000000000000000000006001600160e01b03909116179052945061297b9350505050565b50611596898260008151811061158757fe5b60200260200101518a8a612f27565b6115b68987836001815181106115a857fe5b602002602001015188611eac565b604080516001600160a01b038a81168252602082018a90528881168284015260608201889052915186928c16917ff9d7e11fb5d8d1e0a4be344a6a6adfb912161747edf926fb283150d07c39c108919081900360800190a350505095945050505050565b836116258133611d07565b60005460408051631293efbb60e21b81526001600160a01b038089166004830152915188939290921691634a4fbeec91602480820192602092909190829003018186803b15801561167557600080fd5b505afa158015611689573d6000803e3d6000fd5b505050506040513d602081101561169f57600080fd5b5051156116e7576040805162461bcd60e51b815260206004820152601160248201527010918e881dd85b1b195d081b1bd8dad959607a1b604482015290519081900360640190fd5b60035460408051637e5a4eb960e01b81526001600160a01b03878116600483015291516000939290921691637e5a4eb991602480820192602092909190829003018186803b15801561173857600080fd5b505afa15801561174c573d6000803e3d6000fd5b505050506040513d602081101561176257600080fd5b505160025490915061178090889083906001600160a01b0316611d76565b61178c87828787612f27565b604080516001600160a01b0387811682526020820187905282518993918b16927fdd016248708c391ccb5c72f9258127c75b9b291ac1479513fe4f331c3489013792908290030190a350505050505050565b60035460408051637e5a4eb960e01b81526001600160a01b038481166004830152915160009384938493911691637e5a4eb991602480820192602092909190829003018186803b15801561183157600080fd5b505afa158015611845573d6000803e3d6000fd5b505050506040513d602081101561185b57600080fd5b5051604080516370a0823160e01b81526001600160a01b0388811660048301529151929350600092918416916370a0823191602480820192602092909190829003018186803b1580156118ad57600080fd5b505afa1580156118c1573d6000803e3d6000fd5b505050506040513d60208110156118d757600080fd5b5051604080517f182df0f500000000000000000000000000000000000000000000000000000000815290519192506000916001600160a01b0385169163182df0f5916004808301926020929190829003018186803b15801561193857600080fd5b505afa15801561194c573d6000803e3d6000fd5b505050506040513d602081101561196257600080fd5b5051905061197c670de0b6b3a7640000610a8d8484612170565b976000975095505050505050565b836119958133611d07565b60005460408051631293efbb60e21b81526001600160a01b038089166004830152915188939290921691634a4fbeec91602480820192602092909190829003018186803b1580156119e557600080fd5b505afa1580156119f9573d6000803e3d6000fd5b505050506040513d6020811015611a0f57600080fd5b505115611a57576040805162461bcd60e51b815260206004820152601160248201527010918e881dd85b1b195d081b1bd8dad959607a1b604482015290519081900360640190fd5b60035460408051637e5a4eb960e01b81526001600160a01b03878116600483015291516000939290921691637e5a4eb991602480820192602092909190829003018186803b158015611aa857600080fd5b505afa158015611abc573d6000803e3d6000fd5b505050506040513d6020811015611ad257600080fd5b50519050611ae187828661240c565b600254611afa90889083906001600160a01b0316612db1565b604080516001600160a01b0387811682526020820187905282518993918b16927fbfa42ea7d37497e6a09441fadba47d64b610b6b1183d895dd0a42507973430bf92908290030190a350505050505050565b606090565b600084611b5e8133611d07565b60005460408051631293efbb60e21b81526001600160a01b03808a166004830152915189939290921691634a4fbeec91602480820192602092909190829003018186803b158015611bae57600080fd5b505afa158015611bc2573d6000803e3d6000fd5b505050506040513d6020811015611bd857600080fd5b505115611c20576040805162461bcd60e51b815260206004820152601160248201527010918e881dd85b1b195d081b1bd8dad959607a1b604482015290519081900360640190fd5b60035460408051637e5a4eb960e01b81526001600160a01b03898116600483015291516000939290921691637e5a4eb991602480820192602092909190829003018186803b158015611c7157600080fd5b505afa158015611c85573d6000803e3d6000fd5b505050506040513d6020811015611c9b57600080fd5b50519050611cab88828989612f27565b604080516001600160a01b038981168252602082018990528183018890529151889650918a16917ff8eece150ed2126815122a6def9737751aecd814379d4ce8c9edd07133a49cdb9181900360600190a2505050949350505050565b611d118282610c66565b80611d215750611d218282613250565b611d72576040805162461bcd60e51b815260206004820152601c60248201527f42463a206d757374206265206f776e6572206f72206665617475726500000000604482015290519081900360640190fd5b5050565b6000816001600160a01b031663929fe9a185856040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015611dd657600080fd5b505afa158015611dea573d6000803e3d6000fd5b505050506040513d6020811015611e0057600080fd5b5051905080611ea657604080516001808252818301909252606091602080830190803683370190505090508381600081518110611e3957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050611ea385846000846040516024018080602001828103825283818151815260200191508051906020019060200280838360008381101561151d578181015183820152602001611505565b50505b50505050565b6001600160a01b038216611f07576040805162461bcd60e51b815260206004820152601e60248201527f434d3a204e6f206d61726b657420666f722074617267657420746f6b656e0000604482015290519081900360640190fd5b60008111611f55576040805162461bcd60e51b81526020600482015260166024820152750434d3a20616d6f756e742063616e6e6f7420626520360541b604482015290519081900360640190fd5b60006001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14611ff957836001600160a01b03166370a08231866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611fc857600080fd5b505afa158015611fdc573d6000803e3d6000fd5b505050506040513d6020811015611ff257600080fd5b5051612005565b846001600160a01b0316315b6040805160248082018690528251808303909101815260449091019091526020810180516001600160e01b03167fc5ebeaec00000000000000000000000000000000000000000000000000000000179052909150612069908690859060009061297b565b5060006001600160a01b03851673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461210e57846001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156120dd57600080fd5b505afa1580156120f1573d6000803e3d6000fd5b505050506040513d602081101561210757600080fd5b505161211a565b856001600160a01b0316315b9050818111611ea3576040805162461bcd60e51b815260206004820152601160248201527f434d3a20626f72726f77206661696c6564000000000000000000000000000000604482015290519081900360640190fd5b60008261217f57506000610d07565b8282028284828161218c57fe5b04146121c95760405162461bcd60e51b81526004018080602001828103825260218152602001806133756021913960400191505060405180910390fd5b9392505050565b60006121c983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506132d2565b60008111612260576040805162461bcd60e51b81526020600482015260166024820152750434d3a20616d6f756e742063616e6e6f7420626520360541b604482015290519081900360640190fd5b6000826001600160a01b03166370a08231856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156122af57600080fd5b505afa1580156122c3573d6000803e3d6000fd5b505050506040513d60208110156122d957600080fd5b50516040805160248082018690528251808303909101815260449091019091526020810180516001600160e01b03167fdb006a750000000000000000000000000000000000000000000000000000000017905290915061233f908590859060009061297b565b5080836001600160a01b03166370a08231866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561238e57600080fd5b505afa1580156123a2573d6000803e3d6000fd5b505050506040513d60208110156123b857600080fd5b505110611ea6576040805162461bcd60e51b815260206004820152601160248201527f434d3a2072656465656d206661696c6564000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b038216612467576040805162461bcd60e51b815260206004820152601e60248201527f434d3a204e6f206d61726b657420666f722074617267657420746f6b656e0000604482015290519081900360640190fd5b600081116124b5576040805162461bcd60e51b81526020600482015260166024820152750434d3a20616d6f756e742063616e6e6f7420626520360541b604482015290519081900360640190fd5b6060826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156124f057600080fd5b505afa158015612504573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561252d57600080fd5b810190808051604051939291908464010000000082111561254d57600080fd5b90830190602082018581111561256257600080fd5b825164010000000081118282018810171561257c57600080fd5b82525081516020918201929091019080838360005b838110156125a9578181015183820152602001612591565b50505050905090810190601f1680156125d65780820380516001836020036101000a031916815260200191505b50604052505050905060008060405160200180807f6345544800000000000000000000000000000000000000000000000000000000815250600401905060405160208183030381529060405280519060200120836040516020018082805190602001908083835b6020831061265c5780518252601f19909201916020918201910161263d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120141561270d576040805160048152602481019091526020810180516001600160e01b03167f4e4d9fea000000000000000000000000000000000000000000000000000000001790526001600160a01b0387163192506126fb9087908790879061297b565b50506001600160a01b03851631612927565b6000856001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561274857600080fd5b505afa15801561275c573d6000803e3d6000fd5b505050506040513d602081101561277257600080fd5b5051604080516370a0823160e01b81526001600160a01b038a811660048301529151929350908316916370a0823191602480820192602092909190829003018186803b1580156127c157600080fd5b505afa1580156127d5573d6000803e3d6000fd5b505050506040513d60208110156127eb57600080fd5b5051604080516001600160a01b038916602482015260448082018990528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052909350612847908890839060009061297b565b506040805160248082018890528251808303909101815260449091019091526020810180516001600160e01b03167f0e752702000000000000000000000000000000000000000000000000000000001790526128a9908890889060009061297b565b50806001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156128f757600080fd5b505afa15801561290b573d6000803e3d6000fd5b505050506040513d602081101561292157600080fd5b50519150505b818110611ea3576040805162461bcd60e51b815260206004820152601660248201527f434d3a207265706179426f72726f77206661696c656400000000000000000000604482015290519081900360640190fd5b6001546040517f915c77b90000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301908152868216602484015260448301869052608060648401908152855160848501528551606095939093169363915c77b9938a938a938a938a9360a490910190602085019080838360005b83811015612a165781810151838201526020016129fe565b50505050905090810190601f168015612a435780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015612a6557600080fd5b505af1158015612a79573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612aa257600080fd5b8101908080516040519392919084640100000000821115612ac257600080fd5b908301906020820185811115612ad757600080fd5b8251640100000000811182820188101715612af157600080fd5b82525081516020918201929091019080838360005b83811015612b1e578181015183820152602001612b06565b50505050905090810190601f168015612b4b5780820380516001836020036101000a031916815260200191505b506040525050509050949350505050565b6001600160a01b038216612bb7576040805162461bcd60e51b815260206004820152601e60248201527f434d3a204e6f206d61726b657420666f722074617267657420746f6b656e0000604482015290519081900360640190fd5b60008111612c05576040805162461bcd60e51b81526020600482015260166024820152750434d3a20616d6f756e742063616e6e6f7420626520360541b604482015290519081900360640190fd5b6000826001600160a01b03166370a08231856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612c5457600080fd5b505afa158015612c68573d6000803e3d6000fd5b505050506040513d6020811015612c7e57600080fd5b50516040805160248082018690528251808303909101815260449091019091526020810180516001600160e01b03167f852a12e300000000000000000000000000000000000000000000000000000000179052909150612ce4908590859060009061297b565b5080836001600160a01b03166370a08231866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612d3357600080fd5b505afa158015612d47573d6000803e3d6000fd5b505050506040513d6020811015612d5d57600080fd5b505110611ea6576040805162461bcd60e51b815260206004820152601b60248201527f434d3a2072656465656d556e6465726c79696e67206661696c65640000000000604482015290519081900360640190fd5b6000826001600160a01b03166370a08231856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612e0057600080fd5b505afa158015612e14573d6000803e3d6000fd5b505050506040513d6020811015612e2a57600080fd5b5051604080517f95dd91930000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301529151929350600092918616916395dd919391602480820192602092909190829003018186803b158015612e9557600080fd5b505afa158015612ea9573d6000803e3d6000fd5b505050506040513d6020811015612ebf57600080fd5b5051905081158015612ecf575080155b15610c5f57604080516001600160a01b0386166024808301919091528251808303909101815260449091019091526020810180516001600160e01b0316630ede4edd60e41b179052611ea3908690859060009061297b565b6001600160a01b038316612f82576040805162461bcd60e51b815260206004820152601e60248201527f434d3a204e6f206d61726b657420666f722074617267657420746f6b656e0000604482015290519081900360640190fd5b60008111612fd0576040805162461bcd60e51b81526020600482015260166024820152750434d3a20616d6f756e742063616e6e6f7420626520360541b604482015290519081900360640190fd5b6000836001600160a01b03166370a08231866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561301f57600080fd5b505afa158015613033573d6000803e3d6000fd5b505050506040513d602081101561304957600080fd5b505190506001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156130c9576040805160048152602481019091526020810180516001600160e01b03167f1249c58b000000000000000000000000000000000000000000000000000000001790526130c39086908690859061297b565b50613184565b604080516001600160a01b038616602482015260448082018590528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052613120908690859060009061297b565b506040805160248082018590528251808303909101815260449091019091526020810180516001600160e01b03167fa0712d6800000000000000000000000000000000000000000000000000000000179052613182908690869060009061297b565b505b80846001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156131d257600080fd5b505afa1580156131e6573d6000803e3d6000fd5b505050506040513d60208110156131fc57600080fd5b505111610c5f576040805162461bcd60e51b815260206004820152600f60248201527f434d3a206d696e74206661696c65640000000000000000000000000000000000604482015290519081900360640190fd5b6000816001600160a01b0316836001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561329557600080fd5b505afa1580156132a9573d6000803e3d6000fd5b505050506040513d60208110156132bf57600080fd5b50516001600160a01b0316149392505050565b6000818361335e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561332357818101518382015260200161330b565b50505050905090810190601f1680156133505780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161336a57fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77434d3a206661696c656420746f20676574206163636f756e74206c6971756964697479a2646970667358221220c1e55394c7046c4ba5ed000f812ce903bca5e46892190237dddfb31606e83b6e64736f6c634300060c0033

Deployed Bytecode Sourcemap

2001:17780:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3645:60:0;;;;;;;;;;;;;;;;-1:-1:-1;3645:60:0;-1:-1:-1;;;;;3645:60:0;;:::i;:::-;;3650:165:1;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3650:165:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3650:165:1;;-1:-1:-1;3650:165:1;-1:-1:-1;3650:165:1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2226:41;;;:::i;:::-;;;;-1:-1:-1;;;;;2226:41:1;;;;;;;;;;;;;;2137:31;;;:::i;10277:506::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;10277:506:1;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;8512:492;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;8512:492:1;;;;;;;;;;;;;;;;;;;;:::i;11965:525::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;11965:525:1;;;;;;;;;;;;;;;;;:::i;3181:242:0:-;;;;;;;;;;;;;;;;-1:-1:-1;3181:242:0;-1:-1:-1;;;;;3181:242:0;;:::i;4122:193::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;4122:193:0;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;5485:937:1;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;5485:937:1;;;;;;;;:::i;7636:527::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;7636:527:1;;;;;;;;;;;;;;;;;;;;:::i;4355:830::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;4355:830:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;6763:524;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;6763:524:1;;;;;;;;;;;;;;;;;;;;:::i;12818:464::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;12818:464:1;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;9351:489;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;9351:489:1;;;;;;;;;;;;;;;;;;;;:::i;3972:100:0:-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11274:471:1;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;11274:471:1;;;;;;;;;;;;;;;;;;;;;;:::i;3645:60:0:-;;:::o;3650:165:1:-;3781:1;;3650:165;;;;;;:::o;2226:41::-;;;-1:-1:-1;;;;;2226:41:1;;:::o;2137:31::-;;;-1:-1:-1;;;;;2137:31:1;;:::o;10277:506::-;10403:13;10418:17;10452:10;10464:14;10480;10498:11;;;;;;;;;-1:-1:-1;;;;;10498:11:1;-1:-1:-1;;;;;10498:31:1;;10530:7;10498:40;;;;;;;;;;;;;-1:-1:-1;;;;;10498:40:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10498:40:1;;;;;;;;;;;;;-1:-1:-1;10498:40:1;;-1:-1:-1;10498:40:1;-1:-1:-1;10556:10:1;;10548:58;;;;-1:-1:-1;;;10548:58:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10620:13;;10616:65;;-1:-1:-1;10657:1:1;;-1:-1:-1;10660:9:1;-1:-1:-1;10649:21:1;;-1:-1:-1;10649:21:1;10616:65;10694:13;;10690:65;;10731:1;;-1:-1:-1;10734:9:1;-1:-1:-1;10723:21:1;;-1:-1:-1;;10723:21:1;10690:65;10772:1;10774;10764:12;;;;;;;10277:506;;;;;;:::o;8512:492::-;8692:7;2813:51:0;2844:7;2853:10;2813:30;:51::i;:::-;1723:11:::1;::::0;:29:::1;::::0;;-1:-1:-1;;;1723:29:0;;-1:-1:-1;;;;;1723:29:0;;::::1;;::::0;::::1;::::0;;;8726:7:1;;1723:11:0;;;::::1;::::0;:20:::1;::::0;:29;;;;;::::1;::::0;;;;;;;;;:11;:29;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;1723:29:0;1722:30:::1;1714:60;;;::::0;;-1:-1:-1;;;1714:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1714:60:0;;;;;;;;;;;;;::::1;;8766:16:1::2;::::0;:38:::2;::::0;;-1:-1:-1;;;8766:38:1;;-1:-1:-1;;;;;8766:38:1;;::::2;;::::0;::::2;::::0;;;8749:14:::2;::::0;8766:16;;;::::2;::::0;:26:::2;::::0;:38;;;;;::::2;::::0;;;;;;;;;:16;:38;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;8766:38:1;8859:11:::2;::::0;8766:38;;-1:-1:-1;8814:58:1::2;::::0;8834:7;;8766:38;;-1:-1:-1;;;;;8859:11:1::2;8814:19;:58::i;:::-;8882:48;8889:7;8898:10;8910:6;8918:11;8882:6;:48::i;:::-;8945:52;::::0;;-1:-1:-1;;;;;8945:52:1;;::::2;::::0;;::::2;::::0;::::2;::::0;;;;;8964:7;;8945:52;;::::2;::::0;::::2;::::0;;;;;;;::::2;1784:1:0;2874::::1;8512:492:1::0;;;;;:::o;11965:525::-;12123:7;2813:51:0;2844:7;2853:10;2813:30;:51::i;:::-;1723:11:::1;::::0;:29:::1;::::0;;-1:-1:-1;;;1723:29:0;;-1:-1:-1;;;;;1723:29:0;;::::1;;::::0;::::1;::::0;;;12157:7:1;;1723:11:0;;;::::1;::::0;:20:::1;::::0;:29;;;;;::::1;::::0;;;;;;;;;:11;:29;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;1723:29:0;1722:30:::1;1714:60;;;::::0;;-1:-1:-1;;;1714:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1714:60:0;;;;;;;;;;;;;::::1;;12201:5:1::2;12188:9;:18;;12180:57;;;::::0;;-1:-1:-1;;;12180:57:1;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;12264:16;::::0;:34:::2;::::0;;-1:-1:-1;;;12264:34:1;;-1:-1:-1;;;;;12264:34:1;;::::2;;::::0;::::2;::::0;;;12247:14:::2;::::0;12264:16;;;::::2;::::0;:26:::2;::::0;:34;;;;;::::2;::::0;;;;;;;;;:16;:34;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;12264:34:1;12322::::2;::::0;;-1:-1:-1;;;12322:34:1;;-1:-1:-1;;;;;12322:34:1;;::::2;;::::0;::::2;::::0;;;12264;;-1:-1:-1;12308:11:1::2;::::0;12322:25;;::::2;::::0;::::2;::::0;:34;;;;;12264::::2;::::0;12322;;;;;;;;:25;:34;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;12322:34:1;;-1:-1:-1;12366:57:1::2;12373:7:::0;12382:6;12390:32:::2;12416:5;12390:21;12322:34:::0;12401:9;12390:10:::2;:21::i;:::-;:25:::0;::::2;:32::i;:::-;12366:6;:57::i;:::-;12438:45;::::0;;-1:-1:-1;;;;;12438:45:1;;::::2;::::0;;::::2;::::0;::::2;::::0;;;;;;;::::2;::::0;::::2;::::0;;;;;;::::2;1784:1:0;;2874::::1;11965:525:1::0;;;;:::o;3181:242:0:-;3255:10;3274:6;-1:-1:-1;;;;;3268:23:0;;3300:4;3268:38;;;;;;;;;;;;;-1:-1:-1;;;;;3268:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3268:38:0;3392:14;;3328:87;;;-1:-1:-1;;;;;3392:14:0;;;3328:87;;;;;;;;;;;;;;;;;;;;;;;;;;;3268:38;3328:87;;;;-1:-1:-1;;;;;3328:87:0;3351:31;3328:87;;;3316:100;;;;3268:38;;-1:-1:-1;3316:11:0;;;;3328:87;;3316:100;;;;;3328:87;3316:100;;;;;;;;;;-1:-1:-1;;3316:100:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3181:242;;:::o;4122:193::-;4255:14;;:53;;;;;;-1:-1:-1;;;;;4255:53:0;;;;;;;;;;;;;;;;4232:4;;4255:14;;;;;:34;;:53;;;;;;;;;;;;;;;:14;:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4255:53:0;;-1:-1:-1;4122:193:0;;;;;:::o;5485:937:1:-;5610:7;2813:51:0;2844:7;2853:10;2813:30;:51::i;:::-;1723:11:::1;::::0;:29:::1;::::0;;-1:-1:-1;;;1723:29:0;;-1:-1:-1;;;;;1723:29:0;;::::1;;::::0;::::1;::::0;;;5644:7:1;;1723:11:0;;;::::1;::::0;:20:::1;::::0;:29;;;;;::::1;::::0;;;;;;;;;:11;:29;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;1723:29:0;1722:30:::1;1714:60;;;::::0;;-1:-1:-1;;;1714:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1714:60:0;;;;;;;;;;;;;::::1;;5694:11:1::2;::::0;:32:::2;::::0;;;;;-1:-1:-1;;;;;5694:32:1;;::::2;;::::0;::::2;::::0;;;5667:24:::2;::::0;5694:11;;;::::2;::::0;:23:::2;::::0;:32;;;;;:11:::2;::::0;:32;;;;;;;;:11;:32;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;-1:-1:-1::0;;5694:32:1::2;::::0;::::2;;::::0;::::2;::::0;::::2;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;::::0;;::::2;::::0;::::2;::::0;::::2;::::0;;::::2;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;::::0;;-1:-1:-1;5694:32:1;;::::2;::::0;;::::2;::::0;;::::2;::::0;::::2;::::0;;;::::2;;;;;;;;::::0;;::::2;::::0;;;::::2;::::0;::::2;;;;;;;;;;;;;;::::0;::::2;;5667:59;;5741:6;5736:637;5757:7;:14;5753:1;:18;5736:637;;;5792:14;5809:7;5817:1;5809:10;;;;;;;;;;;;;;5792:27;;5833:9;5853:6;-1:-1:-1::0;;;;;5845:36:1::2;;5882:7;5845:45;;;;;;;;;;;;;-1:-1:-1::0;;;;;5845:45:1::2;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;5845:45:1;;-1:-1:-1;5908:8:1;;5904:459:::2;;5936:34;5948:7;5957:6;5965:4;5936:11;:34::i;:::-;5988:15;6014:6;-1:-1:-1::0;;;;;6006:25:1::2;;6032:7;6006:34;;;;;;;;;;;;;-1:-1:-1::0;;;;;6006:34:1::2;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;6006:34:1;;-1:-1:-1;6062:15:1;6058:291:::2;;6180:11;::::0;6245:63:::2;::::0;;-1:-1:-1;;;;;6245:63:1;;::::2;;::::0;;::::2;::::0;;;;;;;;;;;;;;;;;;;;;::::2;::::0;::::2;::::0;;-1:-1:-1;;;;;6245:63:1::2;-1:-1:-1::0;;;6245:63:1::2;::::0;;6101:229:::2;::::0;6139:7;;6180:11:::2;::::0;::::2;::::0;6101:12:::2;:229::i;:::-;;6058:291;5904:459;;-1:-1:-1::0;;5773:3:1::2;;5736:637;;;-1:-1:-1::0;6387:28:1::2;::::0;6407:7;;-1:-1:-1;;;;;6387:28:1;::::2;::::0;::::2;::::0;;;::::2;1784:1:0;2874::::1;5485:937:1::0;;;:::o;7636:527::-;7832:7;2813:51:0;2844:7;2853:10;2813:30;:51::i;:::-;1723:11:::1;::::0;:29:::1;::::0;;-1:-1:-1;;;1723:29:0;;-1:-1:-1;;;;;1723:29:0;;::::1;;::::0;::::1;::::0;;;7866:7:1;;1723:11:0;;;::::1;::::0;:20:::1;::::0;:29;;;;;::::1;::::0;;;;;;;;;:11;:29;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;1723:29:0;1722:30:::1;1714:60;;;::::0;;-1:-1:-1;;;1714:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1714:60:0;;;;;;;;;;;;;::::1;;7906:16:1::2;::::0;:39:::2;::::0;;-1:-1:-1;;;7906:39:1;;-1:-1:-1;;;;;7906:39:1;;::::2;;::::0;::::2;::::0;;;7889:14:::2;::::0;7906:16;;;::::2;::::0;:26:::2;::::0;:39;;;;;::::2;::::0;;;;;;;;;:16;:39;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;7906:39:1;;-1:-1:-1;7955:52:1::2;7972:7:::0;7906:39;7989:17;7955:16:::2;:52::i;:::-;8061:11;::::0;8017:57:::2;::::0;8036:7;;8045:6;;-1:-1:-1;;;;;8061:11:1::2;8017:18;:57::i;:::-;8089:67;::::0;;-1:-1:-1;;;;;8089:67:1;;::::2;::::0;;::::2;::::0;::::2;::::0;;;;;8116:7;;8089:67;;::::2;::::0;::::2;::::0;;;;;;;::::2;1784:1:0;2874::::1;7636:527:1::0;;;;;:::o;4355:830::-;4635:15;4575:7;2813:51:0;2844:7;2853:10;2813:30;:51::i;:::-;1723:11:::1;::::0;:29:::1;::::0;;-1:-1:-1;;;1723:29:0;;-1:-1:-1;;;;;1723:29:0;;::::1;;::::0;::::1;::::0;;;4609:7:1;;1723:11:0;;;::::1;::::0;:20:::1;::::0;:29;;;;;::::1;::::0;;;;;;;;;:11;:29;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;1723:29:0;1722:30:::1;1714:60;;;::::0;;-1:-1:-1;;;1714:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1714:60:0;;;;;;;;;;;;;::::1;;4693:16:1::2;::::0;;4707:1:::2;4693:16:::0;;;4666:24:::2;4693:16:::0;;::::2;::::0;;4666:24;4693:16:::2;::::0;::::2;::::0;;::::2;::::0;::::2;-1:-1:-1::0;;4732:16:1::2;::::0;:39:::2;::::0;;-1:-1:-1;;;4732:39:1;;-1:-1:-1;;;;;4732:39:1;;::::2;;::::0;::::2;::::0;;;4666:43;;-1:-1:-1;4732:16:1;::::2;::::0;:26:::2;::::0;-1:-1:-1;4732:39:1;;;;;::::2;::::0;;;;;;;;:16;:39;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;4732:39:1;4719:10;;:7;;4727:1:::2;::::0;4719:10:::2;;;;-1:-1:-1::0;;;;;4719:52:1;;::::2;:10;::::0;;::::2;::::0;;;;;;:52;;;;4794:16:::2;::::0;:38:::2;::::0;;-1:-1:-1;;;4794:38:1;;;;::::2;;::::0;::::2;::::0;;;:16;;;::::2;::::0;:26:::2;::::0;:38;;;;;4719:10;;4794:38;;;;;:16;:38;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;4794:38:1;4781:10;;:7;;4789:1:::2;::::0;4781:10;::::2;;;;;-1:-1:-1::0;;;;;4781:51:1;;::::2;:10;::::0;;::::2;::::0;;;;;;:51;;;;4872:11:::2;::::0;4889:59:::2;::::0;::::2;::::0;::::2;::::0;;;;;;;;;;;4842:107:::2;::::0;4855:7;;4872:11;::::2;::::0;::::2;::::0;4940:7;;4889:59;;;;;;;;;;::::2;::::0;::::2;::::0;;;4872:11;4889:59:::2;;;;;;;::::0;;::::2;::::0;;;::::2;::::0;::::2;;;;;-1:-1:-1::0;;4889:59:1::2;::::0;;;;;::::2;::::0;;::::2;-1:-1:-1::0;;4889:59:1;;;;;;-1:-1:-1;4889:59:1::2;::::0;::::2;::::0;;::::2;-1:-1:-1::0;;;;;4889:59:1;;::::2;;::::0;;;-1:-1:-1;4842:12:1::2;::::0;-1:-1:-1;;;;4842:107:1:i:2;:::-;;4959:57;4964:7;4973;4981:1;4973:10;;;;;;;;;;;;;;4985:11;4998:17;4959:4;:57::i;:::-;5026:52;5033:7;5042:10;5054:7;5062:1;5054:10;;;;;;;;;;;;;;5066:11;5026:6;:52::i;:::-;5093:85;::::0;;-1:-1:-1;;;;;5093:85:1;;::::2;::::0;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;;;;;;;;;;;;5113:7;;5093:85;::::2;::::0;::::2;::::0;;;;;;;;::::2;1784:1:0;2874::::1;4355:830:1::0;;;;;;;;:::o;6763:524::-;6956:7;2813:51:0;2844:7;2853:10;2813:30;:51::i;:::-;1723:11:::1;::::0;:29:::1;::::0;;-1:-1:-1;;;1723:29:0;;-1:-1:-1;;;;;1723:29:0;;::::1;;::::0;::::1;::::0;;;6990:7:1;;1723:11:0;;;::::1;::::0;:20:::1;::::0;:29;;;;;::::1;::::0;;;;;;;;;:11;:29;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;1723:29:0;1722:30:::1;1714:60;;;::::0;;-1:-1:-1;;;1714:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1714:60:0;;;;;;;;;;;;;::::1;;7030:16:1::2;::::0;:39:::2;::::0;;-1:-1:-1;;;7030:39:1;;-1:-1:-1;;;;;7030:39:1;;::::2;;::::0;::::2;::::0;;;7013:14:::2;::::0;7030:16;;;::::2;::::0;:26:::2;::::0;:39;;;;;::::2;::::0;;;;;;;;;:16;:39;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;7030:39:1;7124:11:::2;::::0;7030:39;;-1:-1:-1;7079:58:1::2;::::0;7099:7;;7030:39;;-1:-1:-1;;;;;7124:11:1::2;7079:19;:58::i;:::-;7147:53;7152:7;7161:6;7169:11;7182:17;7147:4;:53::i;:::-;7215:65;::::0;;-1:-1:-1;;;;;7215:65:1;;::::2;::::0;;::::2;::::0;::::2;::::0;;;;;7240:7;;7215:65;;::::2;::::0;::::2;::::0;;;;;;;::::2;1784:1:0;2874::::1;6763:524:1::0;;;;;:::o;12818:464::-;13015:16;;:34;;;-1:-1:-1;;;13015:34:1;;-1:-1:-1;;;;;13015:34:1;;;;;;;;;12943:19;;;;;;13015:16;;;:26;;:34;;;;;;;;;;;;;;;:16;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13015:34:1;13073;;;-1:-1:-1;;;13073:34:1;;-1:-1:-1;;;;;13073:34:1;;;;;;;;;13015;;-1:-1:-1;13059:11:1;;13073:25;;;;;;:34;;;;;13015;;13073;;;;;;;;:25;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13073:34:1;13145:36;;;;;;;;13073:34;;-1:-1:-1;13117:25:1;;-1:-1:-1;;;;;13145:34:1;;;;;:36;;;;;13073:34;;13145:36;;;;;;;:34;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13145:36:1;;-1:-1:-1;13205:46:1;13242:8;13205:32;:6;13145:36;13205:10;:32::i;:46::-;13191:60;13274:1;;-1:-1:-1;12818:464:1;-1:-1:-1;;;;;;12818:464:1:o;9351:489::-;9534:7;2813:51:0;2844:7;2853:10;2813:30;:51::i;:::-;1723:11:::1;::::0;:29:::1;::::0;;-1:-1:-1;;;1723:29:0;;-1:-1:-1;;;;;1723:29:0;;::::1;;::::0;::::1;::::0;;;9568:7:1;;1723:11:0;;;::::1;::::0;:20:::1;::::0;:29;;;;;::::1;::::0;;;;;;;;;:11;:29;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;1723:29:0;1722:30:::1;1714:60;;;::::0;;-1:-1:-1;;;1714:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1714:60:0;;;;;;;;;;;;;::::1;;9608:16:1::2;::::0;:38:::2;::::0;;-1:-1:-1;;;9608:38:1;;-1:-1:-1;;;;;9608:38:1;;::::2;;::::0;::::2;::::0;;;9591:14:::2;::::0;9608:16;;;::::2;::::0;:26:::2;::::0;:38;;;;;::::2;::::0;;;;;;;;;:16;:38;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;9608:38:1;;-1:-1:-1;9656:41:1::2;9668:7:::0;9608:38;9685:11;9656::::2;:41::i;:::-;9751:11;::::0;9707:57:::2;::::0;9726:7;;9735:6;;-1:-1:-1;;;;;9751:11:1::2;9707:18;:57::i;:::-;9779:54;::::0;;-1:-1:-1;;;;;9779:54:1;;::::2;::::0;;::::2;::::0;::::2;::::0;;;;;9800:7;;9779:54;;::::2;::::0;::::2;::::0;;;;;;;::::2;1784:1:0;2874::::1;9351:489:1::0;;;;;:::o;3972:100:0:-;4047:21;3972:100;:::o;11274:471:1:-;11512:17;11452:7;2813:51:0;2844:7;2853:10;2813:30;:51::i;:::-;1723:11:::1;::::0;:29:::1;::::0;;-1:-1:-1;;;1723:29:0;;-1:-1:-1;;;;;1723:29:0;;::::1;;::::0;::::1;::::0;;;11486:7:1;;1723:11:0;;;::::1;::::0;:20:::1;::::0;:29;;;;;::::1;::::0;;;;;;;;;:11;:29;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;1723:29:0;1722:30:::1;1714:60;;;::::0;;-1:-1:-1;;;1714:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1714:60:0;;;;;;;;;;;;;::::1;;11562:16:1::2;::::0;:34:::2;::::0;;-1:-1:-1;;;11562:34:1;;-1:-1:-1;;;;;11562:34:1;;::::2;;::::0;::::2;::::0;;;11545:14:::2;::::0;11562:16;;;::::2;::::0;:26:::2;::::0;:34;;;;;::::2;::::0;;;;;;;;;:16;:34;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;11562:34:1;;-1:-1:-1;11606:38:1::2;11611:7:::0;11562:34;11628:6;11636:7;11606:4:::2;:38::i;:::-;11688:50;::::0;;-1:-1:-1;;;;;11688:50:1;;::::2;::::0;;::::2;::::0;::::2;::::0;;;;;;;;;;;11666:7;;-1:-1:-1;11688:50:1;;::::2;::::0;::::2;::::0;;;;;;;::::2;1784:1:0;2874::::1;11274:471:1::0;;;;;;;:::o;5251:228:0:-;5357:53;5393:7;5402;5357:35;:53::i;:::-;:82;;;;5414:25;5422:7;5431;5414;:25::i;:::-;5349:123;;;;;-1:-1:-1;;;5349:123:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;5251:228;;:::o;18715:434:1:-;18819:14;18849:12;-1:-1:-1;;;;;18836:42:1;;18879:7;18896;18836:69;;;;;;;;;;;;;-1:-1:-1;;;;;18836:69:1;;;;;;-1:-1:-1;;;;;18836:69:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18836:69:1;;-1:-1:-1;18836:69:1;18915:228;;18971:16;;;18985:1;18971:16;;;;;;;;;18945:23;;18971:16;;;;;;;;;;;-1:-1:-1;18971:16:1;18945:42;;19013:7;19001:6;19008:1;19001:9;;;;;;;;;;;;;:19;-1:-1:-1;;;;;19001:19:1;;;-1:-1:-1;;;;;19001:19:1;;;;;19034:98;19047:7;19056:12;19070:1;19124:6;19073:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19034:98;;18915:228;;18715:434;;;;:::o;16479:622::-;-1:-1:-1;;;;;16589:21:1;;16581:64;;;;;-1:-1:-1;;;16581:64:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;16673:1;16663:7;:11;16655:46;;;;;-1:-1:-1;;;16655:46:1;;;;;;;;;;;;-1:-1:-1;;;16655:46:1;;;;;;;;;;;;;;;16711:26;-1:-1:-1;;;;;16740:19:1;;1343:42:0;16740:19:1;:72;;16786:6;-1:-1:-1;;;;;16780:23:1;;16804:7;16780:32;;;;;;;;;;;;;-1:-1:-1;;;;;16780:32:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16780:32:1;16740:72;;;16762:7;-1:-1:-1;;;;;16762:15:1;;16740:72;16856:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;16856:51:1;;;;;16711:101;;-1:-1:-1;16822:86:1;;16835:7;;16844;;16853:1;;16822:12;:86::i;:::-;-1:-1:-1;16918:24:1;-1:-1:-1;;;;;16945:19:1;;1343:42:0;16945:19:1;:72;;16991:6;-1:-1:-1;;;;;16985:23:1;;17009:7;16985:32;;;;;;;;;;;;;-1:-1:-1;;;;;16985:32:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16985:32:1;16945:72;;;16967:7;-1:-1:-1;;;;;16967:15:1;;16945:72;16918:99;;17054:18;17035:16;:37;17027:67;;;;;-1:-1:-1;;;17027:67:1;;;;;;;;;;;;;;;;;;;;;;;;;;;2119:459:10;2177:7;2418:6;2414:45;;-1:-1:-1;2447:1:10;2440:8;;2414:45;2481:5;;;2485:1;2481;:5;:1;2504:5;;;;;:10;2496:56;;;;-1:-1:-1;;;2496:56:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2570:1;2119:459;-1:-1:-1;;;2119:459:10:o;3033:130::-;3091:7;3117:39;3121:1;3124;3117:39;;;;;;;;;;;;;;;;;:3;:39::i;14651:809:1:-;15161:1;15151:7;:11;15143:46;;;;;-1:-1:-1;;;15143:46:1;;;;;;;;;;;;-1:-1:-1;;;15143:46:1;;;;;;;;;;;;;;;15199:27;15235:7;-1:-1:-1;;;;;15229:24:1;;15254:7;15229:33;;;;;;;;;;;;;-1:-1:-1;;;;;15229:33:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15229:33:1;15306:51;;;;;;;;;;;;;;;;;;;;;;;;;;;15229:33;15306:51;;;;-1:-1:-1;;;;;15306:51:1;;;;;15229:33;;-1:-1:-1;15272:86:1;;15285:7;;15294;;15303:1;;15272:12;:86::i;:::-;;15412:19;15382:7;-1:-1:-1;;;;;15376:24:1;;15401:7;15376:33;;;;;;;;;;;;;-1:-1:-1;;;;;15376:33:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15376:33:1;:55;15368:85;;;;;-1:-1:-1;;;15368:85:1;;;;;;;;;;;;;;;;;;;;;;;;;;;17340:1148;-1:-1:-1;;;;;17439:21:1;;17431:64;;;;;-1:-1:-1;;;17431:64:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;17523:1;17513:7;:11;17505:46;;;;;-1:-1:-1;;;17505:46:1;;;;;;;;;;;;-1:-1:-1;;;17505:46:1;;;;;;;;;;;;;;;17561:20;17592:7;-1:-1:-1;;;;;17584:23:1;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;17584:25:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17584:25:1;;;;;;;;;;-1:-1:-1;17584:25:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17561:48;;17619:26;17655:24;17742;;;;;;;;;;;;;;;;;;;;;;;;;;17732:35;;;;;;17720:6;17703:24;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;17703:24:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17693:35;;;;;;:74;17689:711;;;17873:40;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;17873:40:1;;;;;-1:-1:-1;;;;;17804:15:1;;;;-1:-1:-1;17833:81:1;;17804:7;;17855;;17864;;17833:12;:81::i;:::-;-1:-1:-1;;;;;;;17947:15:1;;;17689:711;;;17993:13;18017:7;-1:-1:-1;;;;;18009:27:1;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18009:29:1;18073:31;;;-1:-1:-1;;;18073:31:1;;-1:-1:-1;;;;;18073:31:1;;;;;;;;;18009:29;;-1:-1:-1;18073:22:1;;;;;;:31;;;;;18009:29;;18073:31;;;;;;;;:22;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18073:31:1;18150:69;;;-1:-1:-1;;;;;18150:69:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18073:31;18150:69;;;;-1:-1:-1;;;;;18150:69:1;-1:-1:-1;;;18150:69:1;;;18073:31;;-1:-1:-1;18118:102:1;;18131:7;;18140:5;;18147:1;;18118:12;:102::i;:::-;-1:-1:-1;18268:56:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18268:56:1;;;;;18234:91;;18247:7;;18256;;18265:1;;18234:12;:91::i;:::-;;18364:5;-1:-1:-1;;;;;18358:22:1;;18381:7;18358:31;;;;;;;;;;;;;-1:-1:-1;;;;;18358:31:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18358:31:1;;-1:-1:-1;;17689:711:1;18436:18;18417:16;:37;18409:72;;;;;-1:-1:-1;;;18409:72:1;;;;;;;;;;;;;;;;;;;;;;;;;;;5749:251:0;5912:14;;:81;;;;;-1:-1:-1;;;;;5912:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5871:17;;5912:14;;;;;:52;;5965:7;;5974:3;;5979:6;;5987:5;;5912:81;;;;;;;;;;;;:14;:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5912:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5912:81:0;;;;;;;;;;-1:-1:-1;5912:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5905:88;;5749:251;;;;;;:::o;15695:507:1:-;-1:-1:-1;;;;;15799:21:1;;15791:64;;;;;-1:-1:-1;;;15791:64:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;15883:1;15873:7;:11;15865:46;;;;;-1:-1:-1;;;15865:46:1;;;;;;;;;;;;-1:-1:-1;;;15865:46:1;;;;;;;;;;;;;;;15921:27;15957:7;-1:-1:-1;;;;;15951:24:1;;15976:7;15951:33;;;;;;;;;;;;;-1:-1:-1;;;;;15951:33:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15951:33:1;16028:61;;;;;;;;;;;;;;;;;;;;;;;;;;;15951:33;16028:61;;;;-1:-1:-1;;;;;16028:61:1;;;;;15951:33;;-1:-1:-1;15994:96:1;;16007:7;;16016;;16025:1;;15994:12;:96::i;:::-;;16144:19;16114:7;-1:-1:-1;;;;;16108:24:1;;16133:7;16108:33;;;;;;;;;;;;;-1:-1:-1;;;;;16108:33:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16108:33:1;:55;16100:95;;;;;-1:-1:-1;;;16100:95:1;;;;;;;;;;;;;;;;;;;;;;;;;;;19386:393;19489:15;19515:7;-1:-1:-1;;;;;19507:26:1;;19534:7;19507:35;;;;;;;;;;;;;-1:-1:-1;;;;;19507:35:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19507:35:1;19564:45;;;;;;-1:-1:-1;;;;;19564:45:1;;;;;;;;;19507:35;;-1:-1:-1;19552:9:1;;19564:36;;;;;;:45;;;;;19507:35;;19564:45;;;;;;;;:36;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19564:45:1;;-1:-1:-1;19623:15:1;;:28;;;;-1:-1:-1;19642:9:1;;19623:28;19619:154;;;19706:55;;;-1:-1:-1;;;;;19706:55:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;19706:55:1;-1:-1:-1;;;19706:55:1;;;19667:95;;19680:7;;19689:12;;19703:1;;19667:12;:95::i;13668:758::-;-1:-1:-1;;;;;13776:21:1;;13768:64;;;;;-1:-1:-1;;;13768:64:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;13860:1;13850:7;:11;13842:46;;;;;-1:-1:-1;;;13842:46:1;;;;;;;;;;;;-1:-1:-1;;;13842:46:1;;;;;;;;;;;;;;;13898:27;13934:7;-1:-1:-1;;;;;13928:24:1;;13953:7;13928:33;;;;;;;;;;;;;-1:-1:-1;;;;;13928:33:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13928:33:1;;-1:-1:-1;;;;;;13975:19:1;;1343:42:0;13975:19:1;13971:356;;;14050:33;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14050:33:1;;;;;14010:74;;14023:7;;14032;;14041;;14010:12;:74::i;:::-;;13971:356;;;14148:69;;;-1:-1:-1;;;;;14148:69:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14148:69:1;-1:-1:-1;;;14148:69:1;;;14115:103;;14128:7;;14137:6;;14145:1;;14115:12;:103::i;:::-;-1:-1:-1;14266:49:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14266:49:1;;;;;14232:84;;14245:7;;14254;;14263:1;;14232:12;:84::i;:::-;;13971:356;14380:19;14350:7;-1:-1:-1;;;;;14344:24:1;;14369:7;14344:33;;;;;;;;;;;;;-1:-1:-1;;;;;14344:33:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14344:33:1;:55;14336:83;;;;;-1:-1:-1;;;14336:83:1;;;;;;;;;;;;;;;;;;;;;;;;;;;4935:135:0;5007:4;5058:5;-1:-1:-1;;;;;5030:33:0;5038:7;-1:-1:-1;;;;;5030:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5030:24:0;-1:-1:-1;;;;;5030:33:0;;;4935:135;-1:-1:-1;;;4935:135:0:o;3638:338:10:-;3724:7;3824:12;3817:5;3809:28;;;;-1:-1:-1;;;3809:28:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3847:9;3863:1;3859;:5;;;;;;;3638:338;-1:-1:-1;;;;;3638:338:10:o

Swarm Source

ipfs://c1e55394c7046c4ba5ed000f812ce903bca5e46892190237dddfb31606e83b6e

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

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.