Contract 0xf33efa22671bcd023a121ae72587643a697666c4

Contract Overview

Balance:
0 DEV
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xf72a9f105db527c78424eedc599f6d63eaa8f29a64a42cc576ebf171506690d30x6080604025723672022-07-29 21:21:18187 days 23 mins ago0x16f4898f47c085c41d7cc6b1dc72b91ea617dcbb IN  Contract Creation0 DEV0.054695651
[ Download CSV Export 
Latest 17 internal transactions
Parent Txn Hash Block From To Value
0xea69e4f572572e89507aa7d433bca096ece32ba2cfee727036db965a817b01d125728502022-07-29 23:27:18186 days 22 hrs ago 0xf33efa22671bcd023a121ae72587643a697666c40xd32f3b402cbbb2842c9acdb7b78ba45e5f29ec640 DEV
0xea69e4f572572e89507aa7d433bca096ece32ba2cfee727036db965a817b01d125728502022-07-29 23:27:18186 days 22 hrs ago 0xf33efa22671bcd023a121ae72587643a697666c40xa1b9f2938ee8a19d71da4228d278da013d5eabdc0 DEV
0xea69e4f572572e89507aa7d433bca096ece32ba2cfee727036db965a817b01d125728502022-07-29 23:27:18186 days 22 hrs ago 0xf33efa22671bcd023a121ae72587643a697666c40xa1b9f2938ee8a19d71da4228d278da013d5eabdc0 DEV
0xea69e4f572572e89507aa7d433bca096ece32ba2cfee727036db965a817b01d125728502022-07-29 23:27:18186 days 22 hrs ago 0x3d3d367ca64bec7e47fbeb2cb7640989d8c5f9570xf33efa22671bcd023a121ae72587643a697666c40 DEV
0xea69e4f572572e89507aa7d433bca096ece32ba2cfee727036db965a817b01d125728502022-07-29 23:27:18186 days 22 hrs ago 0xf33efa22671bcd023a121ae72587643a697666c40xd9216fcb8ca2ae7d545754ff675fcb479c33dc350.01 DEV
0xea69e4f572572e89507aa7d433bca096ece32ba2cfee727036db965a817b01d125728502022-07-29 23:27:18186 days 22 hrs ago 0xf33efa22671bcd023a121ae72587643a697666c40xa1b9f2938ee8a19d71da4228d278da013d5eabdc0 DEV
0xea69e4f572572e89507aa7d433bca096ece32ba2cfee727036db965a817b01d125728502022-07-29 23:27:18186 days 22 hrs ago 0x3d3d367ca64bec7e47fbeb2cb7640989d8c5f9570xf33efa22671bcd023a121ae72587643a697666c40.01 DEV
0xc55b5f904557e910593a1b7180cb5d5c2eebff8404ded333ac66f0a8fbdf7a8325728332022-07-29 23:23:36186 days 22 hrs ago 0xf33efa22671bcd023a121ae72587643a697666c40xd32f3b402cbbb2842c9acdb7b78ba45e5f29ec640 DEV
0xc55b5f904557e910593a1b7180cb5d5c2eebff8404ded333ac66f0a8fbdf7a8325728332022-07-29 23:23:36186 days 22 hrs ago 0xf33efa22671bcd023a121ae72587643a697666c40xa1b9f2938ee8a19d71da4228d278da013d5eabdc0 DEV
0xc55b5f904557e910593a1b7180cb5d5c2eebff8404ded333ac66f0a8fbdf7a8325728332022-07-29 23:23:36186 days 22 hrs ago 0xf33efa22671bcd023a121ae72587643a697666c40xa1b9f2938ee8a19d71da4228d278da013d5eabdc0 DEV
0xc55b5f904557e910593a1b7180cb5d5c2eebff8404ded333ac66f0a8fbdf7a8325728332022-07-29 23:23:36186 days 22 hrs ago 0x3d3d367ca64bec7e47fbeb2cb7640989d8c5f9570xf33efa22671bcd023a121ae72587643a697666c40 DEV
0xc55b5f904557e910593a1b7180cb5d5c2eebff8404ded333ac66f0a8fbdf7a8325728332022-07-29 23:23:36186 days 22 hrs ago 0xf33efa22671bcd023a121ae72587643a697666c40xd9216fcb8ca2ae7d545754ff675fcb479c33dc350.01 DEV
0xc55b5f904557e910593a1b7180cb5d5c2eebff8404ded333ac66f0a8fbdf7a8325728332022-07-29 23:23:36186 days 22 hrs ago 0xf33efa22671bcd023a121ae72587643a697666c40xa1b9f2938ee8a19d71da4228d278da013d5eabdc0 DEV
0xc55b5f904557e910593a1b7180cb5d5c2eebff8404ded333ac66f0a8fbdf7a8325728332022-07-29 23:23:36186 days 22 hrs ago 0x3d3d367ca64bec7e47fbeb2cb7640989d8c5f9570xf33efa22671bcd023a121ae72587643a697666c40.01 DEV
0xc93330239d3a1027773c2355592eed80a8647923aafa877e4b2cf934fdcc005b25724532022-07-29 21:45:36186 days 23 hrs ago 0x3d3d367ca64bec7e47fbeb2cb7640989d8c5f9570xf33efa22671bcd023a121ae72587643a697666c40 DEV
0x30e16596b30cfe8008194dedc02eb95914c7196f65adc6b3ee1db9e02392d62e25724002022-07-29 21:30:24187 days 13 mins ago 0x3d3d367ca64bec7e47fbeb2cb7640989d8c5f9570xf33efa22671bcd023a121ae72587643a697666c40 DEV
0xb51db370cc00d2c008301663acc1b7d281c01a12d0b955f23d148d19c34f6c6e25723692022-07-29 21:21:42187 days 22 mins ago 0x3d3d367ca64bec7e47fbeb2cb7640989d8c5f9570xf33efa22671bcd023a121ae72587643a697666c40 DEV
[ Download CSV Export 
Loading

Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x50b88b83Fee5036F94425CD55D5Cd9Cf8c3fC7c3

Contract Name:
SatelliteLoanAgent

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)

File 1 of 20 : LoanAgent.sol
//SPDX-License-Identifier: UNLICENSE
pragma solidity ^0.8.4;

import "./interfaces/ILoanAgent.sol";
import "./LoanAgentAdmin.sol";
import "./LoanAgentEvents.sol";
import "./LoanAgentMessageHandler.sol";
import "./LoanAgentInternals.sol";
import "../../util/CommonModifiers.sol";

contract SatelliteLoanAgent is
    ILoanAgent,
    LoanAgentAdmin,
    LoanAgentMessageHandler,
    LoanAgentInternals,
    CommonModifiers
{
    function initialize(address eccAddress) external onlyOwner() {
        require(address(eccAddress) != address(0), "NON_ZEROADDRESS");
        ecc = IECC(eccAddress);
    }

    /**
     * @notice Users borrow assets from the protocol to their own address
     * @param borrowAmount The amount of the underlying asset to borrow
     */
    function borrow(
        uint256 borrowAmount,
        address route,
        address loanMarketAsset
    ) external payable virtual override {
        _sendBorrow(
            msg.sender,
            borrowAmount,
            route,
            loanMarketAsset
        );
    }

    function repayBorrow(
        uint256 repayAmount,
        address route,
        address loanMarketAsset
    ) external payable virtual override returns (bool) {
        _repayBorrowFresh(msg.sender, msg.sender, repayAmount, route, loanMarketAsset);

        return true;
    }

    function repayBorrowBehalf(
        address borrower,
        uint256 repayAmount,
        address route,
        address loanMarketAsset
    ) external payable virtual override returns (bool) {
        _repayBorrowFresh(msg.sender, borrower, repayAmount, route, loanMarketAsset);

        return true;
    }

    fallback() external payable {}
}

File 2 of 20 : ILoanAgent.sol
//SPDX-License-Identifier: UNLICENSE
pragma solidity ^0.8.4;

import "../LoanAgentStorage.sol";
import "../../../interfaces/IHelper.sol";

abstract contract ILoanAgent is LoanAgentStorage {

    function borrow(
        uint256 borrowAmount,
        address route,
        address loanMarketAsset
    ) external payable virtual;

    function repayBorrow(
        uint256 repayAmount,
        address route,
        address loanMarketAsset
    ) external payable virtual returns (bool);

    function repayBorrowBehalf(
        address borrower,
        uint256 repayAmount,
        address route,
        address loanMarketAsset
    ) external payable virtual returns (bool);

    function borrowApproved(
        IHelper.FBBorrow memory params,
        bytes32 metadata
    ) external payable virtual;

    function setMidLayer(address newMiddleLayer) external virtual;

    function setMasterCID(uint256 newChainId) external virtual;
}

File 3 of 20 : LoanAgentAdmin.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;

import "./interfaces/ILoanAgent.sol";
import "./LoanAgentModifiers.sol";
import "./LoanAgentEvents.sol";

abstract contract LoanAgentAdmin is ILoanAgent, LoanAgentModifiers, LoanAgentEvents {
    function setMidLayer(
        address newMiddleLayer
    ) external override onlyOwner() {
        if(newMiddleLayer == address(0)) revert AddressExpected();
        middleLayer = IMiddleLayer(newMiddleLayer);

        emit SetMidLayer(newMiddleLayer);
    }

    function setMasterCID(
        uint256 newChainId
    ) external override onlyOwner() {
        masterCID = newChainId;

        emit SetMasterCID(newChainId);
    }
}

File 4 of 20 : LoanAgentEvents.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;

abstract contract LoanAgentEvents {
    event BorrowSent(
        address user,
        address loanAgent,
        uint256 amount,
        address loanMarketAsset
    );

    event BorrowApproved(
        address indexed borrower,
        uint256 borrowAmount,
        address loanMarketAsset,
        bool isBorrowAllowed
    );

    event BorrowComplete(
        address indexed borrower,
        address loanAgent,
        address loanMarketAsset,
        uint256 borrowAmount
    );

    event RepaySent(
        address payer,
        address borrower,
        address loanAgent,
        uint256 repayAmount,
        address loanMarketAsset
    );

    event LiquidateBorrow(
        address liquidator,
        address borrower,
        uint256 repayAmount,
        address cTokenCollateral,
        uint256 seizeTokens
    );

    event SetMidLayer(
        address middleLayer
    );

    event SetMasterCID(
        uint256 newChainId
    );
}

File 5 of 20 : LoanAgentMessageHandler.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;

import "../../interfaces/IHelper.sol";
import "./interfaces/ILoanAgent.sol";
import "./interfaces/ILoanAgentInternals.sol";
import "./LoanAgentModifiers.sol";
import "../pusd/interfaces/IPUSD.sol";
import "./LoanAgentEvents.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

abstract contract LoanAgentMessageHandler is ILoanAgent, ILoanAgentInternals, LoanAgentModifiers, LoanAgentEvents {
    // slither-disable-next-line assembly
    function _sendBorrow(
        address user,
        uint256 amount,
        address route,
        address loanMarketAsset
    ) internal virtual override {
        bytes memory payload = abi.encode(
            uint256(0),
            IHelper.MBorrowAllowed(
                IHelper.Selector.MASTER_BORROW_ALLOWED,
                user,
                amount,
                loanMarketAsset
            )
        );

        bytes32 metadata = ecc.preRegMsg(payload, msg.sender);
        assembly {
            mstore(add(payload, 0x20), metadata)
        }

        middleLayer.msend{value: msg.value}(
            masterCID,
            payload, // bytes payload
            payable(msg.sender), // refund address
            route
        );

        emit BorrowSent(
            user,
            address(this),
            amount,
            loanMarketAsset
        );
    }

    function borrowApproved(
        IHelper.FBBorrow memory params,
        bytes32 metadata
    ) external payable override virtual onlyMid() {
        if (!ecc.preProcessingValidation(abi.encode(params), metadata)) revert EccMessageAlreadyProcessed();

        if (!ecc.flagMsgValidated(abi.encode(params), metadata)) revert EccFailedToValidate();

        emit BorrowApproved(
            params.user,
            params.borrowAmount,
            params.loanMarketAsset,
            true
        );

        /////////////////////////
        // EFFECTS & INTERACTIONS
        // (No safe failures beyond this point)

        /*
         * We invoke doTransferOut for the borrower and the borrowAmount.
         *  Note: The pToken must handle variations between ERC-20 and ETH underlying.
         *  On success, the pToken borrowAmount less of cash.
         *  doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.
         */
        // This can be easily simplified because we are only issuing one token - PuSD
        // doTransferOut(borrower, borrowAmount);
        // might need a safe transfer of sorts

        // FIXME: Rename IPUSD to something more generic.
        IPUSD(params.loanMarketAsset).mint(params.user, params.borrowAmount);

        emit BorrowComplete(
            params.user,
            address(this),
            params.loanMarketAsset,
            params.borrowAmount
        );
    }

    // slither-disable-next-line assembly
    function _repayBorrowFresh(
        address payer,
        address borrower,
        uint256 repayAmount,
        address route,
        address loanMarketAsset
    ) internal virtual override returns (uint256) {
        /////////////////////////
        // EFFECTS & INTERACTIONS
        // (No safe failures beyond this point)

        /*
        * We call doTransferIn for the payer and the repayAmount
        *  Note: The pToken must handle variations between ERC-20 and ETH underlying.
        *  On success, the pToken holds an additional repayAmount of cash.
        *  doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.
        *   it returns the amount actually transferred, in case of a fee.
        */
        ERC20Burnable(loanMarketAsset).burnFrom(payer, repayAmount);

        bytes memory payload = abi.encode(
            uint256(0),
            IHelper.MRepay({
                selector: IHelper.Selector.MASTER_REPAY,
                borrower: borrower,
                amountRepaid: repayAmount,
                loanMarketAsset: loanMarketAsset
            })
        );

        bytes32 metadata = ecc.preRegMsg(payload, msg.sender);
        assembly {
            mstore(add(payload, 0x20), metadata)
        }

        middleLayer.msend{ value: msg.value }(
            masterCID,
            payload,
            payable(msg.sender),
            route
        );

        emit RepaySent(
            payer,
            borrower,
            address(this),
            repayAmount,
            loanMarketAsset
        );

        return repayAmount;
    }
}

File 6 of 20 : LoanAgentInternals.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;

import "./interfaces/ILoanAgentInternals.sol";
import "../../interfaces/IHelper.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";

abstract contract LoanAgentInternals is ILoanAgentInternals {

}

File 7 of 20 : CommonModifiers.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;

import "./CommonErrors.sol";

abstract contract CommonModifiers is CommonErrors {

    /**
    * @dev Guard variable for re-entrancy checks
    */
    bool internal notEntered;

    constructor() {
        notEntered = true;
    }

    /**
    * @dev Prevents a contract from calling itself, directly or indirectly.
    */
    modifier nonReentrant() {
        if (!notEntered) revert Reentrancy();
        notEntered = false;
        _;
        notEntered = true; // get a gas-refund post-Istanbul
    }
}

File 8 of 20 : LoanAgentStorage.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;

import "../../middleLayer/interfaces/IMiddleLayer.sol";
import "../../ecc/interfaces/IECC.sol";

abstract contract LoanAgentStorage {
    /**
    * @notice Administrator for this contract
    */
    address payable public admin;

    // slither-disable-next-line unused-state
    IMiddleLayer internal middleLayer;

    // slither-disable-next-line unused-state
    IECC internal ecc;

    // slither-disable-next-line unused-state
    uint256 internal masterCID;
}

File 9 of 20 : IHelper.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.4;

interface IHelper {
    enum Selector {
        MASTER_DEPOSIT,
        MASTER_REDEEM_ALLOWED,
        FB_REDEEM,
        MASTER_REPAY,
        MASTER_BORROW_ALLOWED,
        FB_BORROW,
        SATELLITE_LIQUIDATE_BORROW,
        PUSD_BRIDGE
    }

    // !!!!
    // @dev
    // an artificial uint256 param for metadata should be added
    // after packing the payload
    // metadata can be generated via call to ecc.preRegMsg()

    struct MDeposit {
        Selector selector; // = Selector.MASTER_DEPOSIT
        address user;
        address pToken;
        uint256 previousAmount;
        uint256 amountIncreased;
    }

    struct MRedeemAllowed {
        Selector selector; // = Selector.MASTER_REDEEM_ALLOWED
        address pToken;
        address user;
        uint256 amount;
    }

    struct FBRedeem {
        Selector selector; // = Selector.FB_REDEEM
        address pToken;
        address user;
        uint256 redeemAmount;
    }

    struct MRepay {
        Selector selector; // = Selector.MASTER_REPAY
        address borrower;
        uint256 amountRepaid;
        address loanMarketAsset;
    }

    struct MBorrowAllowed {
        Selector selector; // = Selector.MASTER_BORROW_ALLOWED
        address user;
        uint256 borrowAmount;
        address loanMarketAsset;
    }

    struct FBBorrow {
        Selector selector; // = Selector.FB_BORROW
        address user;
        uint256 borrowAmount;
        address loanMarketAsset;
    }

    struct SLiquidateBorrow {
        Selector selector; // = Selector.SATELLITE_LIQUIDATE_BORROW
        address borrower;
        address liquidator;
        uint256 seizeTokens;
        address pTokenCollateral;
    }


    struct PUSDBridge {
        uint8 selector; // = Selector.PUSD_BRIDGE
        address minter;
        uint256 amount;
    }
}

File 10 of 20 : IMiddleLayer.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

abstract contract IMiddleLayer {
    /**
     * @notice routes and encodes messages for you
     * @param params - abi.encode() of the struct related to the selector, used to generate _payload
     * all params starting with '_' are directly sent to the lz 'send()' function
     */
    function msend(
        uint256 _dstChainId,
        bytes memory params,
        address payable _refundAddress,
        address fallbackAddress
    ) external payable virtual;

    function mreceive(
        uint256 _srcChainId,
        bytes memory payload
    ) external virtual;
}

File 11 of 20 : IECC.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

interface IECC {
    struct Metadata {
        bytes5 soph; // start of payload hash
        uint40 creation;
        uint16 nonce; // in case the same exact message is sent multiple times the same block, we increase the nonce in metadata
        address sender;
    }

    function preRegMsg(
        bytes memory payload,
        address instigator
    ) external returns (bytes32 metadata);

    function preProcessingValidation(
        bytes memory payload,
        bytes32 metadata
    ) external view returns (bool allowed);

    function flagMsgValidated(
        bytes memory payload,
        bytes32 metadata
    ) external returns (bool);

    // function rsm(uint256 messagePtr) external returns (bool);
}

File 12 of 20 : LoanAgentModifiers.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;

import "./LoanAgentStorage.sol";
import "../../util/CommonErrors.sol";

abstract contract LoanAgentModifiers is LoanAgentStorage, CommonErrors {

    modifier onlyOwner() {
        if(msg.sender != admin) revert OnlyOwner();
        _;
    }

    modifier onlyMid() {
        if (msg.sender != address(middleLayer)) revert OnlyMiddleLayer();
        _;
    }
}

File 13 of 20 : CommonErrors.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;

abstract contract CommonErrors {
    error AccountNoAssets(address account);
    error AddressExpected();
    error EccMessageAlreadyProcessed();
    error EccFailedToValidate();
    error ExpectedRedeemAmount();
    error ExpectedRepayAmount();
    error InsufficientReserves();
    error InvalidPayload();
    error InvalidPrice();
    error MarketExists();
    error MarketIsPaused();
    error NotInMarket(uint256 chainId, address token);
    error OnlyAuth();
    error OnlyGateway();
    error OnlyMiddleLayer();
    error OnlyOwner();
    error OnlyRoute();
    error Reentrancy();
    error RepayTooMuch(uint256 repayAmount, uint256 maxAmount);
    error RedeemTooMuch();
    error NotEnoughBalance(address token, address who);
    error LiquidateDisallowed();
    error SeizeTooMuch();
    error RouteNotSupported(address route);
    error TransferFailed(address from, address dest);
    error TransferPaused();
    error UnknownRevert();
}

File 14 of 20 : ILoanAgentInternals.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;

import "../LoanAgentStorage.sol";

abstract contract ILoanAgentInternals is LoanAgentStorage {

    function _repayBorrowFresh(
        address payer,
        address borrower,
        uint256 repayAmount,
        address route,
        address loanMarketAsset
    ) internal virtual returns (uint256);

    function _sendBorrow(
        address user,
        uint256 amount,
        address route,
        address loanMarketAsset
    ) internal virtual;
}

File 15 of 20 : IPUSD.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;

interface IPUSD {
    function mint(address to, uint256 amount) external;
}

File 16 of 20 : ERC20Burnable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)

