MOVR Price: $2.26 (-0.62%)

Contract

0xc9C85890eBd79AFeb244577f69750AE584Cb4C19

Overview

MOVR Balance

Moonriver Chain LogoMoonriver Chain LogoMoonriver Chain Logo0 MOVR

MOVR Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Remove Market42207232023-05-11 16:15:00991 days ago1683821700IN
0xc9C85890...584Cb4C19
0 MOVR0.000117652.25
Remove Market42207142023-05-11 16:13:12991 days ago1683821592IN
0xc9C85890...584Cb4C19
0 MOVR0.000117652.25
Update Claim Rew...42206822023-05-11 16:06:36991 days ago1683821196IN
0xc9C85890...584Cb4C19
0 MOVR0.000056722.25
Set Vault42206812023-05-11 16:06:24991 days ago1683821184IN
0xc9C85890...584Cb4C19
0 MOVR0.000107272.25
Set Safety Modul...42206762023-05-11 16:05:24991 days ago1683821124IN
0xc9C85890...584Cb4C19
0 MOVR0.000062542.25
Set Comptroller42206742023-05-11 16:05:00991 days ago1683821100IN
0xc9C85890...584Cb4C19
0 MOVR0.000062592.25
Set Up42206642023-05-11 16:02:54991 days ago1683820974IN
0xc9C85890...584Cb4C19
0 MOVR0.001650482.25

Parent Transaction Hash Block From To
View All Internal Transactions
Cross-Chain Transactions
Loading...
Loading

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

Contract Name:
autoMint

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

// import "./Module.sol";
import "./interfaces/IVault.sol";
import "./factory/FactoryFriendly.sol";
import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "moonwell-contracts-private/contracts/core/MTokenInterfaces.sol";
interface IMGlimmer { function mint() external payable; }
interface Comptroller {
    function claimReward(uint8 rewardType, address holder, address[] memory mTokens) external;
}
interface IStakedToken {
    function stake(address to, uint256 amount) external;
    function claimRewards(address to, uint256 amount) external;
    function getTotalRewardsBalance(address staker) external view returns (uint256);
}

contract autoMint is FactoryFriendly {
    struct Market {
        uint256 minBalance;
        address marketContract;
    }

    mapping(address => Market) public tokens;
    mapping(address => bool) public admins;
    address[] public adminList;
    address[] public tokenList;
    address[] public marketList;
    address public vault = address(0);
    address public comptroller = address(0);
    address public safetyModule = address(0);

    uint256 public claimRewardsCooldown = 86400; // 24 hours
    uint256 public claimStakingRewardsCooldown = 86400; // 24 hours
    uint256 public lastClaimedTime;
    uint256 public lastClaimedStakingTime;

    event VaultSet(address indexed previousVault, address indexed newVault);
    event ComptrollerSet(address indexed previousComptroller, address indexed newComptroller);
    event SafetyModuleSet(address indexed previousSafetyModule, address indexed newSafetyModule);
    event MarketAdded(address indexed token, uint256 minBalance, address marketContract);
    event MarketModified(address indexed token, uint256 minBalance, address marketContract);
    event MarketRemoved(address indexed token);
    event AdminAdded(address indexed admin);
    event AdminRemoved(address indexed admin);
    event Approved(address indexed token, address indexed spender, uint256 amount);
    event ApproveFailed(address indexed token, address indexed spender);
    event Minted(address indexed marketContract, uint256 amount);
    event MintFailed(address indexed token, address indexed marketContract);
    event ModuleAddress(address indexed module);
    event CooldownUpdated(uint256 oldCooldown, uint256 newCooldown);
    event RewardsClaimed(uint256 timestamp);
    event RewardsClaimFailed(uint256 timestamp);
    event StakingRewardsClaimed(uint256 timestamp);
    event StakingRewardsClaimFailed(uint256 timestamp);

    modifier onlyAdmin() {
        require(admins[msg.sender], "autoMint: not an admin");
        _;
    }

    function setUp(bytes memory initializeParams) public virtual override onlyOwner {
        // Add the deployer of the contract as the admin during setup
        addAdmin(msg.sender);

        uint256 currentChainId = block.chainid;
        if (currentChainId == 1285) { // Moonriver
            setComptroller(0x0b7a0EAA884849c6Af7a129e899536dDDcA4905E); // Apollo Comptroller
            setSafetyModule(0xCd76e63f3AbFA864c53b4B98F57c1aA6539FDa3a); // Apollo Safety Module
            addMarket( // stkMFAM
                0xBb8d88bcD9749636BC4D2bE22aaC4Bb3B01A58F1, // MFAM token address
                0,
                address(safetyModule)
            );
            addMarket( // xcKSM
                0xFfFFfFff1FcaCBd218EDc0EbA20Fc2308C778080,
                0,
                0xa0D116513Bd0B8f3F14e6Ea41556c6Ec34688e0f 
            );
            addMarket( // ETH.multi
                0x639A647fbe20b6c8ac19E48E2de44ea792c62c5C,
                0,
                0x6503D905338e2ebB550c9eC39Ced525b612E77aE
            );
            addMarket( // USDC.multi
                0xE3F5a90F9cb311505cd691a46596599aA1A0AD7D,
                0,
                0xd0670AEe3698F66e2D4dAf071EB9c690d978BFA8
            );
            addMarket( // USDT.multi
                0xB44a9B6905aF7c801311e8F4E76932ee959c663C,
                0,
                0x36918B66F9A3eC7a59d0007D8458DB17bDffBF21
            );
            addMarket( // FRAX
                0x1A93B23281CC1CDE4C4741353F3064709A16197d,
                0,
                0x93Ef8B7c6171BaB1C0A51092B2c9da8dc2ba0e9D
            );
            addMarket( // WBTC.multi
                0x6aB6d61428fde76768D7b45D8BFeec19c6eF91A8,
                0,
                0x6E745367F4Ad2b3da7339aee65dC85d416614D90
            );
            addMarket( // MOVR
                0x0000000000000000000000000000000000000000,
                0,
                0x6a1A771C7826596652daDC9145fEAaE62b1cd07f
            );
        } else if (currentChainId == 1284) { // Moonbeam
            setComptroller(0x8E00D5e02E65A19337Cdba98bbA9F84d4186a180); // Artemis Comptroller
            setSafetyModule(0x8568A675384d761f36eC269D695d6Ce4423cfaB1); // Artemis Safety Module
            addMarket( // stkWELL
                0x511aB53F793683763E5a8829738301368a2411E3, // WELL token address
                0,
                address(safetyModule)
            );
            addMarket( // xcDOT
                0xD22Da948c0aB3A27f5570b604f3ADef5F68211C3,
                0,
                0xFfFFfFff1FcaCBd218EDc0EbA20Fc2308C778080
            );
            addMarket( // xcUSDT
                0x42A96C0681B74838eC525AdbD13c37f66388f289,
                0,
                0xFFFFFFfFea09FB06d082fd1275CD48b191cbCD1d
            );
            addMarket( // FRAX
                0x1C55649f73CDA2f72CEf3DD6C5CA3d49EFcF484C,
                0,
                0x322E86852e492a7Ee17f28a78c663da38FB33bfb
            );
            addMarket( // USDC.wh
                0x744b1756e7651c6D57f5311767EAFE5E931D615b,
                0,
                0x931715FEE2d06333043d11F658C8CE934aC61D0c
            );
            addMarket( // ETH.wh
                0xb6c94b3A378537300387B57ab1cC0d2083f9AeaC,
                0,
                0xab3f0245B83feB11d15AAffeFD7AD465a59817eD
            );
            addMarket( // WBTC.wh
                0xaaa20c5a584a9fECdFEDD71E46DA7858B774A9ce,
                0,
                0xE57eBd2d67B462E9926e04a8e33f01cD0D64346D
            );
        }
    }

    function setVault(address newVault) public onlyAdmin {
        address previousVault = vault;
        vault = newVault;
        emit VaultSet(previousVault, newVault);
    }

    function setComptroller(address newComptroller) public onlyAdmin {
        address previousComptroller = comptroller;
        comptroller = newComptroller;
        emit ComptrollerSet(address(previousComptroller), address(newComptroller));
    }

    function setSafetyModule(address newSafetyModule) public onlyAdmin {
        address previousSafetyModule = safetyModule;
        safetyModule = newSafetyModule;
        emit SafetyModuleSet(address(previousSafetyModule), address(newSafetyModule));
    }

    function updateClaimRewardsCooldown(uint256 newCooldown) public onlyAdmin {
        uint256 oldCooldown = claimRewardsCooldown;
        claimRewardsCooldown = newCooldown;
        emit CooldownUpdated(oldCooldown, newCooldown);
    }

    function exec(
        address to,
        uint256 value,
        bytes memory data,
        Enum.Operation operation
    ) internal returns (bool success) {
        success = IVault(vault).execTransactionFromModule(
                to,
                value,
                data,
                operation
            );
        return success;
    }

    function addAdmin(address admin) public onlyOwner {
        admins[admin] = true;
        adminList.push(admin);
        emit AdminAdded(admin);
    }

    function removeAdmin(address admin) public onlyOwner {
        delete admins[admin];
        for (uint256 i = 0; i < adminList.length; i++) {
            if (adminList[i] == admin) {
                adminList[i] = adminList[adminList.length - 1];
                adminList.pop();
                break;
            }
        }
        emit AdminRemoved(admin);
    }

    function addMarket(address token, uint256 minBalance, address marketContract) public onlyAdmin {
        tokens[token] = Market(minBalance, marketContract);
        tokenList.push(token);
        marketList.push(marketContract);
        emit MarketAdded(token, minBalance, marketContract);
    }

    function modifyMarket(address token, uint256 minBalance, address marketContract) public onlyAdmin {
        require(tokens[token].marketContract != address(0), "autoMint: market not found");
        tokens[token] = Market(minBalance, marketContract);
        emit MarketModified(token, minBalance, marketContract);
    }

    function removeMarket(address token) public onlyAdmin {
        delete tokens[token];
        for (uint256 i = 0; i < tokenList.length; i++) {
            if (tokenList[i] == token) {
                tokenList[i] = tokenList[tokenList.length - 1];
                tokenList.pop();
                marketList[i] = marketList[marketList.length - 1];
                marketList.pop();
                break;
            }
        }
        emit MarketRemoved(token);
    }

    function getAvailableBalance(address token) public view returns (uint256) {
        Market memory market = tokens[token];
        require(market.marketContract != address(0), "autoMint: market not found");

        uint256 safeBalance = 0;
        if (token == address(0)) { // If the token is native (ETH, MOVR, GLMR, etc)
            safeBalance = address(vault).balance; // get the native balance of the vault
        } else {  // If the token is ERC20
            safeBalance = IERC20(token).balanceOf(vault); // get the ERC20 balance of the vault
        }
        if (safeBalance > market.minBalance) {
            return safeBalance - market.minBalance;
        }
        return 0;
    }

    function mint(address token) public {
        uint256 availableBalance;
        Market memory market = tokens[token];
        bytes memory mintCalldata;

        if (token == address(0)) {
            // Get the available balance of the native gas token (ETH, etc)
            availableBalance = address(vault).balance;
            require(availableBalance > 0, "autoMint: no available balance");

            // Construct the calldata for the payable MGlimmer mint function call
            mintCalldata = abi.encodeWithSelector(
                IMGlimmer(market.marketContract).mint.selector
            );

            // Call the exec function to execute the mint function through the Module contract
            if ( exec(market.marketContract, availableBalance, mintCalldata, Enum.Operation.Call) ) {
                emit Minted(market.marketContract, availableBalance);
            } else {
                emit MintFailed(token, market.marketContract);
                return;
            }
        } else {
            availableBalance = getAvailableBalance(token);
            require(availableBalance > 0, "autoMint: no available balance");

            // Construct the calldata for the approve function call
            bytes memory approveCalldata = abi.encodeWithSelector(
                IERC20(token).approve.selector,
                market.marketContract,
                availableBalance
            );

            // Call the exec function to execute the approve function through the Module contract
            if ( exec(token, 0, approveCalldata, Enum.Operation.Call) ) {
                emit Approved(token, market.marketContract, availableBalance);
            } else {
                emit ApproveFailed(token, market.marketContract);
                return;
            }

            if (market.marketContract == safetyModule) {
                // Construct the calldata for the IStakedToken stake function call
                mintCalldata = abi.encodeWithSelector(
                    IStakedToken(market.marketContract).stake.selector,
                    address(vault),
                    availableBalance
                );
            } else {
                // Construct the calldata for the MErc20Interface mint function call
                mintCalldata = abi.encodeWithSelector(
                    MErc20Interface(market.marketContract).mint.selector,
                    availableBalance
                );
            }

            // Call the exec function to execute the mint function through the Module contract
            if ( exec(market.marketContract, token == address(0) ? availableBalance : 0, mintCalldata, Enum.Operation.Call) ) {
                emit Minted(market.marketContract, availableBalance);
            } else {
                emit MintFailed(token, market.marketContract);
                return;
            }
        }
    }

    function claimRewards() public {
        require(block.timestamp >= lastClaimedTime + claimRewardsCooldown, "autoMint: cooldown not reached");
        lastClaimedTime = block.timestamp;

        Comptroller comptrollerInstance = Comptroller(payable(comptroller));
        address[] memory allMarkets = marketList;

        comptrollerInstance.claimReward(0, address(vault), allMarkets);
        comptrollerInstance.claimReward(1, address(vault), allMarkets); 
        emit RewardsClaimed(block.timestamp);
    }

    function claimStakingRewards() public {
        require(block.timestamp >= lastClaimedStakingTime + claimStakingRewardsCooldown, "autoMint: cooldown not reached");
        lastClaimedTime = block.timestamp;

        try IStakedToken(safetyModule)
            .claimRewards(
                vault, 
                IStakedToken(safetyModule)
                .getTotalRewardsBalance(
                    vault
                )
            )
        { 
            emit StakingRewardsClaimed(block.timestamp); 
        } catch {
            emit StakingRewardsClaimFailed(block.timestamp);
        }
    }

    function getAdmins() public view returns (address[] memory) {
        return adminList;
    }

    function getTokens() public view returns (address[] memory) {
        return tokenList;
    }

    function getMarkets() public view returns (address[] memory) {
        return marketList;
    }
}

// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.10;

abstract contract ComptrollerInterface {
    /// @notice Indicator that this is a Comptroller contract (for inspection)
    bool public constant isComptroller = true;

    /*** Assets You Are In ***/

    function enterMarkets(address[] calldata mTokens) virtual external returns (uint[] memory);
    function exitMarket(address mToken) virtual external returns (uint);

    /*** Policy Hooks ***/

    function mintAllowed(address mToken, address minter, uint mintAmount) virtual external returns (uint);

    function redeemAllowed(address mToken, address redeemer, uint redeemTokens) virtual external returns (uint);

    // Do not remove, still used by MToken
    function redeemVerify(address mToken, address redeemer, uint redeemAmount, uint redeemTokens) pure virtual external;

    function borrowAllowed(address mToken, address borrower, uint borrowAmount) virtual external returns (uint);

    function repayBorrowAllowed(
        address mToken,
        address payer,
        address borrower,
        uint repayAmount) virtual external returns (uint);

    function liquidateBorrowAllowed(
        address mTokenBorrowed,
        address mTokenCollateral,
        address liquidator,
        address borrower,
        uint repayAmount) virtual external view returns (uint);

    function seizeAllowed(
        address mTokenCollateral,
        address mTokenBorrowed,
        address liquidator,
        address borrower,
        uint seizeTokens) virtual external returns (uint);

    function transferAllowed(address mToken, address src, address dst, uint transferTokens) virtual external returns (uint);

    /*** Liquidity/Liquidation Calculations ***/

    function liquidateCalculateSeizeTokens(
        address mTokenBorrowed,
        address mTokenCollateral,
        uint repayAmount) virtual external view returns (uint, uint);
}

// The hooks that were patched out of the comptroller to make room for the supply caps, if we need them
abstract contract ComptrollerInterfaceWithAllVerificationHooks is ComptrollerInterface {

    function mintVerify(address mToken, address minter, uint mintAmount, uint mintTokens) virtual external;

    // Included in ComptrollerInterface already
    // function redeemVerify(address mToken, address redeemer, uint redeemAmount, uint redeemTokens) virtual external;

    function borrowVerify(address mToken, address borrower, uint borrowAmount) virtual external;

    function repayBorrowVerify(
        address mToken,
        address payer,
        address borrower,
        uint repayAmount,
        uint borrowerIndex) virtual external;

    function liquidateBorrowVerify(
        address mTokenBorrowed,
        address mTokenCollateral,
        address liquidator,
        address borrower,
        uint repayAmount,
        uint seizeTokens) virtual external;

    function seizeVerify(
        address mTokenCollateral,
        address mTokenBorrowed,
        address liquidator,
        address borrower,
        uint seizeTokens) virtual external;

    function transferVerify(address mToken, address src, address dst, uint transferTokens) virtual external;
}

// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.10;

/**
 * @title EIP20NonStandardInterface
 * @dev Version of ERC20 with no return values for `transfer` and `transferFrom`
 *  See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca
 */
interface EIP20NonStandardInterface {

    /**
     * @notice Get the total number of tokens in circulation
     * @return The supply of tokens
     */
    function totalSupply() external view returns (uint256);

    /**
     * @notice Gets the balance of the specified address
     * @param owner The address from which the balance will be retrieved
     * @return balance The balance
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    ///
    /// !!!!!!!!!!!!!!
    /// !!! NOTICE !!! `transfer` does not return a value, in violation of the ERC-20 specification
    /// !!!!!!!!!!!!!!
    ///

    /**
      * @notice Transfer `amount` tokens from `msg.sender` to `dst`
      * @param dst The address of the destination account
      * @param amount The number of tokens to transfer
      */
    function transfer(address dst, uint256 amount) external;

    ///
    /// !!!!!!!!!!!!!!
    /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the ERC-20 specification
    /// !!!!!!!!!!!!!!
    ///

    /**
      * @notice Transfer `amount` tokens from `src` to `dst`
      * @param src The address of the source account
      * @param dst The address of the destination account
      * @param amount The number of tokens to transfer
      */
    function transferFrom(address src, address dst, uint256 amount) external;

    /**
      * @notice Approve `spender` to transfer up to `amount` from `src`
      * @dev This will overwrite the approval amount for `spender`
      *  and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)
      * @param spender The address of the account which may transfer tokens
      * @param amount The number of tokens that are approved
      * @return success Whether or not the approval succeeded
      */
    function approve(address spender, uint256 amount) external returns (bool success);

    /**
      * @notice Get the current allowance from `owner` for `spender`
      * @param owner The address of the account which owns the tokens to be spent
      * @param spender The address of the account which may transfer tokens
      * @return remaining The number of tokens allowed to be spent
      */
    function allowance(address owner, address spender) external view returns (uint256 remaining);

    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Approval(address indexed owner, address indexed spender, uint256 amount);
}

// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.10;

contract ComptrollerErrorReporter {
    enum Error {
        NO_ERROR,
        UNAUTHORIZED,
        COMPTROLLER_MISMATCH,
        INSUFFICIENT_SHORTFALL,
        INSUFFICIENT_LIQUIDITY,
        INVALID_CLOSE_FACTOR,
        INVALID_COLLATERAL_FACTOR,
        INVALID_LIQUIDATION_INCENTIVE,
        MARKET_NOT_ENTERED, // no longer possible
        MARKET_NOT_LISTED,
        MARKET_ALREADY_LISTED,
        MATH_ERROR,
        NONZERO_BORROW_BALANCE,
        PRICE_ERROR,
        REJECTION,
        SNAPSHOT_ERROR,
        TOO_MANY_ASSETS,
        TOO_MUCH_REPAY
    }

    enum FailureInfo {
        ACCEPT_ADMIN_PENDING_ADMIN_CHECK,
        ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,
        EXIT_MARKET_BALANCE_OWED,
        EXIT_MARKET_REJECTION,
        SET_CLOSE_FACTOR_OWNER_CHECK,
        SET_CLOSE_FACTOR_VALIDATION,
        SET_COLLATERAL_FACTOR_OWNER_CHECK,
        SET_COLLATERAL_FACTOR_NO_EXISTS,
        SET_COLLATERAL_FACTOR_VALIDATION,
        SET_COLLATERAL_FACTOR_WITHOUT_PRICE,
        SET_IMPLEMENTATION_OWNER_CHECK,
        SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,
        SET_LIQUIDATION_INCENTIVE_VALIDATION,
        SET_MAX_ASSETS_OWNER_CHECK,
        SET_PENDING_ADMIN_OWNER_CHECK,
        SET_PENDING_IMPLEMENTATION_OWNER_CHECK,
        SET_PRICE_ORACLE_OWNER_CHECK,
        SUPPORT_MARKET_EXISTS,
        SUPPORT_MARKET_OWNER_CHECK,
        SET_PAUSE_GUARDIAN_OWNER_CHECK,
        SET_GAS_AMOUNT_OWNER_CHECK
    }

    /**
      * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary
      * contract-specific code that enables us to report opaque error codes from upgradeable contracts.
      **/
    event Failure(uint error, uint info, uint detail);

    /**
      * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator
      */
    function fail(Error err, FailureInfo info) internal returns (uint) {
        emit Failure(uint(err), uint(info), 0);

        return uint(err);
    }

    /**
      * @dev use this when reporting an opaque error from an upgradeable collaborator contract
      */
    function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {
        emit Failure(uint(err), uint(info), opaqueError);

        return uint(err);
    }
}

contract TokenErrorReporter {
    enum Error {
        NO_ERROR,
        UNAUTHORIZED,
        BAD_INPUT,
        COMPTROLLER_REJECTION,
        COMPTROLLER_CALCULATION_ERROR,
        INTEREST_RATE_MODEL_ERROR,
        INVALID_ACCOUNT_PAIR,
        INVALID_CLOSE_AMOUNT_REQUESTED,
        INVALID_COLLATERAL_FACTOR,
        MATH_ERROR,
        MARKET_NOT_FRESH,
        MARKET_NOT_LISTED,
        TOKEN_INSUFFICIENT_ALLOWANCE,
        TOKEN_INSUFFICIENT_BALANCE,
        TOKEN_INSUFFICIENT_CASH,
        TOKEN_TRANSFER_IN_FAILED,
        TOKEN_TRANSFER_OUT_FAILED
    }

    /*
     * Note: FailureInfo (but not Error) is kept in alphabetical order
     *       This is because FailureInfo grows significantly faster, and
     *       the order of Error has some meaning, while the order of FailureInfo
     *       is entirely arbitrary.
     */
    enum FailureInfo {
        ACCEPT_ADMIN_PENDING_ADMIN_CHECK,
        ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,
        ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,
        ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,
        ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,
        ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,
        ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,
        BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,
        BORROW_ACCRUE_INTEREST_FAILED,
        BORROW_CASH_NOT_AVAILABLE,
        BORROW_FRESHNESS_CHECK,
        BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,
        BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,
        BORROW_MARKET_NOT_LISTED,
        BORROW_COMPTROLLER_REJECTION,
        LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,
        LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,
        LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,
        LIQUIDATE_COMPTROLLER_REJECTION,
        LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,
        LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,
        LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,
        LIQUIDATE_FRESHNESS_CHECK,
        LIQUIDATE_LIQUIDATOR_IS_BORROWER,
        LIQUIDATE_REPAY_BORROW_FRESH_FAILED,
        LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,
        LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,
        LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,
        LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,
        LIQUIDATE_SEIZE_TOO_MUCH,
        MINT_ACCRUE_INTEREST_FAILED,
        MINT_COMPTROLLER_REJECTION,
        MINT_EXCHANGE_CALCULATION_FAILED,
        MINT_EXCHANGE_RATE_READ_FAILED,
        MINT_FRESHNESS_CHECK,
        MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,
        MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,
        MINT_TRANSFER_IN_FAILED,
        MINT_TRANSFER_IN_NOT_POSSIBLE,
        REDEEM_ACCRUE_INTEREST_FAILED,
        REDEEM_COMPTROLLER_REJECTION,
        REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,
        REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,
        REDEEM_EXCHANGE_RATE_READ_FAILED,
        REDEEM_FRESHNESS_CHECK,
        REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,
        REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,
        REDEEM_TRANSFER_OUT_NOT_POSSIBLE,
        REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,
        REDUCE_RESERVES_ADMIN_CHECK,
        REDUCE_RESERVES_CASH_NOT_AVAILABLE,
        REDUCE_RESERVES_FRESH_CHECK,
        REDUCE_RESERVES_VALIDATION,
        REPAY_BEHALF_ACCRUE_INTEREST_FAILED,
        REPAY_BORROW_ACCRUE_INTEREST_FAILED,
        REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,
        REPAY_BORROW_COMPTROLLER_REJECTION,
        REPAY_BORROW_FRESHNESS_CHECK,
        REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,
        REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,
        REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,
        SET_COLLATERAL_FACTOR_OWNER_CHECK,
        SET_COLLATERAL_FACTOR_VALIDATION,
        SET_COMPTROLLER_OWNER_CHECK,
        SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,
        SET_INTEREST_RATE_MODEL_FRESH_CHECK,
        SET_INTEREST_RATE_MODEL_OWNER_CHECK,
        SET_MAX_ASSETS_OWNER_CHECK,
        SET_ORACLE_MARKET_NOT_LISTED,
        SET_PENDING_ADMIN_OWNER_CHECK,
        SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,
        SET_RESERVE_FACTOR_ADMIN_CHECK,
        SET_RESERVE_FACTOR_FRESH_CHECK,
        SET_RESERVE_FACTOR_BOUNDS_CHECK,
        TRANSFER_COMPTROLLER_REJECTION,
        TRANSFER_NOT_ALLOWED,
        TRANSFER_NOT_ENOUGH,
        TRANSFER_TOO_MUCH,
        ADD_RESERVES_ACCRUE_INTEREST_FAILED,
        ADD_RESERVES_FRESH_CHECK,
        ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,
        SET_PROTOCOL_SEIZE_SHARE_ACCRUE_INTEREST_FAILED,
        SET_PROTOCOL_SEIZE_SHARE_OWNER_CHECK,
        SET_PROTOCOL_SEIZE_SHARE_FRESH_CHECK
    }

    /**
      * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary
      * contract-specific code that enables us to report opaque error codes from upgradeable contracts.
      **/
    event Failure(uint error, uint info, uint detail);

    /**
      * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator
      */
    function fail(Error err, FailureInfo info) internal returns (uint) {
        emit Failure(uint(err), uint(info), 0);

        return uint(err);
    }

    /**
      * @dev use this when reporting an opaque error from an upgradeable collaborator contract
      */
    function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {
        emit Failure(uint(err), uint(info), opaqueError);

        return uint(err);
    }
}

// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.10;

/**
  * @title Moonwell's InterestRateModel Interface
  * @author Moonwell
  */
abstract contract InterestRateModel {
    /// @notice Indicator that this is an InterestRateModel contract (for inspection)
    bool public constant isInterestRateModel = true;

    /**
      * @notice Calculates the current borrow interest rate per timestamp
      * @param cash The total amount of cash the market has
      * @param borrows The total amount of borrows the market has outstanding
      * @param reserves The total amount of reserves the market has
      * @return The borrow rate per timestamp (as a percentage, and scaled by 1e18)
      */
    function getBorrowRate(uint cash, uint borrows, uint reserves) virtual external view returns (uint);

    /**
      * @notice Calculates the current supply interest rate per timestamp
      * @param cash The total amount of cash the market has
      * @param borrows The total amount of borrows the market has outstanding
      * @param reserves The total amount of reserves the market has
      * @param reserveFactorMantissa The current reserve factor the market has
      * @return The supply rate per timestamp (as a percentage, and scaled by 1e18)
      */
    function getSupplyRate(uint cash, uint borrows, uint reserves, uint reserveFactorMantissa) virtual external view returns (uint);

}

File 6 of 12 : MTokenInterfaces.sol
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.10;

import "./ComptrollerInterface.sol";
import "./IRModels/InterestRateModel.sol";
import "./EIP20NonStandardInterface.sol";
import "./ErrorReporter.sol";

contract MTokenStorage {
    /// @dev Guard variable for re-entrancy checks
    bool internal _notEntered;

    /// @notice EIP-20 token name for this token
    string public name;

    /// @notice EIP-20 token symbol for this token
    string public symbol;

    /// @notice EIP-20 token decimals for this token
    uint8 public decimals;

    /// @notice Maximum borrow rate that can ever be applied (.0005% / block)
    uint internal constant borrowRateMaxMantissa = 0.0005e16;

    // @notice Maximum fraction of interest that can be set aside for reserves
    uint internal constant reserveFactorMaxMantissa = 1e18;

    /// @notice Administrator for this contract
    address payable public admin;

    /// @notice Pending administrator for this contract
    address payable public pendingAdmin;

    /// @notice Contract which oversees inter-mToken operations
    ComptrollerInterface public comptroller;

    /// @notice Model which tells what the current interest rate should be
    InterestRateModel public interestRateModel;

    // @notice Initial exchange rate used when minting the first MTokens (used when totalSupply = 0)
    uint internal initialExchangeRateMantissa;

    /// @notice Fraction of interest currently set aside for reserves
    uint public reserveFactorMantissa;

    /// @notice Block number that interest was last accrued at
    uint public accrualBlockTimestamp;

    /// @notice Accumulator of the total earned interest rate since the opening of the market
    uint public borrowIndex;

    /// @notice Total amount of outstanding borrows of the underlying in this market
    uint public totalBorrows;

    /// @notice Total amount of reserves of the underlying held in this market
    uint public totalReserves;

    /// @notice Total number of tokens in circulation
    uint public totalSupply;

    /// @notice Official record of token balances for each account
    mapping (address => uint) internal accountTokens;

    /// @notice Approved token transfer amounts on behalf of others
    mapping (address => mapping (address => uint)) internal transferAllowances;

    /**
     * @notice Container for borrow balance information
     * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action
     * @member interestIndex Global borrowIndex as of the most recent balance-changing action
     */
    struct BorrowSnapshot {
        uint principal;
        uint interestIndex;
    }

    // @notice Mapping of account addresses to outstanding borrow balances
    mapping(address => BorrowSnapshot) internal accountBorrows;

    /// @notice Share of seized collateral that is added to reserves
    uint public protocolSeizeShareMantissa;

}

abstract contract MTokenInterface is MTokenStorage {
    /// @notice Indicator that this is a MToken contract (for inspection)
    bool public constant isMToken = true;

    /*** Market Events ***/

    /// @notice Event emitted when interest is accrued
    event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);

    /// @notice Event emitted when tokens are minted
    event Mint(address minter, uint mintAmount, uint mintTokens);

    /// @notice Event emitted when tokens are redeemed
    event Redeem(address redeemer, uint redeemAmount, uint redeemTokens);

    /// @notice Event emitted when underlying is borrowed
    event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);

    /// @notice Event emitted when a borrow is repaid
    event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);

    /// @notice Event emitted when a borrow is liquidated
    event LiquidateBorrow(address liquidator, address borrower, uint repayAmount, address mTokenCollateral, uint seizeTokens);

    /*** Admin Events ***/

    /// @notice Event emitted when pendingAdmin is changed
    event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);

    /// @notice Event emitted when pendingAdmin is accepted, which means admin is updated
    event NewAdmin(address oldAdmin, address newAdmin);

    /// @notice Event emitted when comptroller is changed
    event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);

    /// @notice Event emitted when interestRateModel is changed
    event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);

    /// @notice Event emitted when the reserve factor is changed
    event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);

    /// @notice Event emitted when the protocol seize share is changed
    event NewProtocolSeizeShare(uint oldProtocolSeizeShareMantissa, uint newProtocolSeizeShareMantissa);

    /// @notice Event emitted when the reserves are added
    event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);

    /// @notice Event emitted when the reserves are reduced
    event ReservesReduced(address admin, uint reduceAmount, uint newTotalReserves);

    /// @notice EIP20 Transfer event
    event Transfer(address indexed from, address indexed to, uint amount);

    /// @notice EIP20 Approval event
    event Approval(address indexed owner, address indexed spender, uint amount);

    /*** User Interface ***/

    function transfer(address dst, uint amount) virtual external returns (bool);
    function transferFrom(address src, address dst, uint amount) virtual external returns (bool);
    function approve(address spender, uint amount) virtual external returns (bool);
    function allowance(address owner, address spender) virtual external view returns (uint);
    function balanceOf(address owner) virtual external view returns (uint);
    function balanceOfUnderlying(address owner) virtual external returns (uint);
    function getAccountSnapshot(address account) virtual external view returns (uint, uint, uint, uint);
    function borrowRatePerTimestamp() virtual external view returns (uint);
    function supplyRatePerTimestamp() virtual external view returns (uint);
    function totalBorrowsCurrent() virtual external returns (uint);
    function borrowBalanceCurrent(address account) virtual external returns (uint);
    function borrowBalanceStored(address account) virtual external view returns (uint);
    function exchangeRateCurrent() virtual external returns (uint);
    function exchangeRateStored() virtual external view returns (uint);
    function getCash() virtual external view returns (uint);
    function accrueInterest() virtual external returns (uint);
    function seize(address liquidator, address borrower, uint seizeTokens) virtual external returns (uint);

    /*** Admin Functions ***/

    function _setPendingAdmin(address payable newPendingAdmin) virtual external returns (uint);
    function _acceptAdmin() virtual external returns (uint);
    function _setComptroller(ComptrollerInterface newComptroller) virtual external returns (uint);
    function _setReserveFactor(uint newReserveFactorMantissa) virtual external returns (uint);
    function _reduceReserves(uint reduceAmount) virtual external returns (uint);
    function _setInterestRateModel(InterestRateModel newInterestRateModel) virtual external returns (uint);
    function _setProtocolSeizeShare(uint newProtocolSeizeShareMantissa) virtual external returns (uint);
}

contract MErc20Storage {
    /// @notice Underlying asset for this MToken
    address public underlying;
}

abstract contract MErc20Interface is MErc20Storage {

    /*** User Interface ***/

    function mint(uint mintAmount) virtual external returns (uint);
    function mintWithPermit(uint mintAmount, uint deadline, uint8 v, bytes32 r, bytes32 s) virtual external returns (uint);
    function redeem(uint redeemTokens) virtual external returns (uint);
    function redeemUnderlying(uint redeemAmount) virtual external returns (uint);
    function borrow(uint borrowAmount) virtual external returns (uint);
    function repayBorrow(uint repayAmount) virtual external returns (uint);
    function repayBorrowBehalf(address borrower, uint repayAmount) virtual external returns (uint);
    function liquidateBorrow(address borrower, uint repayAmount, MTokenInterface mTokenCollateral) virtual external returns (uint);
    function sweepToken(EIP20NonStandardInterface token) virtual external;


    /*** Admin Functions ***/

    function _addReserves(uint addAmount) virtual external returns (uint);
}

contract MDelegationStorage {
    /// @notice Implementation address for this contract
    address public implementation;
}

abstract contract MDelegatorInterface is MDelegationStorage {
    /// @notice Emitted when implementation is changed
    event NewImplementation(address oldImplementation, address newImplementation);

    /**
     * @notice Called by the admin to update the implementation of the delegator
     * @param implementation_ The address of the new implementation for delegation
     * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation
     * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation
     */
    function _setImplementation(address implementation_, bool allowResign, bytes memory becomeImplementationData) virtual external;
}

abstract contract MDelegateInterface is MDelegationStorage {
    /**
     * @notice Called by the delegator on a delegate to initialize it for duty
     * @dev Should revert if any issues arise which make it unfit for delegation
     * @param data The encoded bytes data for any initialization
     */
    function _becomeImplementation(bytes memory data) virtual external;

    /// @notice Called by the delegator on a delegate to forfeit its responsibility
    function _resignImplementation() virtual external;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 10 of 12 : Enum.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

/**
 * @title Enum - Collection of enums used in Safe contracts.
 * @author Richard Meissner - @rmeissner
 */
abstract contract Enum {
    enum Operation {
        Call,
        DelegateCall
    }
}

File 11 of 12 : FactoryFriendly.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

import "openzeppelin-contracts/contracts/access/Ownable.sol";

abstract contract FactoryFriendly is Ownable {
    function setUp(bytes memory initializeParams) public virtual;
}

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

import "safe-contracts/common/Enum.sol";

interface IVault {
    event EnabledModule(address module);
    event DisabledModule(address module);
    event ExecutionFromModuleSuccess(address indexed module);
    event ExecutionFromModuleFailure(address indexed module);

    /// @dev Enables a module on the vault.
    /// @notice Can only be called by the vault.
    /// @notice Modules should be stored as a linked list.
    /// @notice Must emit EnabledModule(address module) if successful.
    /// @param module Module to be enabled.
    function enableModule(address module) external;

    /// @dev Disables a module on the vault.
    /// @notice Can only be called by the vault.
    /// @notice Must emit DisabledModule(address module) if successful.
    /// @param prevModule Address that pointed to the module to be removed in the linked list
    /// @param module Module to be removed.
    function disableModule(address prevModule, address module) external;

    /// @dev Allows a Module to execute a transaction.
    /// @notice Can only be called by an enabled module.
    /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.
    /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.
    /// @param to Destination address of module transaction.
    /// @param value Ether value of module transaction.
    /// @param data Data payload of module transaction.
    /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.
    function execTransactionFromModule(
        address to,
        uint256 value,
        bytes memory data,
        Enum.Operation operation
    ) external returns (bool success);

    /// @dev Allows a Module to execute a transaction and return data
    /// @notice Can only be called by an enabled module.
    /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.
    /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.
    /// @param to Destination address of module transaction.
    /// @param value Ether value of module transaction.
    /// @param data Data payload of module transaction.
    /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.
    function execTransactionFromModuleReturnData(
        address to,
        uint256 value,
        bytes memory data,
        Enum.Operation operation
    ) external returns (bool success, bytes memory returnData);

    /// @dev Returns if an module is enabled
    /// @return True if the module is enabled
    function isModuleEnabled(address module) external view returns (bool);

    /// @dev Returns array of modules.
    /// @param start Start of the page.
    /// @param pageSize Maximum number of modules that should be returned.
    /// @return array Array of modules.
    /// @return next Start of the next page.
    function getModulesPaginated(address start, uint256 pageSize)
        external
        view
        returns (address[] memory array, address next);
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"}],"name":"AdminAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"}],"name":"AdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"}],"name":"ApproveFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousComptroller","type":"address"},{"indexed":true,"internalType":"address","name":"newComptroller","type":"address"}],"name":"ComptrollerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldCooldown","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCooldown","type":"uint256"}],"name":"CooldownUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"minBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"marketContract","type":"address"}],"name":"MarketAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"minBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"marketContract","type":"address"}],"name":"MarketModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"MarketRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"marketContract","type":"address"}],"name":"MintFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"marketContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"module","type":"address"}],"name":"ModuleAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RewardsClaimFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RewardsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousSafetyModule","type":"address"},{"indexed":true,"internalType":"address","name":"newSafetyModule","type":"address"}],"name":"SafetyModuleSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"StakingRewardsClaimFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"StakingRewardsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousVault","type":"address"},{"indexed":true,"internalType":"address","name":"newVault","type":"address"}],"name":"VaultSet","type":"event"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"minBalance","type":"uint256"},{"internalType":"address","name":"marketContract","type":"address"}],"name":"addMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"adminList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"admins","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimRewardsCooldown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimStakingRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimStakingRewardsCooldown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"comptroller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAdmins","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getAvailableBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMarkets","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastClaimedStakingTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastClaimedTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"marketList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"minBalance","type":"uint256"},{"internalType":"address","name":"marketContract","type":"address"}],"name":"modifyMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"removeMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"safetyModule","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newComptroller","type":"address"}],"name":"setComptroller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSafetyModule","type":"address"}],"name":"setSafetyModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initializeParams","type":"bytes"}],"name":"setUp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newVault","type":"address"}],"name":"setVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokens","outputs":[{"internalType":"uint256","name":"minBalance","type":"uint256"},{"internalType":"address","name":"marketContract","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newCooldown","type":"uint256"}],"name":"updateClaimRewardsCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

0x6080604052600680546001600160a01b03199081169091556007805482169055600880549091169055620151806009819055600a5534801561004057600080fd5b5061004a3361004f565b61009f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61203f806100ae6000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c8063704802751161010f578063ba46faa4116100a2578063eaa4e39711610071578063eaa4e3971461043c578063ec2c90161461044f578063f2fde38b14610457578063fbfa77cf1461046a57600080fd5b8063ba46faa4146103c0578063bef3a06f146103c9578063db913236146103dc578063e4860339146103ef57600080fd5b80639ead7222116100de5780639ead722214610389578063a4f9edbf1461039c578063aa6ca808146103af578063b7f904f4146103b757600080fd5b8063704802751461034a578063715018a61461035d5780638bad38dd146103655780638da5cb5b1461037857600080fd5b806337bc7995116101875780636817031b116101565780636817031b146103095780636a6278421461031c5780636b69e05b1461032f5780636c24a76f1461033757600080fd5b806337bc7995146102a75780634277bc19146102b0578063429b62e5146102c35780635fe3b567146102f657600080fd5b8063232b956c116101c3578063232b956c1461026057806331ae450b1461027357806334b9558e14610288578063372500ab1461029f57600080fd5b806306814c8c146101f557806311117fc81461020a5780631785f53c1461023a578063190f3b0e1461024d575b600080fd5b610208610203366004611cbe565b61047d565b005b61021d610218366004611cfa565b6105aa565b6040516001600160a01b0390911681526020015b60405180910390f35b610208610248366004611d13565b6105d4565b61020861025b366004611cbe565b61073a565b61021d61026e366004611cfa565b610858565b61027b610868565b6040516102319190611d79565b610291600b5481565b604051908152602001610231565b6102086108ca565b610291600c5481565b6102086102be366004611d13565b610aa8565b6102e66102d1366004611d13565b60026020526000908152604090205460ff1681565b6040519015158152602001610231565b60075461021d906001600160a01b031681565b610208610317366004611d13565b610b29565b61020861032a366004611d13565b610baa565b610208610fe8565b610291610345366004611d13565b61118b565b610208610358366004611d13565b6112c9565b61020861135d565b610208610373366004611d13565b61136f565b6000546001600160a01b031661021d565b61021d610397366004611cfa565b6113f0565b6102086103aa366004611da2565b611400565b61027b611789565b610291600a5481565b61029160095481565b60085461021d906001600160a01b031681565b6102086103ea366004611d13565b6117e9565b61041f6103fd366004611d13565b600160208190526000918252604090912080549101546001600160a01b031682565b604080519283526001600160a01b03909116602083015201610231565b61020861044a366004611cfa565b611a2f565b61027b611a9c565b610208610465366004611d13565b611afc565b60065461021d906001600160a01b031681565b3360009081526002602052604090205460ff166104b55760405162461bcd60e51b81526004016104ac90611e53565b60405180910390fd5b6040805180820182528381526001600160a01b038381166020808401828152888416600081815260018085528882209751885592519683018054979096166001600160a01b031997881617909555600480548084019091557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180548716821790556005805492830181559094527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180549094168217909355835186815292830152917f9781ca4d875ac031055c59b5c3517505b4215eaf500ae23142ed3f23f89b99d491015b60405180910390a2505050565b600381815481106105ba57600080fd5b6000918252602090912001546001600160a01b0316905081565b6105dc611b75565b6001600160a01b0381166000908152600260205260408120805460ff191690555b60035481101561070257816001600160a01b03166003828154811061062457610624611e83565b6000918252602090912001546001600160a01b0316036106f0576003805461064e90600190611eaf565b8154811061065e5761065e611e83565b600091825260209091200154600380546001600160a01b03909216918390811061068a5761068a611e83565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060038054806106c9576106c9611ec6565b600082815260209020810160001990810180546001600160a01b0319169055019055610702565b806106fa81611edc565b9150506105fd565b506040516001600160a01b038216907fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f90600090a250565b3360009081526002602052604090205460ff166107695760405162461bcd60e51b81526004016104ac90611e53565b6001600160a01b0383811660009081526001602081905260409091200154166107d45760405162461bcd60e51b815260206004820152601a60248201527f6175746f4d696e743a206d61726b6574206e6f7420666f756e6400000000000060448201526064016104ac565b6040805180820182528381526001600160a01b03838116602080840182815288841660008181526001808552908890209651875591519590910180546001600160a01b031916959094169490941790925583518681529182015290917f0fdb1e6fbbb4f78b49d76dda4c1abd885c2c61bc5a3c8f7dc7333dbfed207c47910161059d565b600581815481106105ba57600080fd5b606060038054806020026020016040519081016040528092919081815260200182805480156108c057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116108a2575b5050505050905090565b600954600b546108da9190611ef5565b4210156109295760405162461bcd60e51b815260206004820152601e60248201527f6175746f4d696e743a20636f6f6c646f776e206e6f742072656163686564000060448201526064016104ac565b42600b5560075460058054604080516020808402820181019092528281526001600160a01b03909416936000939092909183018282801561099357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610975575b5050600654604051633a22995760e11b81529495506001600160a01b038088169563744532ae95506109d19450600093509116908690600401611f0d565b600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050600654604051633a22995760e11b81526001600160a01b03808716945063744532ae9350610a39926001929116908690600401611f0d565b600060405180830381600087803b158015610a5357600080fd5b505af1158015610a67573d6000803e3d6000fd5b505050507fed6771ea2f01816faa7ccf034b76201581d0b4374e86f83b06a8b4191c6b9f8942604051610a9c91815260200190565b60405180910390a15050565b3360009081526002602052604090205460ff16610ad75760405162461bcd60e51b81526004016104ac90611e53565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fbad9696e81d9dae078b1047e81b564a2a752b8332bfafa1ba95bb472d0c3995d90600090a35050565b3360009081526002602052604090205460ff16610b585760405162461bcd60e51b81526004016104ac90611e53565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8800deb8c31293b539eaf5391fcc88280dc58f015c043d65dd5b72a0979a1dd190600090a35050565b6001600160a01b03808216600081815260016020818152604080842081518083019092528054825290920154909416938101939093529190606090610d1b576006546001600160a01b031631925082610c455760405162461bcd60e51b815260206004820152601e60248201527f6175746f4d696e743a206e6f20617661696c61626c652062616c616e6365000060448201526064016104ac565b50604080516004815260248101909152602080820180516001600160e01b0316631249c58b60e01b179052820151610c809084836000611bcf565b15610cd15781602001516001600160a01b03167f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe84604051610cc491815260200190565b60405180910390a2610fe2565b81602001516001600160a01b0316846001600160a01b03167fcf820e941f79eb0198ff9801f6d38152eb9187b4bbc056920f02aaab2096820f60405160405180910390a350505050565b610d248461118b565b925060008311610d765760405162461bcd60e51b815260206004820152601e60248201527f6175746f4d696e743a206e6f20617661696c61626c652062616c616e6365000060448201526064016104ac565b602082810151604080516001600160a01b0390921660248301526044808301879052815180840390910181526064909201905290810180516001600160e01b031663095ea7b360e01b179052610dcf8560008381611bcf565b15610e2a5782602001516001600160a01b0316856001600160a01b03167f80da462ebfbe41cfc9bc015e7a9a3c7a2a73dbccede72d8ceb583606c27f8f9086604051610e1d91815260200190565b60405180910390a3610e75565b82602001516001600160a01b0316856001600160a01b03167f1b6c83ab3d6c1a2bc303598b02d3efbe429db254d638526edcac9b58afe314d860405160405180910390a35050505050565b60085460208401516001600160a01b03918216911603610ee057600654604080516001600160a01b039092166024830152604480830187905281518084039091018152606490920190526020810180516001600160e01b03166356e4bb9760e11b1790529150610f1b565b6040805160248082018790528251808303909101815260449091019091526020810180516001600160e01b031663140e25ad60e31b17905291505b6020830151610f44906001600160a01b03871615610f3a576000610f3c565b855b846000611bcf565b15610f955782602001516001600160a01b03167f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe85604051610f8891815260200190565b60405180910390a2610fe0565b82602001516001600160a01b0316856001600160a01b03167fcf820e941f79eb0198ff9801f6d38152eb9187b4bbc056920f02aaab2096820f60405160405180910390a35050505050565b505b50505050565b600a54600c54610ff89190611ef5565b4210156110475760405162461bcd60e51b815260206004820152601e60248201527f6175746f4d696e743a20636f6f6c646f776e206e6f742072656163686564000060448201526064016104ac565b42600b556008546006546040516346df7f7160e11b81526001600160a01b03918216600482018190529190921691639a99b4f091908390638dbefee290602401602060405180830381865afa1580156110a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c89190611f3a565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561110e57600080fd5b505af192505050801561111f575060015b611159576040514281527f60e98818d572ffb9a61a91aa4dfd85284db7bd1e3e0f53bce480594f65080645906020015b60405180910390a1565b6040514281527f99286ebc338de8c4322de68e2c3e211d63cac6045f7e2335d92a4dde3bf74b949060200161114f565b565b6001600160a01b03808216600090815260016020818152604080842081518083019092528054825290920154909316928101839052909161120e5760405162461bcd60e51b815260206004820152601a60248201527f6175746f4d696e743a206d61726b6574206e6f7420666f756e6400000000000060448201526064016104ac565b60006001600160a01b03841661123157506006546001600160a01b0316316112a2565b6006546040516370a0823160e01b81526001600160a01b039182166004820152908516906370a0823190602401602060405180830381865afa15801561127b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129f9190611f3a565b90505b81518111156112bf5781516112b79082611eaf565b949350505050565b5060009392505050565b6112d1611b75565b6001600160a01b038116600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517f44d6d25963f097ad14f29f06854a01f575648a1ef82f30e562ccd3889717e3399190a250565b611365611b75565b6111896000611c52565b3360009081526002602052604090205460ff1661139e5760405162461bcd60e51b81526004016104ac90611e53565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907ff9c778bc4132bd7b4191bd075fe55f09ae6c902c7e7ed4208bcad804ed147feb90600090a35050565b600481815481106105ba57600080fd5b611408611b75565b611411336112c9565b466105058190036115e057611439730b7a0eaa884849c6af7a129e899536dddca4905e61136f565b61145673cd76e63f3abfa864c53b4b98f57c1aa6539fda3a610aa8565b6008546114849073bb8d88bcd9749636bc4d2be22aac4bb3b01a58f1906000906001600160a01b031661047d565b6114b873ffffffff1fcacbd218edc0eba20fc2308c778080600073a0d116513bd0b8f3f14e6ea41556c6ec34688e0f61047d565b6114ec73639a647fbe20b6c8ac19e48e2de44ea792c62c5c6000736503d905338e2ebb550c9ec39ced525b612e77ae61047d565b61152073e3f5a90f9cb311505cd691a46596599aa1a0ad7d600073d0670aee3698f66e2d4daf071eb9c690d978bfa861047d565b61155473b44a9b6905af7c801311e8f4e76932ee959c663c60007336918b66f9a3ec7a59d0007d8458db17bdffbf2161047d565b611588731a93b23281cc1cde4c4741353f3064709a16197d60007393ef8b7c6171bab1c0a51092b2c9da8dc2ba0e9d61047d565b6115bc736ab6d61428fde76768d7b45d8bfeec19c6ef91a86000736e745367f4ad2b3da7339aee65dc85d416614d9061047d565b6115dc600080736a1a771c7826596652dadc9145feaae62b1cd07f61047d565b5050565b80610504036115dc57611606738e00d5e02e65a19337cdba98bba9f84d4186a18061136f565b611623738568a675384d761f36ec269d695d6ce4423cfab1610aa8565b6008546116519073511ab53f793683763e5a8829738301368a2411e3906000906001600160a01b031661047d565b61168573d22da948c0ab3a27f5570b604f3adef5f68211c3600073ffffffff1fcacbd218edc0eba20fc2308c77808061047d565b6116b97342a96c0681b74838ec525adbd13c37f66388f289600073ffffffffea09fb06d082fd1275cd48b191cbcd1d61047d565b6116ed731c55649f73cda2f72cef3dd6c5ca3d49efcf484c600073322e86852e492a7ee17f28a78c663da38fb33bfb61047d565b61172173744b1756e7651c6d57f5311767eafe5e931d615b600073931715fee2d06333043d11f658c8ce934ac61d0c61047d565b61175573b6c94b3a378537300387b57ab1cc0d2083f9aeac600073ab3f0245b83feb11d15aaffefd7ad465a59817ed61047d565b6115dc73aaa20c5a584a9fecdfedd71e46da7858b774a9ce600073e57ebd2d67b462e9926e04a8e33f01cd0d64346d61047d565b606060048054806020026020016040519081016040528092919081815260200182805480156108c0576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116108a2575050505050905090565b3360009081526002602052604090205460ff166118185760405162461bcd60e51b81526004016104ac90611e53565b6001600160a01b038116600090815260016020819052604082208281550180546001600160a01b03191690555b6004548110156119f757816001600160a01b03166004828154811061186c5761186c611e83565b6000918252602090912001546001600160a01b0316036119e5576004805461189690600190611eaf565b815481106118a6576118a6611e83565b600091825260209091200154600480546001600160a01b0390921691839081106118d2576118d2611e83565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600480548061191157611911611ec6565b600082815260209020810160001990810180546001600160a01b03191690550190556005805461194390600190611eaf565b8154811061195357611953611e83565b600091825260209091200154600580546001600160a01b03909216918390811061197f5761197f611e83565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060058054806119be576119be611ec6565b600082815260209020810160001990810180546001600160a01b03191690550190556119f7565b806119ef81611edc565b915050611845565b506040516001600160a01b038216907f59d7b1e52008dc342c9421dadfc773114b914a65682a4e4b53cf60a970df0d7790600090a250565b3360009081526002602052604090205460ff16611a5e5760405162461bcd60e51b81526004016104ac90611e53565b600980549082905560408051828152602081018490527f5953b565c074c2cce1866b4e69c9efc4908556bb6fca70f735907c94d94055159101610a9c565b606060058054806020026020016040519081016040528092919081815260200182805480156108c0576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116108a2575050505050905090565b611b04611b75565b6001600160a01b038116611b695760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104ac565b611b7281611c52565b50565b6000546001600160a01b031633146111895760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ac565b60065460405163468721a760e01b81526000916001600160a01b03169063468721a790611c06908890889088908890600401611f75565b6020604051808303816000875af1158015611c25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c499190611fe7565b95945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80356001600160a01b0381168114611cb957600080fd5b919050565b600080600060608486031215611cd357600080fd5b611cdc84611ca2565b925060208401359150611cf160408501611ca2565b90509250925092565b600060208284031215611d0c57600080fd5b5035919050565b600060208284031215611d2557600080fd5b611d2e82611ca2565b9392505050565b600081518084526020808501945080840160005b83811015611d6e5781516001600160a01b031687529582019590820190600101611d49565b509495945050505050565b602081526000611d2e6020830184611d35565b634e487b7160e01b600052604160045260246000fd5b600060208284031215611db457600080fd5b813567ffffffffffffffff80821115611dcc57600080fd5b818401915084601f830112611de057600080fd5b813581811115611df257611df2611d8c565b604051601f8201601f19908116603f01168101908382118183101715611e1a57611e1a611d8c565b81604052828152876020848701011115611e3357600080fd5b826020860160208301376000928101602001929092525095945050505050565b60208082526016908201527530baba37a6b4b73a1d103737ba1030b71030b236b4b760511b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082821015611ec157611ec1611e99565b500390565b634e487b7160e01b600052603160045260246000fd5b600060018201611eee57611eee611e99565b5060010190565b60008219821115611f0857611f08611e99565b500190565b60ff841681526001600160a01b0383166020820152606060408201819052600090611c4990830184611d35565b600060208284031215611f4c57600080fd5b5051919050565b60028110611f7157634e487b7160e01b600052602160045260246000fd5b9052565b60018060a01b038516815260006020858184015260806040840152845180608085015260005b81811015611fb75786810183015185820160a001528201611f9b565b81811115611fc957600060a083870101525b50601f01601f1916830160a0019150611c4990506060830184611f53565b600060208284031215611ff957600080fd5b81518015158114611d2e57600080fdfea26469706673582212207aff29e933f0123dbb1e32b1a37ffe4c60678b22af49d887f813f62caea62e2364736f6c634300080d0033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101f05760003560e01c8063704802751161010f578063ba46faa4116100a2578063eaa4e39711610071578063eaa4e3971461043c578063ec2c90161461044f578063f2fde38b14610457578063fbfa77cf1461046a57600080fd5b8063ba46faa4146103c0578063bef3a06f146103c9578063db913236146103dc578063e4860339146103ef57600080fd5b80639ead7222116100de5780639ead722214610389578063a4f9edbf1461039c578063aa6ca808146103af578063b7f904f4146103b757600080fd5b8063704802751461034a578063715018a61461035d5780638bad38dd146103655780638da5cb5b1461037857600080fd5b806337bc7995116101875780636817031b116101565780636817031b146103095780636a6278421461031c5780636b69e05b1461032f5780636c24a76f1461033757600080fd5b806337bc7995146102a75780634277bc19146102b0578063429b62e5146102c35780635fe3b567146102f657600080fd5b8063232b956c116101c3578063232b956c1461026057806331ae450b1461027357806334b9558e14610288578063372500ab1461029f57600080fd5b806306814c8c146101f557806311117fc81461020a5780631785f53c1461023a578063190f3b0e1461024d575b600080fd5b610208610203366004611cbe565b61047d565b005b61021d610218366004611cfa565b6105aa565b6040516001600160a01b0390911681526020015b60405180910390f35b610208610248366004611d13565b6105d4565b61020861025b366004611cbe565b61073a565b61021d61026e366004611cfa565b610858565b61027b610868565b6040516102319190611d79565b610291600b5481565b604051908152602001610231565b6102086108ca565b610291600c5481565b6102086102be366004611d13565b610aa8565b6102e66102d1366004611d13565b60026020526000908152604090205460ff1681565b6040519015158152602001610231565b60075461021d906001600160a01b031681565b610208610317366004611d13565b610b29565b61020861032a366004611d13565b610baa565b610208610fe8565b610291610345366004611d13565b61118b565b610208610358366004611d13565b6112c9565b61020861135d565b610208610373366004611d13565b61136f565b6000546001600160a01b031661021d565b61021d610397366004611cfa565b6113f0565b6102086103aa366004611da2565b611400565b61027b611789565b610291600a5481565b61029160095481565b60085461021d906001600160a01b031681565b6102086103ea366004611d13565b6117e9565b61041f6103fd366004611d13565b600160208190526000918252604090912080549101546001600160a01b031682565b604080519283526001600160a01b03909116602083015201610231565b61020861044a366004611cfa565b611a2f565b61027b611a9c565b610208610465366004611d13565b611afc565b60065461021d906001600160a01b031681565b3360009081526002602052604090205460ff166104b55760405162461bcd60e51b81526004016104ac90611e53565b60405180910390fd5b6040805180820182528381526001600160a01b038381166020808401828152888416600081815260018085528882209751885592519683018054979096166001600160a01b031997881617909555600480548084019091557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180548716821790556005805492830181559094527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180549094168217909355835186815292830152917f9781ca4d875ac031055c59b5c3517505b4215eaf500ae23142ed3f23f89b99d491015b60405180910390a2505050565b600381815481106105ba57600080fd5b6000918252602090912001546001600160a01b0316905081565b6105dc611b75565b6001600160a01b0381166000908152600260205260408120805460ff191690555b60035481101561070257816001600160a01b03166003828154811061062457610624611e83565b6000918252602090912001546001600160a01b0316036106f0576003805461064e90600190611eaf565b8154811061065e5761065e611e83565b600091825260209091200154600380546001600160a01b03909216918390811061068a5761068a611e83565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060038054806106c9576106c9611ec6565b600082815260209020810160001990810180546001600160a01b0319169055019055610702565b806106fa81611edc565b9150506105fd565b506040516001600160a01b038216907fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f90600090a250565b3360009081526002602052604090205460ff166107695760405162461bcd60e51b81526004016104ac90611e53565b6001600160a01b0383811660009081526001602081905260409091200154166107d45760405162461bcd60e51b815260206004820152601a60248201527f6175746f4d696e743a206d61726b6574206e6f7420666f756e6400000000000060448201526064016104ac565b6040805180820182528381526001600160a01b03838116602080840182815288841660008181526001808552908890209651875591519590910180546001600160a01b031916959094169490941790925583518681529182015290917f0fdb1e6fbbb4f78b49d76dda4c1abd885c2c61bc5a3c8f7dc7333dbfed207c47910161059d565b600581815481106105ba57600080fd5b606060038054806020026020016040519081016040528092919081815260200182805480156108c057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116108a2575b5050505050905090565b600954600b546108da9190611ef5565b4210156109295760405162461bcd60e51b815260206004820152601e60248201527f6175746f4d696e743a20636f6f6c646f776e206e6f742072656163686564000060448201526064016104ac565b42600b5560075460058054604080516020808402820181019092528281526001600160a01b03909416936000939092909183018282801561099357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610975575b5050600654604051633a22995760e11b81529495506001600160a01b038088169563744532ae95506109d19450600093509116908690600401611f0d565b600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050600654604051633a22995760e11b81526001600160a01b03808716945063744532ae9350610a39926001929116908690600401611f0d565b600060405180830381600087803b158015610a5357600080fd5b505af1158015610a67573d6000803e3d6000fd5b505050507fed6771ea2f01816faa7ccf034b76201581d0b4374e86f83b06a8b4191c6b9f8942604051610a9c91815260200190565b60405180910390a15050565b3360009081526002602052604090205460ff16610ad75760405162461bcd60e51b81526004016104ac90611e53565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fbad9696e81d9dae078b1047e81b564a2a752b8332bfafa1ba95bb472d0c3995d90600090a35050565b3360009081526002602052604090205460ff16610b585760405162461bcd60e51b81526004016104ac90611e53565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8800deb8c31293b539eaf5391fcc88280dc58f015c043d65dd5b72a0979a1dd190600090a35050565b6001600160a01b03808216600081815260016020818152604080842081518083019092528054825290920154909416938101939093529190606090610d1b576006546001600160a01b031631925082610c455760405162461bcd60e51b815260206004820152601e60248201527f6175746f4d696e743a206e6f20617661696c61626c652062616c616e6365000060448201526064016104ac565b50604080516004815260248101909152602080820180516001600160e01b0316631249c58b60e01b179052820151610c809084836000611bcf565b15610cd15781602001516001600160a01b03167f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe84604051610cc491815260200190565b60405180910390a2610fe2565b81602001516001600160a01b0316846001600160a01b03167fcf820e941f79eb0198ff9801f6d38152eb9187b4bbc056920f02aaab2096820f60405160405180910390a350505050565b610d248461118b565b925060008311610d765760405162461bcd60e51b815260206004820152601e60248201527f6175746f4d696e743a206e6f20617661696c61626c652062616c616e6365000060448201526064016104ac565b602082810151604080516001600160a01b0390921660248301526044808301879052815180840390910181526064909201905290810180516001600160e01b031663095ea7b360e01b179052610dcf8560008381611bcf565b15610e2a5782602001516001600160a01b0316856001600160a01b03167f80da462ebfbe41cfc9bc015e7a9a3c7a2a73dbccede72d8ceb583606c27f8f9086604051610e1d91815260200190565b60405180910390a3610e75565b82602001516001600160a01b0316856001600160a01b03167f1b6c83ab3d6c1a2bc303598b02d3efbe429db254d638526edcac9b58afe314d860405160405180910390a35050505050565b60085460208401516001600160a01b03918216911603610ee057600654604080516001600160a01b039092166024830152604480830187905281518084039091018152606490920190526020810180516001600160e01b03166356e4bb9760e11b1790529150610f1b565b6040805160248082018790528251808303909101815260449091019091526020810180516001600160e01b031663140e25ad60e31b17905291505b6020830151610f44906001600160a01b03871615610f3a576000610f3c565b855b846000611bcf565b15610f955782602001516001600160a01b03167f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe85604051610f8891815260200190565b60405180910390a2610fe0565b82602001516001600160a01b0316856001600160a01b03167fcf820e941f79eb0198ff9801f6d38152eb9187b4bbc056920f02aaab2096820f60405160405180910390a35050505050565b505b50505050565b600a54600c54610ff89190611ef5565b4210156110475760405162461bcd60e51b815260206004820152601e60248201527f6175746f4d696e743a20636f6f6c646f776e206e6f742072656163686564000060448201526064016104ac565b42600b556008546006546040516346df7f7160e11b81526001600160a01b03918216600482018190529190921691639a99b4f091908390638dbefee290602401602060405180830381865afa1580156110a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c89190611f3a565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561110e57600080fd5b505af192505050801561111f575060015b611159576040514281527f60e98818d572ffb9a61a91aa4dfd85284db7bd1e3e0f53bce480594f65080645906020015b60405180910390a1565b6040514281527f99286ebc338de8c4322de68e2c3e211d63cac6045f7e2335d92a4dde3bf74b949060200161114f565b565b6001600160a01b03808216600090815260016020818152604080842081518083019092528054825290920154909316928101839052909161120e5760405162461bcd60e51b815260206004820152601a60248201527f6175746f4d696e743a206d61726b6574206e6f7420666f756e6400000000000060448201526064016104ac565b60006001600160a01b03841661123157506006546001600160a01b0316316112a2565b6006546040516370a0823160e01b81526001600160a01b039182166004820152908516906370a0823190602401602060405180830381865afa15801561127b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129f9190611f3a565b90505b81518111156112bf5781516112b79082611eaf565b949350505050565b5060009392505050565b6112d1611b75565b6001600160a01b038116600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517f44d6d25963f097ad14f29f06854a01f575648a1ef82f30e562ccd3889717e3399190a250565b611365611b75565b6111896000611c52565b3360009081526002602052604090205460ff1661139e5760405162461bcd60e51b81526004016104ac90611e53565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907ff9c778bc4132bd7b4191bd075fe55f09ae6c902c7e7ed4208bcad804ed147feb90600090a35050565b600481815481106105ba57600080fd5b611408611b75565b611411336112c9565b466105058190036115e057611439730b7a0eaa884849c6af7a129e899536dddca4905e61136f565b61145673cd76e63f3abfa864c53b4b98f57c1aa6539fda3a610aa8565b6008546114849073bb8d88bcd9749636bc4d2be22aac4bb3b01a58f1906000906001600160a01b031661047d565b6114b873ffffffff1fcacbd218edc0eba20fc2308c778080600073a0d116513bd0b8f3f14e6ea41556c6ec34688e0f61047d565b6114ec73639a647fbe20b6c8ac19e48e2de44ea792c62c5c6000736503d905338e2ebb550c9ec39ced525b612e77ae61047d565b61152073e3f5a90f9cb311505cd691a46596599aa1a0ad7d600073d0670aee3698f66e2d4daf071eb9c690d978bfa861047d565b61155473b44a9b6905af7c801311e8f4e76932ee959c663c60007336918b66f9a3ec7a59d0007d8458db17bdffbf2161047d565b611588731a93b23281cc1cde4c4741353f3064709a16197d60007393ef8b7c6171bab1c0a51092b2c9da8dc2ba0e9d61047d565b6115bc736ab6d61428fde76768d7b45d8bfeec19c6ef91a86000736e745367f4ad2b3da7339aee65dc85d416614d9061047d565b6115dc600080736a1a771c7826596652dadc9145feaae62b1cd07f61047d565b5050565b80610504036115dc57611606738e00d5e02e65a19337cdba98bba9f84d4186a18061136f565b611623738568a675384d761f36ec269d695d6ce4423cfab1610aa8565b6008546116519073511ab53f793683763e5a8829738301368a2411e3906000906001600160a01b031661047d565b61168573d22da948c0ab3a27f5570b604f3adef5f68211c3600073ffffffff1fcacbd218edc0eba20fc2308c77808061047d565b6116b97342a96c0681b74838ec525adbd13c37f66388f289600073ffffffffea09fb06d082fd1275cd48b191cbcd1d61047d565b6116ed731c55649f73cda2f72cef3dd6c5ca3d49efcf484c600073322e86852e492a7ee17f28a78c663da38fb33bfb61047d565b61172173744b1756e7651c6d57f5311767eafe5e931d615b600073931715fee2d06333043d11f658c8ce934ac61d0c61047d565b61175573b6c94b3a378537300387b57ab1cc0d2083f9aeac600073ab3f0245b83feb11d15aaffefd7ad465a59817ed61047d565b6115dc73aaa20c5a584a9fecdfedd71e46da7858b774a9ce600073e57ebd2d67b462e9926e04a8e33f01cd0d64346d61047d565b606060048054806020026020016040519081016040528092919081815260200182805480156108c0576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116108a2575050505050905090565b3360009081526002602052604090205460ff166118185760405162461bcd60e51b81526004016104ac90611e53565b6001600160a01b038116600090815260016020819052604082208281550180546001600160a01b03191690555b6004548110156119f757816001600160a01b03166004828154811061186c5761186c611e83565b6000918252602090912001546001600160a01b0316036119e5576004805461189690600190611eaf565b815481106118a6576118a6611e83565b600091825260209091200154600480546001600160a01b0390921691839081106118d2576118d2611e83565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600480548061191157611911611ec6565b600082815260209020810160001990810180546001600160a01b03191690550190556005805461194390600190611eaf565b8154811061195357611953611e83565b600091825260209091200154600580546001600160a01b03909216918390811061197f5761197f611e83565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060058054806119be576119be611ec6565b600082815260209020810160001990810180546001600160a01b03191690550190556119f7565b806119ef81611edc565b915050611845565b506040516001600160a01b038216907f59d7b1e52008dc342c9421dadfc773114b914a65682a4e4b53cf60a970df0d7790600090a250565b3360009081526002602052604090205460ff16611a5e5760405162461bcd60e51b81526004016104ac90611e53565b600980549082905560408051828152602081018490527f5953b565c074c2cce1866b4e69c9efc4908556bb6fca70f735907c94d94055159101610a9c565b606060058054806020026020016040519081016040528092919081815260200182805480156108c0576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116108a2575050505050905090565b611b04611b75565b6001600160a01b038116611b695760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104ac565b611b7281611c52565b50565b6000546001600160a01b031633146111895760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ac565b60065460405163468721a760e01b81526000916001600160a01b03169063468721a790611c06908890889088908890600401611f75565b6020604051808303816000875af1158015611c25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c499190611fe7565b95945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80356001600160a01b0381168114611cb957600080fd5b919050565b600080600060608486031215611cd357600080fd5b611cdc84611ca2565b925060208401359150611cf160408501611ca2565b90509250925092565b600060208284031215611d0c57600080fd5b5035919050565b600060208284031215611d2557600080fd5b611d2e82611ca2565b9392505050565b600081518084526020808501945080840160005b83811015611d6e5781516001600160a01b031687529582019590820190600101611d49565b509495945050505050565b602081526000611d2e6020830184611d35565b634e487b7160e01b600052604160045260246000fd5b600060208284031215611db457600080fd5b813567ffffffffffffffff80821115611dcc57600080fd5b818401915084601f830112611de057600080fd5b813581811115611df257611df2611d8c565b604051601f8201601f19908116603f01168101908382118183101715611e1a57611e1a611d8c565b81604052828152876020848701011115611e3357600080fd5b826020860160208301376000928101602001929092525095945050505050565b60208082526016908201527530baba37a6b4b73a1d103737ba1030b71030b236b4b760511b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082821015611ec157611ec1611e99565b500390565b634e487b7160e01b600052603160045260246000fd5b600060018201611eee57611eee611e99565b5060010190565b60008219821115611f0857611f08611e99565b500190565b60ff841681526001600160a01b0383166020820152606060408201819052600090611c4990830184611d35565b600060208284031215611f4c57600080fd5b5051919050565b60028110611f7157634e487b7160e01b600052602160045260246000fd5b9052565b60018060a01b038516815260006020858184015260806040840152845180608085015260005b81811015611fb75786810183015185820160a001528201611f9b565b81811115611fc957600060a083870101525b50601f01601f1916830160a0019150611c4990506060830184611f53565b600060208284031215611ff957600080fd5b81518015158114611d2e57600080fdfea26469706673582212207aff29e933f0123dbb1e32b1a37ffe4c60678b22af49d887f813f62caea62e2364736f6c634300080d0033

Block Transaction Gas Used Reward
view all blocks collator

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.