pragma solidity ^0.8.0;

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

/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        _spendAllowance(account, _msgSender(), amount);
        _burn(account, amount);
    }
}

File 17 of 20 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, _allowances[owner][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = _allowances[owner][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Spend `amount` form the allowance of `owner` toward `spender`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

File 18 of 20 : Context.sol
// 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 19 of 20 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves `amount` tokens from the caller's account to `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);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

File 20 of 20 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AccountNoAssets","type":"error"},{"inputs":[],"name":"AddressExpected","type":"error"},{"inputs":[],"name":"EccFailedToValidate","type":"error"},{"inputs":[],"name":"EccMessageAlreadyProcessed","type":"error"},{"inputs":[],"name":"ExpectedRedeemAmount","type":"error"},{"inputs":[],"name":"ExpectedRepayAmount","type":"error"},{"inputs":[],"name":"InsufficientReserves","type":"error"},{"inputs":[],"name":"InvalidPayload","type":"error"},{"inputs":[],"name":"InvalidPrice","type":"error"},{"inputs":[],"name":"LiquidateDisallowed","type":"error"},{"inputs":[],"name":"MarketExists","type":"error"},{"inputs":[],"name":"MarketIsPaused","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"who","type":"address"}],"name":"NotEnoughBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"name":"NotInMarket","type":"error"},{"inputs":[],"name":"OnlyAuth","type":"error"},{"inputs":[],"name":"OnlyGateway","type":"error"},{"inputs":[],"name":"OnlyMiddleLayer","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[],"name":"OnlyRoute","type":"error"},{"inputs":[],"name":"RedeemTooMuch","type":"error"},{"inputs":[],"name":"Reentrancy","type":"error"},{"inputs":[{"internalType":"uint256","name":"repayAmount","type":"uint256"},{"internalType":"uint256","name":"maxAmount","type":"uint256"}],"name":"RepayTooMuch","type":"error"},{"inputs":[{"internalType":"address","name":"route","type":"address"}],"name":"RouteNotSupported","type":"error"},{"inputs":[],"name":"SeizeTooMuch","type":"error"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"dest","type":"address"}],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"TransferPaused","type":"error"},{"inputs":[],"name":"UnknownRevert","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"borrowAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"loanMarketAsset","type":"address"},{"indexed":false,"internalType":"bool","name":"isBorrowAllowed","type":"bool"}],"name":"BorrowApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"address","name":"loanAgent","type":"address"},{"indexed":false,"internalType":"address","name":"loanMarketAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"borrowAmount","type":"uint256"}],"name":"BorrowComplete","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"loanAgent","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"loanMarketAsset","type":"address"}],"name":"BorrowSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"liquidator","type":"address"},{"indexed":false,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"repayAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"cTokenCollateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"seizeTokens","type":"uint256"}],"name":"LiquidateBorrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"payer","type":"address"},{"indexed":false,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"address","name":"loanAgent","type":"address"},{"indexed":false,"internalType":"uint256","name":"repayAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"loanMarketAsset","type":"address"}],"name":"RepaySent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newChainId","type":"uint256"}],"name":"SetMasterCID","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"middleLayer","type":"address"}],"name":"SetMidLayer","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"borrowAmount","type":"uint256"},{"internalType":"address","name":"route","type":"address"},{"internalType":"address","name":"loanMarketAsset","type":"address"}],"name":"borrow","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"enum IHelper.Selector","name":"selector","type":"uint8"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"borrowAmount","type":"uint256"},{"internalType":"address","name":"loanMarketAsset","type":"address"}],"internalType":"struct IHelper.FBBorrow","name":"params","type":"tuple"},{"internalType":"bytes32","name":"metadata","type":"bytes32"}],"name":"borrowApproved","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"eccAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"repayAmount","type":"uint256"},{"internalType":"address","name":"route","type":"address"},{"internalType":"address","name":"loanMarketAsset","type":"address"}],"name":"repayBorrow","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"repayAmount","type":"uint256"},{"internalType":"address","name":"route","type":"address"},{"internalType":"address","name":"loanMarketAsset","type":"address"}],"name":"repayBorrowBehalf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newChainId","type":"uint256"}],"name":"setMasterCID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMiddleLayer","type":"address"}],"name":"setMidLayer","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b506004805460ff19166001179055610d678061002d6000396000f3fe6080604052600436106100785760003560e01c8063d51641841161004b578063d5164184146100f5578063f851a44014610108578063fad65a2414610140578063fba8f5261461016057005b80630312cadf1461007a5780636da791381461008d5780638596cf85146100ad578063c4d66de8146100d5575b005b610078610088366004610a3c565b610173565b34801561009957600080fd5b506100786100a8366004610ad8565b610442565b6100c06100bb366004610af3565b6104e9565b60405190151581526020015b60405180910390f35b3480156100e157600080fd5b506100786100f0366004610ad8565b610505565b610078610103366004610af3565b61059e565b34801561011457600080fd5b50600054610128906001600160a01b031681565b6040516001600160a01b0390911681526020016100cc565b34801561014c57600080fd5b5061007861015b366004610b2f565b6105af565b6100c061016e366004610b48565b61060f565b6001546001600160a01b0316331461019e5760405163275e4def60e01b815260040160405180910390fd5b6002546040516001600160a01b0390911690637b199563906101c4908590602001610bfb565b604051602081830303815290604052836040518363ffffffff1660e01b81526004016101f1929190610c5c565b602060405180830381865afa15801561020e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102329190610c7e565b61024f57604051638fe72a3360e01b815260040160405180910390fd5b6002546040516001600160a01b0390911690639495a3e390610275908590602001610bfb565b604051602081830303815290604052836040518363ffffffff1660e01b81526004016102a2929190610c5c565b6020604051808303816000875af11580156102c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e59190610c7e565b610302576040516309643d3560e21b815260040160405180910390fd5b81602001516001600160a01b03167fe1a738792e562395beade949e6f88a43cb7b354eb1a13b65176fda2428ae8f41836040015184606001516001604051610368939291909283526001600160a01b039190911660208301521515604082015260600190565b60405180910390a26060820151602083015160408085015190516340c10f1960e01b81526001600160a01b03928316600482015260248101919091529116906340c10f1990604401600060405180830381600087803b1580156103ca57600080fd5b505af11580156103de573d6000803e3d6000fd5b50505060208084015160608086015160408088015181513081526001600160a01b03938416968101969096529085015290911692507f04890681715b9e767a55e46f3448a555438937db00d1bfabd2e168448cf0604d910160405180910390a25050565b6000546001600160a01b0316331461046d57604051635fc483c560e01b815260040160405180910390fd5b6001600160a01b03811661049457604051635f3ee81760e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb17ed45d424a865943bf59736196c025b5a877afd2596e31c6b0141a80615d83906020015b60405180910390a150565b60006104f8333386868661062a565b50600190505b9392505050565b6000546001600160a01b0316331461053057604051635fc483c560e01b815260040160405180910390fd5b6001600160a01b03811661057c5760405162461bcd60e51b815260206004820152600f60248201526e4e4f4e5f5a45524f4144445245535360881b604482015260640160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6105aa33848484610858565b505050565b6000546001600160a01b031633146105da57604051635fc483c560e01b815260040160405180910390fd5b60038190556040518181527f159b5fc2542c2deb484f33dcc48f33a46b83bac2a19ea6e33d918b4665743b6a906020016104de565b600061061e338686868661062a565b50600195945050505050565b60405163079cc67960e41b81526001600160a01b03868116600483015260248201859052600091908316906379cc679090604401600060405180830381600087803b15801561067857600080fd5b505af115801561068c573d6000803e3d6000fd5b505050506000806040518060800160405280600360078111156106b1576106b1610b95565b8152602001886001600160a01b03168152602001878152602001856001600160a01b03168152506040516020016106e9929190610ca0565b60408051601f1981840301815290829052600254634ca2500560e01b83529092506000916001600160a01b0390911690634ca250059061072f9085903390600401610cb4565b6020604051808303816000875af115801561074e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107729190610cde565b60208301819052600154600354604051633483addf60e11b81529293506001600160a01b03909116916369075bbe9134916107b69190879033908c90600401610cf7565b6000604051808303818588803b1580156107cf57600080fd5b505af11580156107e3573d6000803e3d6000fd5b5050604080516001600160a01b03808e168252808d1660208301523092820192909252606081018b905290881660808201527fa6041b8c7555083b2510c583759ee9afe73ac382f1c104803d4d157100c54d19935060a00191506108449050565b60405180910390a150939695505050505050565b60008060405180608001604052806004600781111561087957610879610b95565b8152602001876001600160a01b03168152602001868152602001846001600160a01b03168152506040516020016108b1929190610ca0565b60408051601f1981840301815290829052600254634ca2500560e01b83529092506000916001600160a01b0390911690634ca25005906108f79085903390600401610cb4565b6020604051808303816000875af1158015610916573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093a9190610cde565b60208301819052600154600354604051633483addf60e11b81529293506001600160a01b03909116916369075bbe91349161097e9190879033908b90600401610cf7565b6000604051808303818588803b15801561099757600080fd5b505af11580156109ab573d6000803e3d6000fd5b5050604080516001600160a01b03808c1682523060208301529181018a905290871660608201527f49ddf8634c6b6410199f904aefabde84762c242db5abcd8f1d1d20ba7cc1397793506080019150610a019050565b60405180910390a1505050505050565b803560088110610a2057600080fd5b919050565b80356001600160a01b0381168114610a2057600080fd5b60008082840360a0811215610a5057600080fd5b6080811215610a5e57600080fd5b506040516080810181811067ffffffffffffffff82111715610a9057634e487b7160e01b600052604160045260246000fd5b604052610a9c84610a11565b8152610aaa60208501610a25565b602082015260408401356040820152610ac560608501610a25565b6060820152946080939093013593505050565b600060208284031215610aea57600080fd5b6104fe82610a25565b600080600060608486031215610b0857600080fd5b83359250610b1860208501610a25565b9150610b2660408501610a25565b90509250925092565b600060208284031215610b4157600080fd5b5035919050565b60008060008060808587031215610b5e57600080fd5b610b6785610a25565b935060208501359250610b7c60408601610a25565b9150610b8a60608601610a25565b905092959194509250565b634e487b7160e01b600052602160045260246000fd5b805160088110610bcb57634e487b7160e01b600052602160045260246000fd5b82526020818101516001600160a01b03908116918401919091526040808301519084015260609182015116910152565b60808101610c098284610bab565b92915050565b6000815180845260005b81811015610c3557602081850181015186830182015201610c19565b81811115610c47576000602083870101525b50601f01601f19169290920160200192915050565b604081526000610c6f6040830185610c0f565b90508260208301529392505050565b600060208284031215610c9057600080fd5b815180151581146104fe57600080fd5b82815260a081016104fe6020830184610bab565b604081526000610cc76040830185610c0f565b905060018060a01b03831660208301529392505050565b600060208284031215610cf057600080fd5b5051919050565b848152608060208201526000610d106080830186610c0f565b6001600160a01b03948516604084015292909316606090910152939250505056fea2646970667358221220c6f5700cd424ca11e5d2315e61ffab1c6cb777e94d9f420e8774b9b3d5f844a264736f6c634300080d0033

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading