ETH Price: $3,490.94 (+1.61%)

Contract

0xb639D208Bcf0589D54FaC24E655C79EC529762B8
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction and > 10 Token Transfers found.

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block
From
To
176992492023-07-15 14:02:59524 days ago1689429779  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
GhoFlashMinter

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
london EvmVersion, MIT license
File 1 of 11 : GhoFlashMinter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IACLManager} from '@aave/core-v3/contracts/interfaces/IACLManager.sol';
import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
import {PercentageMath} from '@aave/core-v3/contracts/protocol/libraries/math/PercentageMath.sol';
import {IERC3156FlashBorrower} from '@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol';
import {IERC3156FlashLender} from '@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol';
import {IGhoToken} from '../../gho/interfaces/IGhoToken.sol';
import {IGhoFacilitator} from '../../gho/interfaces/IGhoFacilitator.sol';
import {IGhoFlashMinter} from './interfaces/IGhoFlashMinter.sol';

/**
 * @title GhoFlashMinter
 * @author Aave
 * @notice Contract that enables FlashMinting of GHO.
 * @dev Based heavily on the EIP3156 reference implementation
 */
contract GhoFlashMinter is IGhoFlashMinter {
  using PercentageMath for uint256;

  // @inheritdoc IGhoFlashMinter
  bytes32 public constant CALLBACK_SUCCESS = keccak256('ERC3156FlashBorrower.onFlashLoan');

  // @inheritdoc IGhoFlashMinter
  uint256 public constant MAX_FEE = 1e4;

  // @inheritdoc IGhoFlashMinter
  IPoolAddressesProvider public immutable override ADDRESSES_PROVIDER;

  // @inheritdoc IGhoFlashMinter
  IGhoToken public immutable GHO_TOKEN;

  // The Access Control List manager contract
  IACLManager private immutable ACL_MANAGER;

  // The flashmint fee, expressed in bps (a value of 10000 results in 100.00%)
  uint256 private _fee;

  // The GHO treasury, the recipient of fee distributions
  address private _ghoTreasury;

  /**
   * @dev Only pool admin can call functions marked by this modifier.
   */
  modifier onlyPoolAdmin() {
    require(ACL_MANAGER.isPoolAdmin(msg.sender), 'CALLER_NOT_POOL_ADMIN');
    _;
  }

  /**
   * @dev Constructor
   * @param ghoToken The address of the GHO token contract
   * @param ghoTreasury The address of the GHO treasury
   * @param fee The percentage of the flash-mint amount that needs to be repaid, on top of the principal (in bps)
   * @param addressesProvider The address of the Aave PoolAddressesProvider
   */
  constructor(address ghoToken, address ghoTreasury, uint256 fee, address addressesProvider) {
    require(fee <= MAX_FEE, 'FlashMinter: Fee out of range');
    GHO_TOKEN = IGhoToken(ghoToken);
    _updateGhoTreasury(ghoTreasury);
    _updateFee(fee);
    ADDRESSES_PROVIDER = IPoolAddressesProvider(addressesProvider);
    ACL_MANAGER = IACLManager(IPoolAddressesProvider(addressesProvider).getACLManager());
  }

  /// @inheritdoc IERC3156FlashLender
  function flashLoan(
    IERC3156FlashBorrower receiver,
    address token,
    uint256 amount,
    bytes calldata data
  ) external override returns (bool) {
    require(token == address(GHO_TOKEN), 'FlashMinter: Unsupported currency');

    uint256 fee = ACL_MANAGER.isFlashBorrower(msg.sender) ? 0 : _flashFee(amount);
    GHO_TOKEN.mint(address(receiver), amount);

    require(
      receiver.onFlashLoan(msg.sender, address(GHO_TOKEN), amount, fee, data) == CALLBACK_SUCCESS,
      'FlashMinter: Callback failed'
    );

    GHO_TOKEN.transferFrom(address(receiver), address(this), amount + fee);
    GHO_TOKEN.burn(amount);

    emit FlashMint(address(receiver), msg.sender, address(GHO_TOKEN), amount, fee);

    return true;
  }

  /// @inheritdoc IGhoFacilitator
  function distributeFeesToTreasury() external override {
    uint256 balance = GHO_TOKEN.balanceOf(address(this));
    GHO_TOKEN.transfer(_ghoTreasury, balance);
    emit FeesDistributedToTreasury(_ghoTreasury, address(GHO_TOKEN), balance);
  }

  // @inheritdoc IGhoFlashMinter
  function updateFee(uint256 newFee) external override onlyPoolAdmin {
    _updateFee(newFee);
  }

  /// @inheritdoc IGhoFacilitator
  function updateGhoTreasury(address newGhoTreasury) external override onlyPoolAdmin {
    _updateGhoTreasury(newGhoTreasury);
  }

  /// @inheritdoc IERC3156FlashLender
  function maxFlashLoan(address token) external view override returns (uint256) {
    if (token != address(GHO_TOKEN)) {
      return 0;
    } else {
      (uint256 capacity, uint256 level) = GHO_TOKEN.getFacilitatorBucket(address(this));
      return capacity > level ? capacity - level : 0;
    }
  }

  /// @inheritdoc IERC3156FlashLender
  function flashFee(address token, uint256 amount) external view override returns (uint256) {
    require(token == address(GHO_TOKEN), 'FlashMinter: Unsupported currency');
    return ACL_MANAGER.isFlashBorrower(msg.sender) ? 0 : _flashFee(amount);
  }

  /// @inheritdoc IGhoFlashMinter
  function getFee() external view override returns (uint256) {
    return _fee;
  }

  /// @inheritdoc IGhoFacilitator
  function getGhoTreasury() external view override returns (address) {
    return _ghoTreasury;
  }

  /**
   * @notice Returns the fee to charge for a given flashloan.
   * @dev Internal function with no checks.
   * @param amount The amount of tokens to be borrowed.
   * @return The amount of `token` to be charged for the flashloan, on top of the returned principal.
   */
  function _flashFee(uint256 amount) internal view returns (uint256) {
    return amount.percentMul(_fee);
  }

  function _updateFee(uint256 newFee) internal {
    require(newFee <= MAX_FEE, 'FlashMinter: Fee out of range');
    uint256 oldFee = _fee;
    _fee = newFee;
    emit FeeUpdated(oldFee, newFee);
  }

  function _updateGhoTreasury(address newGhoTreasury) internal {
    address oldGhoTreasury = _ghoTreasury;
    _ghoTreasury = newGhoTreasury;
    emit GhoTreasuryUpdated(oldGhoTreasury, newGhoTreasury);
  }
}

File 2 of 11 : IACLManager.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;

import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol';

/**
 * @title IACLManager
 * @author Aave
 * @notice Defines the basic interface for the ACL Manager
 */
interface IACLManager {
  /**
   * @notice Returns the contract address of the PoolAddressesProvider
   * @return The address of the PoolAddressesProvider
   */
  function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider);

  /**
   * @notice Returns the identifier of the PoolAdmin role
   * @return The id of the PoolAdmin role
   */
  function POOL_ADMIN_ROLE() external view returns (bytes32);

  /**
   * @notice Returns the identifier of the EmergencyAdmin role
   * @return The id of the EmergencyAdmin role
   */
  function EMERGENCY_ADMIN_ROLE() external view returns (bytes32);

  /**
   * @notice Returns the identifier of the RiskAdmin role
   * @return The id of the RiskAdmin role
   */
  function RISK_ADMIN_ROLE() external view returns (bytes32);

  /**
   * @notice Returns the identifier of the FlashBorrower role
   * @return The id of the FlashBorrower role
   */
  function FLASH_BORROWER_ROLE() external view returns (bytes32);

  /**
   * @notice Returns the identifier of the Bridge role
   * @return The id of the Bridge role
   */
  function BRIDGE_ROLE() external view returns (bytes32);

  /**
   * @notice Returns the identifier of the AssetListingAdmin role
   * @return The id of the AssetListingAdmin role
   */
  function ASSET_LISTING_ADMIN_ROLE() external view returns (bytes32);

  /**
   * @notice Set the role as admin of a specific role.
   * @dev By default the admin role for all roles is `DEFAULT_ADMIN_ROLE`.
   * @param role The role to be managed by the admin role
   * @param adminRole The admin role
   */
  function setRoleAdmin(bytes32 role, bytes32 adminRole) external;

  /**
   * @notice Adds a new admin as PoolAdmin
   * @param admin The address of the new admin
   */
  function addPoolAdmin(address admin) external;

  /**
   * @notice Removes an admin as PoolAdmin
   * @param admin The address of the admin to remove
   */
  function removePoolAdmin(address admin) external;

  /**
   * @notice Returns true if the address is PoolAdmin, false otherwise
   * @param admin The address to check
   * @return True if the given address is PoolAdmin, false otherwise
   */
  function isPoolAdmin(address admin) external view returns (bool);

  /**
   * @notice Adds a new admin as EmergencyAdmin
   * @param admin The address of the new admin
   */
  function addEmergencyAdmin(address admin) external;

  /**
   * @notice Removes an admin as EmergencyAdmin
   * @param admin The address of the admin to remove
   */
  function removeEmergencyAdmin(address admin) external;

  /**
   * @notice Returns true if the address is EmergencyAdmin, false otherwise
   * @param admin The address to check
   * @return True if the given address is EmergencyAdmin, false otherwise
   */
  function isEmergencyAdmin(address admin) external view returns (bool);

  /**
   * @notice Adds a new admin as RiskAdmin
   * @param admin The address of the new admin
   */
  function addRiskAdmin(address admin) external;

  /**
   * @notice Removes an admin as RiskAdmin
   * @param admin The address of the admin to remove
   */
  function removeRiskAdmin(address admin) external;

  /**
   * @notice Returns true if the address is RiskAdmin, false otherwise
   * @param admin The address to check
   * @return True if the given address is RiskAdmin, false otherwise
   */
  function isRiskAdmin(address admin) external view returns (bool);

  /**
   * @notice Adds a new address as FlashBorrower
   * @param borrower The address of the new FlashBorrower
   */
  function addFlashBorrower(address borrower) external;

  /**
   * @notice Removes an address as FlashBorrower
   * @param borrower The address of the FlashBorrower to remove
   */
  function removeFlashBorrower(address borrower) external;

  /**
   * @notice Returns true if the address is FlashBorrower, false otherwise
   * @param borrower The address to check
   * @return True if the given address is FlashBorrower, false otherwise
   */
  function isFlashBorrower(address borrower) external view returns (bool);

  /**
   * @notice Adds a new address as Bridge
   * @param bridge The address of the new Bridge
   */
  function addBridge(address bridge) external;

  /**
   * @notice Removes an address as Bridge
   * @param bridge The address of the bridge to remove
   */
  function removeBridge(address bridge) external;

  /**
   * @notice Returns true if the address is Bridge, false otherwise
   * @param bridge The address to check
   * @return True if the given address is Bridge, false otherwise
   */
  function isBridge(address bridge) external view returns (bool);

  /**
   * @notice Adds a new admin as AssetListingAdmin
   * @param admin The address of the new admin
   */
  function addAssetListingAdmin(address admin) external;

  /**
   * @notice Removes an admin as AssetListingAdmin
   * @param admin The address of the admin to remove
   */
  function removeAssetListingAdmin(address admin) external;

  /**
   * @notice Returns true if the address is AssetListingAdmin, false otherwise
   * @param admin The address to check
   * @return True if the given address is AssetListingAdmin, false otherwise
   */
  function isAssetListingAdmin(address admin) external view returns (bool);
}

File 3 of 11 : IPoolAddressesProvider.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;

/**
 * @title IPoolAddressesProvider
 * @author Aave
 * @notice Defines the basic interface for a Pool Addresses Provider.
 */
interface IPoolAddressesProvider {
  /**
   * @dev Emitted when the market identifier is updated.
   * @param oldMarketId The old id of the market
   * @param newMarketId The new id of the market
   */
  event MarketIdSet(string indexed oldMarketId, string indexed newMarketId);

  /**
   * @dev Emitted when the pool is updated.
   * @param oldAddress The old address of the Pool
   * @param newAddress The new address of the Pool
   */
  event PoolUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the pool configurator is updated.
   * @param oldAddress The old address of the PoolConfigurator
   * @param newAddress The new address of the PoolConfigurator
   */
  event PoolConfiguratorUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the price oracle is updated.
   * @param oldAddress The old address of the PriceOracle
   * @param newAddress The new address of the PriceOracle
   */
  event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the ACL manager is updated.
   * @param oldAddress The old address of the ACLManager
   * @param newAddress The new address of the ACLManager
   */
  event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the ACL admin is updated.
   * @param oldAddress The old address of the ACLAdmin
   * @param newAddress The new address of the ACLAdmin
   */
  event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the price oracle sentinel is updated.
   * @param oldAddress The old address of the PriceOracleSentinel
   * @param newAddress The new address of the PriceOracleSentinel
   */
  event PriceOracleSentinelUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the pool data provider is updated.
   * @param oldAddress The old address of the PoolDataProvider
   * @param newAddress The new address of the PoolDataProvider
   */
  event PoolDataProviderUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when a new proxy is created.
   * @param id The identifier of the proxy
   * @param proxyAddress The address of the created proxy contract
   * @param implementationAddress The address of the implementation contract
   */
  event ProxyCreated(
    bytes32 indexed id,
    address indexed proxyAddress,
    address indexed implementationAddress
  );

  /**
   * @dev Emitted when a new non-proxied contract address is registered.
   * @param id The identifier of the contract
   * @param oldAddress The address of the old contract
   * @param newAddress The address of the new contract
   */
  event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the implementation of the proxy registered with id is updated
   * @param id The identifier of the contract
   * @param proxyAddress The address of the proxy contract
   * @param oldImplementationAddress The address of the old implementation contract
   * @param newImplementationAddress The address of the new implementation contract
   */
  event AddressSetAsProxy(
    bytes32 indexed id,
    address indexed proxyAddress,
    address oldImplementationAddress,
    address indexed newImplementationAddress
  );

  /**
   * @notice Returns the id of the Aave market to which this contract points to.
   * @return The market id
   */
  function getMarketId() external view returns (string memory);

  /**
   * @notice Associates an id with a specific PoolAddressesProvider.
   * @dev This can be used to create an onchain registry of PoolAddressesProviders to
   * identify and validate multiple Aave markets.
   * @param newMarketId The market id
   */
  function setMarketId(string calldata newMarketId) external;

  /**
   * @notice Returns an address by its identifier.
   * @dev The returned address might be an EOA or a contract, potentially proxied
   * @dev It returns ZERO if there is no registered address with the given id
   * @param id The id
   * @return The address of the registered for the specified id
   */
  function getAddress(bytes32 id) external view returns (address);

  /**
   * @notice General function to update the implementation of a proxy registered with
   * certain `id`. If there is no proxy registered, it will instantiate one and
   * set as implementation the `newImplementationAddress`.
   * @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit
   * setter function, in order to avoid unexpected consequences
   * @param id The id
   * @param newImplementationAddress The address of the new implementation
   */
  function setAddressAsProxy(bytes32 id, address newImplementationAddress) external;

  /**
   * @notice Sets an address for an id replacing the address saved in the addresses map.
   * @dev IMPORTANT Use this function carefully, as it will do a hard replacement
   * @param id The id
   * @param newAddress The address to set
   */
  function setAddress(bytes32 id, address newAddress) external;

  /**
   * @notice Returns the address of the Pool proxy.
   * @return The Pool proxy address
   */
  function getPool() external view returns (address);

  /**
   * @notice Updates the implementation of the Pool, or creates a proxy
   * setting the new `pool` implementation when the function is called for the first time.
   * @param newPoolImpl The new Pool implementation
   */
  function setPoolImpl(address newPoolImpl) external;

  /**
   * @notice Returns the address of the PoolConfigurator proxy.
   * @return The PoolConfigurator proxy address
   */
  function getPoolConfigurator() external view returns (address);

  /**
   * @notice Updates the implementation of the PoolConfigurator, or creates a proxy
   * setting the new `PoolConfigurator` implementation when the function is called for the first time.
   * @param newPoolConfiguratorImpl The new PoolConfigurator implementation
   */
  function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external;

  /**
   * @notice Returns the address of the price oracle.
   * @return The address of the PriceOracle
   */
  function getPriceOracle() external view returns (address);

  /**
   * @notice Updates the address of the price oracle.
   * @param newPriceOracle The address of the new PriceOracle
   */
  function setPriceOracle(address newPriceOracle) external;

  /**
   * @notice Returns the address of the ACL manager.
   * @return The address of the ACLManager
   */
  function getACLManager() external view returns (address);

  /**
   * @notice Updates the address of the ACL manager.
   * @param newAclManager The address of the new ACLManager
   */
  function setACLManager(address newAclManager) external;

  /**
   * @notice Returns the address of the ACL admin.
   * @return The address of the ACL admin
   */
  function getACLAdmin() external view returns (address);

  /**
   * @notice Updates the address of the ACL admin.
   * @param newAclAdmin The address of the new ACL admin
   */
  function setACLAdmin(address newAclAdmin) external;

  /**
   * @notice Returns the address of the price oracle sentinel.
   * @return The address of the PriceOracleSentinel
   */
  function getPriceOracleSentinel() external view returns (address);

  /**
   * @notice Updates the address of the price oracle sentinel.
   * @param newPriceOracleSentinel The address of the new PriceOracleSentinel
   */
  function setPriceOracleSentinel(address newPriceOracleSentinel) external;

  /**
   * @notice Returns the address of the data provider.
   * @return The address of the DataProvider
   */
  function getPoolDataProvider() external view returns (address);

  /**
   * @notice Updates the address of the data provider.
   * @param newDataProvider The address of the new DataProvider
   */
  function setPoolDataProvider(address newDataProvider) external;
}

File 4 of 11 : PercentageMath.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

/**
 * @title PercentageMath library
 * @author Aave
 * @notice Provides functions to perform percentage calculations
 * @dev Percentages are defined by default with 2 decimals of precision (100.00). The precision is indicated by PERCENTAGE_FACTOR
 * @dev Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down.
 */
library PercentageMath {
  // Maximum percentage factor (100.00%)
  uint256 internal constant PERCENTAGE_FACTOR = 1e4;

  // Half percentage factor (50.00%)
  uint256 internal constant HALF_PERCENTAGE_FACTOR = 0.5e4;

  /**
   * @notice Executes a percentage multiplication
   * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
   * @param value The value of which the percentage needs to be calculated
   * @param percentage The percentage of the value to be calculated
   * @return result value percentmul percentage
   */
  function percentMul(uint256 value, uint256 percentage) internal pure returns (uint256 result) {
    // to avoid overflow, value <= (type(uint256).max - HALF_PERCENTAGE_FACTOR) / percentage
    assembly {
      if iszero(
        or(
          iszero(percentage),
          iszero(gt(value, div(sub(not(0), HALF_PERCENTAGE_FACTOR), percentage)))
        )
      ) {
        revert(0, 0)
      }

      result := div(add(mul(value, percentage), HALF_PERCENTAGE_FACTOR), PERCENTAGE_FACTOR)
    }
  }

  /**
   * @notice Executes a percentage division
   * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
   * @param value The value of which the percentage needs to be calculated
   * @param percentage The percentage of the value to be calculated
   * @return result value percentdiv percentage
   */
  function percentDiv(uint256 value, uint256 percentage) internal pure returns (uint256 result) {
    // to avoid overflow, value <= (type(uint256).max - halfPercentage) / PERCENTAGE_FACTOR
    assembly {
      if or(
        iszero(percentage),
        iszero(iszero(gt(value, div(sub(not(0), div(percentage, 2)), PERCENTAGE_FACTOR))))
      ) {
        revert(0, 0)
      }

      result := div(add(mul(value, PERCENTAGE_FACTOR), div(percentage, 2)), percentage)
    }
  }
}

File 5 of 11 : IERC3156FlashBorrower.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC3156 FlashBorrower, as defined in
 * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
 *
 * _Available since v4.1._
 */
interface IERC3156FlashBorrower {
    /**
     * @dev Receive a flash loan.
     * @param initiator The initiator of the loan.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @param fee The additional amount of tokens to repay.
     * @param data Arbitrary data structure, intended to contain user-defined parameters.
     * @return The keccak256 hash of "IERC3156FlashBorrower.onFlashLoan"
     */
    function onFlashLoan(
        address initiator,
        address token,
        uint256 amount,
        uint256 fee,
        bytes calldata data
    ) external returns (bytes32);
}

File 6 of 11 : IERC3156FlashLender.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)

pragma solidity ^0.8.0;

import "./IERC3156FlashBorrower.sol";

/**
 * @dev Interface of the ERC3156 FlashLender, as defined in
 * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
 *
 * _Available since v4.1._
 */
interface IERC3156FlashLender {
    /**
     * @dev The amount of currency available to be lended.
     * @param token The loan currency.
     * @return The amount of `token` that can be borrowed.
     */
    function maxFlashLoan(address token) external view returns (uint256);

    /**
     * @dev The fee to be charged for a given loan.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @return The amount of `token` to be charged for the loan, on top of the returned principal.
     */
    function flashFee(address token, uint256 amount) external view returns (uint256);

    /**
     * @dev Initiate a flash loan.
     * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @param data Arbitrary data structure, intended to contain user-defined parameters.
     */
    function flashLoan(
        IERC3156FlashBorrower receiver,
        address token,
        uint256 amount,
        bytes calldata data
    ) external returns (bool);
}

File 7 of 11 : IGhoToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {IAccessControl} from '@openzeppelin/contracts/access/IAccessControl.sol';

/**
 * @title IGhoToken
 * @author Aave
 */
interface IGhoToken is IERC20, IAccessControl {
  struct Facilitator {
    uint128 bucketCapacity;
    uint128 bucketLevel;
    string label;
  }

  /**
   * @dev Emitted when a new facilitator is added
   * @param facilitatorAddress The address of the new facilitator
   * @param label A hashed human readable identifier for the facilitator
   * @param bucketCapacity The initial capacity of the facilitator's bucket
   */
  event FacilitatorAdded(
    address indexed facilitatorAddress,
    bytes32 indexed label,
    uint256 bucketCapacity
  );

  /**
   * @dev Emitted when a facilitator is removed
   * @param facilitatorAddress The address of the removed facilitator
   */
  event FacilitatorRemoved(address indexed facilitatorAddress);

  /**
   * @dev Emitted when the bucket capacity of a facilitator is updated
   * @param facilitatorAddress The address of the facilitator whose bucket capacity is being changed
   * @param oldCapacity The old capacity of the bucket
   * @param newCapacity The new capacity of the bucket
   */
  event FacilitatorBucketCapacityUpdated(
    address indexed facilitatorAddress,
    uint256 oldCapacity,
    uint256 newCapacity
  );

  /**
   * @dev Emitted when the bucket level changed
   * @param facilitatorAddress The address of the facilitator whose bucket level is being changed
   * @param oldLevel The old level of the bucket
   * @param newLevel The new level of the bucket
   */
  event FacilitatorBucketLevelUpdated(
    address indexed facilitatorAddress,
    uint256 oldLevel,
    uint256 newLevel
  );

  /**
   * @notice Returns the identifier of the Facilitator Manager Role
   * @return The bytes32 id hash of the FacilitatorManager role
   */
  function FACILITATOR_MANAGER_ROLE() external pure returns (bytes32);

  /**
   * @notice Returns the identifier of the Bucket Manager Role
   * @return The bytes32 id hash of the BucketManager role
   */
  function BUCKET_MANAGER_ROLE() external pure returns (bytes32);

  /**
   * @notice Mints the requested amount of tokens to the account address.
   * @dev Only facilitators with enough bucket capacity available can mint.
   * @dev The bucket level is increased upon minting.
   * @param account The address receiving the GHO tokens
   * @param amount The amount to mint
   */
  function mint(address account, uint256 amount) external;

  /**
   * @notice Burns the requested amount of tokens from the account address.
   * @dev Only active facilitators (bucket level > 0) can burn.
   * @dev The bucket level is decreased upon burning.
   * @param amount The amount to burn
   */
  function burn(uint256 amount) external;

  /**
   * @notice Add the facilitator passed with the parameters to the facilitators list.
   * @dev Only accounts with `FACILITATOR_MANAGER_ROLE` role can call this function
   * @param facilitatorAddress The address of the facilitator to add
   * @param facilitatorLabel A human readable identifier for the facilitator
   * @param bucketCapacity The upward limit of GHO can be minted by the facilitator
   */
  function addFacilitator(
    address facilitatorAddress,
    string calldata facilitatorLabel,
    uint128 bucketCapacity
  ) external;

  /**
   * @notice Remove the facilitator from the facilitators list.
   * @dev Only accounts with `FACILITATOR_MANAGER_ROLE` role can call this function
   * @param facilitatorAddress The address of the facilitator to remove
   */
  function removeFacilitator(address facilitatorAddress) external;

  /**
   * @notice Set the bucket capacity of the facilitator.
   * @dev Only accounts with `BUCKET_MANAGER_ROLE` role can call this function
   * @param facilitator The address of the facilitator
   * @param newCapacity The new capacity of the bucket
   */
  function setFacilitatorBucketCapacity(address facilitator, uint128 newCapacity) external;

  /**
   * @notice Returns the facilitator data
   * @param facilitator The address of the facilitator
   * @return The facilitator configuration
   */
  function getFacilitator(address facilitator) external view returns (Facilitator memory);

  /**
   * @notice Returns the bucket configuration of the facilitator
   * @param facilitator The address of the facilitator
   * @return The capacity of the facilitator's bucket
   * @return The level of the facilitator's bucket
   */
  function getFacilitatorBucket(address facilitator) external view returns (uint256, uint256);

  /**
   * @notice Returns the list of the addresses of the active facilitator
   * @return The list of the facilitators addresses
   */
  function getFacilitatorsList() external view returns (address[] memory);
}

File 8 of 11 : IGhoFacilitator.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title IGhoFacilitator
 * @author Aave
 * @notice Defines the behavior of a Gho Facilitator
 */
interface IGhoFacilitator {
  /**
   * @dev Emitted when fees are distributed to the GhoTreasury
   * @param ghoTreasury The address of the ghoTreasury
   * @param asset The address of the asset transferred to the ghoTreasury
   * @param amount The amount of the asset transferred to the ghoTreasury
   */
  event FeesDistributedToTreasury(
    address indexed ghoTreasury,
    address indexed asset,
    uint256 amount
  );

  /**
   * @dev Emitted when Gho Treasury address is updated
   * @param oldGhoTreasury The address of the old GhoTreasury contract
   * @param newGhoTreasury The address of the new GhoTreasury contract
   */
  event GhoTreasuryUpdated(address indexed oldGhoTreasury, address indexed newGhoTreasury);

  /**
   * @notice Distribute fees to the GhoTreasury
   */
  function distributeFeesToTreasury() external;

  /**
   * @notice Updates the address of the Gho Treasury
   * @dev WARNING: The GhoTreasury is where revenue fees are sent to. Update carefully
   * @param newGhoTreasury The address of the GhoTreasury
   */
  function updateGhoTreasury(address newGhoTreasury) external;

  /**
   * @notice Returns the address of the Gho Treasury
   * @return The address of the GhoTreasury contract
   */
  function getGhoTreasury() external view returns (address);
}

File 9 of 11 : IGhoFlashMinter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IERC3156FlashLender} from '@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol';
import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
import {IGhoFacilitator} from '../../../gho/interfaces/IGhoFacilitator.sol';
import {IGhoToken} from '../../../gho/interfaces/IGhoToken.sol';

/**
 * @title IGhoFlashMinter
 * @author Aave
 * @notice Defines the behavior of the GHO Flash Minter
 */
interface IGhoFlashMinter is IERC3156FlashLender, IGhoFacilitator {
  /**
   * @dev Emitted when the percentage fee is updated
   * @param oldFee The old fee (in bps)
   * @param newFee The new fee (in bps)
   */
  event FeeUpdated(uint256 oldFee, uint256 newFee);

  /**
   * @dev Emitted when a FlashMint occurs
   * @param receiver The receiver of the FlashMinted tokens (it is also the receiver of the callback)
   * @param initiator The address initiating the FlashMint
   * @param asset The asset being FlashMinted. Always GHO.
   * @param amount The principal being FlashMinted
   * @param fee The fee returned on top of the principal
   */
  event FlashMint(
    address indexed receiver,
    address indexed initiator,
    address asset,
    uint256 indexed amount,
    uint256 fee
  );

  /**
   * @notice Returns the required return value for a successful flashmint
   * @return The required callback, the keccak256 hash of 'ERC3156FlashBorrower.onFlashLoan'
   */
  function CALLBACK_SUCCESS() external view returns (bytes32);

  /**
   * @notice Returns the maximum value the fee can be set to
   * @return The maximum percentage fee of the flash-minted amount that the flashFee can be set to (in bps).
   */
  function MAX_FEE() external view returns (uint256);

  /**
   * @notice Returns the address of the Aave Pool Addresses Provider contract
   * @return The address of the PoolAddressesProvider
   */
  function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider);

  /**
   * @notice Returns the address of the GHO token contract
   * @return The address of the GhoToken
   */
  function GHO_TOKEN() external view returns (IGhoToken);

  /**
   * @notice Updates the percentage fee. It is the percentage of the flash-minted amount that needs to be repaid.
   * @dev The fee is expressed in bps. A value of 100, results in 1.00%
   * @param newFee The new percentage fee (in bps)
   */
  function updateFee(uint256 newFee) external;

  /**
   * @notice Returns the percentage of each flash mint taken as a fee
   * @return The percentage fee of the flash-minted amount that needs to be repaid, on top of the principal (in bps).
   */
  function getFee() external view returns (uint256);
}

File 10 of 11 : IERC20.sol
// 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);
}

File 11 of 11 : IAccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

Settings
{
  "remappings": [
    "@aave/core-v3/=lib/aave-v3-core/",
    "@openzeppelin/=lib/openzeppelin-contracts/",
    "aave-address-book/=lib/aave-address-book/src/",
    "aave-helpers/=lib/aave-helpers/",
    "aave-stk-v1-5/=lib/aave-stk-v1-5/src/",
    "aave-v3-core/=lib/aave-v3-core/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "gho-core/=lib/gho-core/src/contracts/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "solidity-utils/=lib/solidity-utils/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"ghoToken","type":"address"},{"internalType":"address","name":"ghoTreasury","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"address","name":"addressesProvider","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"FeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"ghoTreasury","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesDistributedToTreasury","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"initiator","type":"address"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"FlashMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldGhoTreasury","type":"address"},{"indexed":true,"internalType":"address","name":"newGhoTreasury","type":"address"}],"name":"GhoTreasuryUpdated","type":"event"},{"inputs":[],"name":"ADDRESSES_PROVIDER","outputs":[{"internalType":"contract IPoolAddressesProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CALLBACK_SUCCESS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GHO_TOKEN","outputs":[{"internalType":"contract IGhoToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributeFeesToTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"flashFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC3156FlashBorrower","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGhoTreasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"maxFlashLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"updateFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newGhoTreasury","type":"address"}],"name":"updateGhoTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e06040523480156200001157600080fd5b50604051620012443803806200124483398101604081905262000034916200023f565b6127108211156200008c5760405162461bcd60e51b815260206004820152601d60248201527f466c6173684d696e7465723a20466565206f7574206f662072616e676500000060448201526064015b60405180910390fd5b6001600160a01b03841660a052620000a48362000137565b620000af8262000189565b6001600160a01b03811660808190526040805163383e6b8b60e11b8152905163707cd716916004808201926020929091908290030181865afa158015620000fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000120919062000293565b6001600160a01b031660c05250620002b892505050565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f13f4413d8d93a259bd6c10f35095371f30ed50f81a73407e52e9f02000d5d16b90600090a35050565b612710811115620001dd5760405162461bcd60e51b815260206004820152601d60248201527f466c6173684d696e7465723a20466565206f7574206f662072616e6765000000604482015260640162000083565b600080549082905560408051828152602081018490527f528d9479e9f9889a87a3c30c7f7ba537e5e59c4c85a37733b16e57c62df61302910160405180910390a15050565b80516001600160a01b03811681146200023a57600080fd5b919050565b600080600080608085870312156200025657600080fd5b620002618562000222565b9350620002716020860162000222565b925060408501519150620002886060860162000222565b905092959194509250565b600060208284031215620002a657600080fd5b620002b18262000222565b9392505050565b60805160a05160c051610ef462000350600039600081816102090152818161033c015281816108000152610928015260008181610195015281816102d5015281816103ed015281816104930152818161055d0152818161061d0152818161068d015281816106fc0152818161075d015281816108c4015281816109cf01528181610a6e0152610aef0152600060be0152610ef46000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063b1c660f711610071578063b1c660f714610190578063bc063e1a146101b7578063ced72f87146101c0578063d9d98ce4146101c8578063dc49a07b146101db578063e28178cc146101e357600080fd5b80630542975c146100b95780631fde40bb146100fd5780635cffe9de14610112578063613255ab146101355780638237e538146101565780639012c4a81461017d575b600080fd5b6100e07f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61011061010b366004610c7c565b6101f4565b005b610125610120366004610c99565b6102d1565b60405190151581526020016100f4565b610148610143366004610c7c565b6106f8565b6040519081526020016100f4565b6101487f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b61011061018b366004610d38565b6107eb565b6100e07f000000000000000000000000000000000000000000000000000000000000000081565b61014861271081565b600054610148565b6101486101d6366004610d51565b6108c0565b6101106109b7565b6001546001600160a01b03166100e0565b604051637be53ca160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690637be53ca190602401602060405180830381865afa158015610258573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061027c9190610d7d565b6102c55760405162461bcd60e51b815260206004820152601560248201527421a0a62622a92fa727aa2fa827a7a62fa0a226a4a760591b60448201526064015b60405180910390fd5b6102ce81610b43565b50565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b0316146103245760405162461bcd60e51b81526004016102bc90610d9f565b60405163fa50f29760e01b81523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063fa50f29790602401602060405180830381865afa15801561038b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103af9190610d7d565b6103c1576103bc85610b95565b6103c4565b60005b6040516340c10f1960e01b81526001600160a01b038981166004830152602482018890529192507f0000000000000000000000000000000000000000000000000000000000000000909116906340c10f1990604401600060405180830381600087803b15801561043357600080fd5b505af1158015610447573d6000803e3d6000fd5b50506040516323e30c8b60e01b81527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd992506001600160a01b038a1691506323e30c8b906104c39033907f0000000000000000000000000000000000000000000000000000000000000000908b9088908c908c90600401610de0565b6020604051808303816000875af11580156104e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105069190610e3c565b146105535760405162461bcd60e51b815260206004820152601c60248201527f466c6173684d696e7465723a2043616c6c6261636b206661696c65640000000060448201526064016102bc565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166323b872dd883061058e858a610e6b565b6040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015260448201526064016020604051808303816000875af11580156105e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106069190610d7d565b50604051630852cd8d60e31b8152600481018690527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342966c6890602401600060405180830381600087803b15801561066957600080fd5b505af115801561067d573d6000803e3d6000fd5b5050604080516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081168252602082018690528994503393508b16917f9c1558194024d73db1b6fc2739c3070cacc4598122100dd6f7d3a3dd8cee5f36910160405180910390a45060019695505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461073b57506000919050565b6040516355017ca560e11b815230600482015260009081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063aa02f94a906024016040805180830381865afa1580156107a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c79190610e83565b915091508082116107d95760006107e3565b6107e38183610ea7565b949350505050565b604051637be53ca160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690637be53ca190602401602060405180830381865afa15801561084f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108739190610d7d565b6108b75760405162461bcd60e51b815260206004820152601560248201527421a0a62622a92fa727aa2fa827a7a62fa0a226a4a760591b60448201526064016102bc565b6102ce81610baa565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316146109135760405162461bcd60e51b81526004016102bc90610d9f565b60405163fa50f29760e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063fa50f29790602401602060405180830381865afa158015610977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099b9190610d7d565b6109ad576109a882610b95565b6109b0565b60005b9392505050565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a429190610e3c565b60015460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015610ab7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610adb9190610d7d565b506001546040518281526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169216907fb29fcda740927812f5a71075b62e132bead3769a455319c29b9a1cc461a654759060200160405180910390a350565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f13f4413d8d93a259bd6c10f35095371f30ed50f81a73407e52e9f02000d5d16b90600090a35050565b60008054610ba4908390610c41565b92915050565b612710811115610bfc5760405162461bcd60e51b815260206004820152601d60248201527f466c6173684d696e7465723a20466565206f7574206f662072616e676500000060448201526064016102bc565b600080549082905560408051828152602081018490527f528d9479e9f9889a87a3c30c7f7ba537e5e59c4c85a37733b16e57c62df61302910160405180910390a15050565b600081156113881983900484111517610c5957600080fd5b506127109102611388010490565b6001600160a01b03811681146102ce57600080fd5b600060208284031215610c8e57600080fd5b81356109b081610c67565b600080600080600060808688031215610cb157600080fd5b8535610cbc81610c67565b94506020860135610ccc81610c67565b935060408601359250606086013567ffffffffffffffff80821115610cf057600080fd5b818801915088601f830112610d0457600080fd5b813581811115610d1357600080fd5b896020828501011115610d2557600080fd5b9699959850939650602001949392505050565b600060208284031215610d4a57600080fd5b5035919050565b60008060408385031215610d6457600080fd5b8235610d6f81610c67565b946020939093013593505050565b600060208284031215610d8f57600080fd5b815180151581146109b057600080fd5b60208082526021908201527f466c6173684d696e7465723a20556e737570706f727465642063757272656e636040820152607960f81b606082015260800190565b6001600160a01b03878116825286166020820152604081018590526060810184905260a06080820181905281018290526000828460c0840137600060c0848401015260c0601f19601f8501168301019050979650505050505050565b600060208284031215610e4e57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115610e7e57610e7e610e55565b500190565b60008060408385031215610e9657600080fd5b505080516020909101519092909150565b600082821015610eb957610eb9610e55565b50039056fea264697066735822122071a1bf6462aead685e4e7772090adf4cc0ad8a81aa80bf51490562cc3481693964736f6c634300080a003300000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f000000000000000000000000464c71f6c2f760dda6093dcb91c24c39e5d6e18c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100b45760003560e01c8063b1c660f711610071578063b1c660f714610190578063bc063e1a146101b7578063ced72f87146101c0578063d9d98ce4146101c8578063dc49a07b146101db578063e28178cc146101e357600080fd5b80630542975c146100b95780631fde40bb146100fd5780635cffe9de14610112578063613255ab146101355780638237e538146101565780639012c4a81461017d575b600080fd5b6100e07f0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e81565b6040516001600160a01b0390911681526020015b60405180910390f35b61011061010b366004610c7c565b6101f4565b005b610125610120366004610c99565b6102d1565b60405190151581526020016100f4565b610148610143366004610c7c565b6106f8565b6040519081526020016100f4565b6101487f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b61011061018b366004610d38565b6107eb565b6100e07f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f81565b61014861271081565b600054610148565b6101486101d6366004610d51565b6108c0565b6101106109b7565b6001546001600160a01b03166100e0565b604051637be53ca160e01b81523360048201527f000000000000000000000000c2aacf6553d20d1e9d78e365aaba8032af9c85b06001600160a01b031690637be53ca190602401602060405180830381865afa158015610258573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061027c9190610d7d565b6102c55760405162461bcd60e51b815260206004820152601560248201527421a0a62622a92fa727aa2fa827a7a62fa0a226a4a760591b60448201526064015b60405180910390fd5b6102ce81610b43565b50565b60007f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f6001600160a01b0316856001600160a01b0316146103245760405162461bcd60e51b81526004016102bc90610d9f565b60405163fa50f29760e01b81523360048201526000907f000000000000000000000000c2aacf6553d20d1e9d78e365aaba8032af9c85b06001600160a01b03169063fa50f29790602401602060405180830381865afa15801561038b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103af9190610d7d565b6103c1576103bc85610b95565b6103c4565b60005b6040516340c10f1960e01b81526001600160a01b038981166004830152602482018890529192507f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f909116906340c10f1990604401600060405180830381600087803b15801561043357600080fd5b505af1158015610447573d6000803e3d6000fd5b50506040516323e30c8b60e01b81527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd992506001600160a01b038a1691506323e30c8b906104c39033907f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f908b9088908c908c90600401610de0565b6020604051808303816000875af11580156104e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105069190610e3c565b146105535760405162461bcd60e51b815260206004820152601c60248201527f466c6173684d696e7465723a2043616c6c6261636b206661696c65640000000060448201526064016102bc565b6001600160a01b037f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f166323b872dd883061058e858a610e6b565b6040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015260448201526064016020604051808303816000875af11580156105e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106069190610d7d565b50604051630852cd8d60e31b8152600481018690527f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f6001600160a01b0316906342966c6890602401600060405180830381600087803b15801561066957600080fd5b505af115801561067d573d6000803e3d6000fd5b5050604080516001600160a01b037f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f81168252602082018690528994503393508b16917f9c1558194024d73db1b6fc2739c3070cacc4598122100dd6f7d3a3dd8cee5f36910160405180910390a45060019695505050505050565b60007f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f6001600160a01b0316826001600160a01b03161461073b57506000919050565b6040516355017ca560e11b815230600482015260009081906001600160a01b037f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f169063aa02f94a906024016040805180830381865afa1580156107a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c79190610e83565b915091508082116107d95760006107e3565b6107e38183610ea7565b949350505050565b604051637be53ca160e01b81523360048201527f000000000000000000000000c2aacf6553d20d1e9d78e365aaba8032af9c85b06001600160a01b031690637be53ca190602401602060405180830381865afa15801561084f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108739190610d7d565b6108b75760405162461bcd60e51b815260206004820152601560248201527421a0a62622a92fa727aa2fa827a7a62fa0a226a4a760591b60448201526064016102bc565b6102ce81610baa565b60007f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f6001600160a01b0316836001600160a01b0316146109135760405162461bcd60e51b81526004016102bc90610d9f565b60405163fa50f29760e01b81523360048201527f000000000000000000000000c2aacf6553d20d1e9d78e365aaba8032af9c85b06001600160a01b03169063fa50f29790602401602060405180830381865afa158015610977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099b9190610d7d565b6109ad576109a882610b95565b6109b0565b60005b9392505050565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f6001600160a01b0316906370a0823190602401602060405180830381865afa158015610a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a429190610e3c565b60015460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f169063a9059cbb906044016020604051808303816000875af1158015610ab7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610adb9190610d7d565b506001546040518281526001600160a01b037f00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f81169216907fb29fcda740927812f5a71075b62e132bead3769a455319c29b9a1cc461a654759060200160405180910390a350565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f13f4413d8d93a259bd6c10f35095371f30ed50f81a73407e52e9f02000d5d16b90600090a35050565b60008054610ba4908390610c41565b92915050565b612710811115610bfc5760405162461bcd60e51b815260206004820152601d60248201527f466c6173684d696e7465723a20466565206f7574206f662072616e676500000060448201526064016102bc565b600080549082905560408051828152602081018490527f528d9479e9f9889a87a3c30c7f7ba537e5e59c4c85a37733b16e57c62df61302910160405180910390a15050565b600081156113881983900484111517610c5957600080fd5b506127109102611388010490565b6001600160a01b03811681146102ce57600080fd5b600060208284031215610c8e57600080fd5b81356109b081610c67565b600080600080600060808688031215610cb157600080fd5b8535610cbc81610c67565b94506020860135610ccc81610c67565b935060408601359250606086013567ffffffffffffffff80821115610cf057600080fd5b818801915088601f830112610d0457600080fd5b813581811115610d1357600080fd5b896020828501011115610d2557600080fd5b9699959850939650602001949392505050565b600060208284031215610d4a57600080fd5b5035919050565b60008060408385031215610d6457600080fd5b8235610d6f81610c67565b946020939093013593505050565b600060208284031215610d8f57600080fd5b815180151581146109b057600080fd5b60208082526021908201527f466c6173684d696e7465723a20556e737570706f727465642063757272656e636040820152607960f81b606082015260800190565b6001600160a01b03878116825286166020820152604081018590526060810184905260a06080820181905281018290526000828460c0840137600060c0848401015260c0601f19601f8501168301019050979650505050505050565b600060208284031215610e4e57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115610e7e57610e7e610e55565b500190565b60008060408385031215610e9657600080fd5b505080516020909101519092909150565b600082821015610eb957610eb9610e55565b50039056fea264697066735822122071a1bf6462aead685e4e7772090adf4cc0ad8a81aa80bf51490562cc3481693964736f6c634300080a0033

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

00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f000000000000000000000000464c71f6c2f760dda6093dcb91c24c39e5d6e18c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e

-----Decoded View---------------
Arg [0] : ghoToken (address): 0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f
Arg [1] : ghoTreasury (address): 0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c
Arg [2] : fee (uint256): 0
Arg [3] : addressesProvider (address): 0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f
Arg [1] : 000000000000000000000000464c71f6c2f760dda6093dcb91c24c39e5d6e18c
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e


Deployed Bytecode Sourcemap

902:4746:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1220:67;;;;;;;;-1:-1:-1;;;;;208:32:11;;;190:51;;178:2;163:18;1220:67:3;;;;;;;;3831:128;;;;;;:::i;:::-;;:::i;:::-;;2643:736;;;;;;:::i;:::-;;:::i;:::-;;;1776:14:11;;1769:22;1751:41;;1739:2;1724:18;2643:736:3;1611:187:11;4001:300:3;;;;;;:::i;:::-;;:::i;:::-;;;1949:25:11;;;1937:2;1922:18;4001:300:3;1803:177:11;1019:88:3;;1062:45;1019:88;;3697:96;;;;;;:::i;:::-;;:::i;1325:36::-;;;;;1145:37;;1179:3;1145:37;;4631:81;4681:7;4703:4;4631:81;;4343:250;;;;;;:::i;:::-;;:::i;3417:243::-;;;:::i;4750:97::-;4830:12;;-1:-1:-1;;;;;4830:12:3;4750:97;;3831:128;1774:35;;-1:-1:-1;;;1774:35:3;;1798:10;1774:35;;;190:51:11;1774:11:3;-1:-1:-1;;;;;1774:23:3;;;;163:18:11;;1774:35:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1766:69;;;;-1:-1:-1;;;1766:69:3;;3590:2:11;1766:69:3;;;3572:21:11;3629:2;3609:18;;;3602:30;-1:-1:-1;;;3648:18:11;;;3641:51;3709:18;;1766:69:3;;;;;;;;;3920:34:::1;3939:14;3920:18;:34::i;:::-;3831:128:::0;:::o;2643:736::-;2793:4;2830:9;-1:-1:-1;;;;;2813:27:3;:5;-1:-1:-1;;;;;2813:27:3;;2805:73;;;;-1:-1:-1;;;2805:73:3;;;;;;;:::i;:::-;2899:39;;-1:-1:-1;;;2899:39:3;;2927:10;2899:39;;;190:51:11;2885:11:3;;2899;-1:-1:-1;;;;;2899:27:3;;;;163:18:11;;2899:39:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:63;;2945:17;2955:6;2945:9;:17::i;:::-;2899:63;;;2941:1;2899:63;2968:41;;-1:-1:-1;;;2968:41:3;;-1:-1:-1;;;;;4332:32:11;;;2968:41:3;;;4314:51:11;4381:18;;;4374:34;;;2885:77:3;;-1:-1:-1;2968:9:3;:14;;;;;;4287:18:11;;2968:41:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3031:71:3;;-1:-1:-1;;;3031:71:3;;1062:45;;-1:-1:-1;;;;;;3031:20:3;;;-1:-1:-1;3031:20:3;;:71;;3052:10;;3072:9;;3084:6;;3092:3;;3097:4;;;;3031:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:91;3016:150;;;;-1:-1:-1;;;3016:150:3;;5549:2:11;3016:150:3;;;5531:21:11;5588:2;5568:18;;;5561:30;5627;5607:18;;;5600:58;5675:18;;3016:150:3;5347:352:11;3016:150:3;-1:-1:-1;;;;;3173:9:3;:22;;3204:8;3223:4;3230:12;3239:3;3230:6;:12;:::i;:::-;3173:70;;-1:-1:-1;;;;;;3173:70:3;;;;;;;-1:-1:-1;;;;;6227:15:11;;;3173:70:3;;;6209:34:11;6279:15;;;;6259:18;;;6252:43;6311:18;;;6304:34;6144:18;;3173:70:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;3249:22:3;;-1:-1:-1;;;3249:22:3;;;;;1949:25:11;;;3249:9:3;-1:-1:-1;;;;;3249:14:3;;;;1922:18:11;;3249:22:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3283:73:3;;;-1:-1:-1;;;;;3332:9:3;4332:32:11;;4314:51;;4396:2;4381:18;;4374:34;;;3344:6:3;;-1:-1:-1;3312:10:3;;-1:-1:-1;3283:73:3;;;;;4287:18:11;3283:73:3;;;;;;;-1:-1:-1;3370:4:3;;2643:736;-1:-1:-1;;;;;;2643:736:3:o;4001:300::-;4070:7;4106:9;-1:-1:-1;;;;;4089:27:3;:5;-1:-1:-1;;;;;4089:27:3;;4085:212;;-1:-1:-1;4133:1:3;;4001:300;-1:-1:-1;4001:300:3:o;4085:212::-;4191:45;;-1:-1:-1;;;4191:45:3;;4230:4;4191:45;;;190:51:11;4156:16:3;;;;-1:-1:-1;;;;;4191:9:3;:30;;;;163:18:11;;4191:45:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4155:81;;;;4262:5;4251:8;:16;:39;;4289:1;4251:39;;;4270:16;4281:5;4270:8;:16;:::i;:::-;4244:46;4001:300;-1:-1:-1;;;;4001:300:3:o;3697:96::-;1774:35;;-1:-1:-1;;;1774:35:3;;1798:10;1774:35;;;190:51:11;1774:11:3;-1:-1:-1;;;;;1774:23:3;;;;163:18:11;;1774:35:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1766:69;;;;-1:-1:-1;;;1766:69:3;;3590:2:11;1766:69:3;;;3572:21:11;3629:2;3609:18;;;3602:30;-1:-1:-1;;;3648:18:11;;;3641:51;3709:18;;1766:69:3;3388:345:11;1766:69:3;3770:18:::1;3781:6;3770:10;:18::i;4343:250::-:0;4424:7;4464:9;-1:-1:-1;;;;;4447:27:3;:5;-1:-1:-1;;;;;4447:27:3;;4439:73;;;;-1:-1:-1;;;4439:73:3;;;;;;;:::i;:::-;4525:39;;-1:-1:-1;;;4525:39:3;;4553:10;4525:39;;;190:51:11;4525:11:3;-1:-1:-1;;;;;4525:27:3;;;;163:18:11;;4525:39:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:63;;4571:17;4581:6;4571:9;:17::i;:::-;4525:63;;;4567:1;4525:63;4518:70;4343:250;-1:-1:-1;;;4343:250:3:o;3417:243::-;3495:34;;-1:-1:-1;;;3495:34:3;;3523:4;3495:34;;;190:51:11;3477:15:3;;3495:9;-1:-1:-1;;;;;3495:19:3;;;;163:18:11;;3495:34:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3554:12;;3535:41;;-1:-1:-1;;;3535:41:3;;-1:-1:-1;;;;;3554:12:3;;;3535:41;;;4314:51:11;4381:18;;;4374:34;;;3477:52:3;;-1:-1:-1;3535:9:3;:18;;;;4287::11;;3535:41:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;3613:12:3;;3587:68;;1949:25:11;;;-1:-1:-1;;;;;3635:9:3;3587:68;;;3613:12;;3587:68;;1937:2:11;1922:18;3587:68:3;;;;;;;3471:189;3417:243::o;5441:205::-;5533:12;;;-1:-1:-1;;;;;5551:29:3;;;-1:-1:-1;;;;;;5551:29:3;;;;;;;5591:50;;5533:12;;;5551:29;5533:12;;5591:50;;5508:22;;5591:50;5502:144;5441:205;:::o;5127:108::-;5185:7;5225:4;;5207:23;;:6;;:17;:23::i;:::-;5200:30;5127:108;-1:-1:-1;;5127:108:3:o;5239:198::-;1179:3;5298:6;:17;;5290:59;;;;-1:-1:-1;;;5290:59:3;;7120:2:11;5290:59:3;;;7102:21:11;7159:2;7139:18;;;7132:30;7198:31;7178:18;;;7171:59;7247:18;;5290:59:3;6918:353:11;5290:59:3;5355:14;5372:4;;5382:13;;;;5406:26;;;7450:25:11;;;7506:2;7491:18;;7484:34;;;5406:26:3;;7423:18:11;5406:26:3;;;;;;;5284:153;5239:198;:::o;1005:496:2:-;1083:14;1248:18;;-1:-1:-1;;1295:52:2;;;1285:63;;1278:71;1234:125;1215:183;;1388:1;1385;1378:12;1215:183;-1:-1:-1;1473:17:2;1424:22;;1448;1420:51;1416:75;;1005:496::o;252:131:11:-;-1:-1:-1;;;;;327:31:11;;317:42;;307:70;;373:1;370;363:12;388:247;447:6;500:2;488:9;479:7;475:23;471:32;468:52;;;516:1;513;506:12;468:52;555:9;542:23;574:31;599:5;574:31;:::i;640:966::-;767:6;775;783;791;799;852:3;840:9;831:7;827:23;823:33;820:53;;;869:1;866;859:12;820:53;908:9;895:23;927:31;952:5;927:31;:::i;:::-;977:5;-1:-1:-1;1034:2:11;1019:18;;1006:32;1047:33;1006:32;1047:33;:::i;:::-;1099:7;-1:-1:-1;1153:2:11;1138:18;;1125:32;;-1:-1:-1;1208:2:11;1193:18;;1180:32;1231:18;1261:14;;;1258:34;;;1288:1;1285;1278:12;1258:34;1326:6;1315:9;1311:22;1301:32;;1371:7;1364:4;1360:2;1356:13;1352:27;1342:55;;1393:1;1390;1383:12;1342:55;1433:2;1420:16;1459:2;1451:6;1448:14;1445:34;;;1475:1;1472;1465:12;1445:34;1520:7;1515:2;1506:6;1502:2;1498:15;1494:24;1491:37;1488:57;;;1541:1;1538;1531:12;1488:57;640:966;;;;-1:-1:-1;640:966:11;;-1:-1:-1;1572:2:11;1564:11;;1594:6;640:966;-1:-1:-1;;;640:966:11:o;2167:180::-;2226:6;2279:2;2267:9;2258:7;2254:23;2250:32;2247:52;;;2295:1;2292;2285:12;2247:52;-1:-1:-1;2318:23:11;;2167:180;-1:-1:-1;2167:180:11:o;2578:315::-;2646:6;2654;2707:2;2695:9;2686:7;2682:23;2678:32;2675:52;;;2723:1;2720;2713:12;2675:52;2762:9;2749:23;2781:31;2806:5;2781:31;:::i;:::-;2831:5;2883:2;2868:18;;;;2855:32;;-1:-1:-1;;;2578:315:11:o;3106:277::-;3173:6;3226:2;3214:9;3205:7;3201:23;3197:32;3194:52;;;3242:1;3239;3232:12;3194:52;3274:9;3268:16;3327:5;3320:13;3313:21;3306:5;3303:32;3293:60;;3349:1;3346;3339:12;3738:397;3940:2;3922:21;;;3979:2;3959:18;;;3952:30;4018:34;4013:2;3998:18;;3991:62;-1:-1:-1;;;4084:2:11;4069:18;;4062:31;4125:3;4110:19;;3738:397::o;4419:734::-;-1:-1:-1;;;;;4726:15:11;;;4708:34;;4778:15;;4773:2;4758:18;;4751:43;4825:2;4810:18;;4803:34;;;4868:2;4853:18;;4846:34;;;4688:3;4911;4896:19;;4889:32;;;4937:19;;4930:35;;;4651:4;4958:6;5008;5002:3;4987:19;;4974:49;5073:1;5067:3;5058:6;5047:9;5043:22;5039:32;5032:43;5143:3;5136:2;5132:7;5127:2;5119:6;5115:15;5111:29;5100:9;5096:45;5092:55;5084:63;;4419:734;;;;;;;;;:::o;5158:184::-;5228:6;5281:2;5269:9;5260:7;5256:23;5252:32;5249:52;;;5297:1;5294;5287:12;5249:52;-1:-1:-1;5320:16:11;;5158:184;-1:-1:-1;5158:184:11:o;5704:127::-;5765:10;5760:3;5756:20;5753:1;5746:31;5796:4;5793:1;5786:15;5820:4;5817:1;5810:15;5836:128;5876:3;5907:1;5903:6;5900:1;5897:13;5894:39;;;5913:18;;:::i;:::-;-1:-1:-1;5949:9:11;;5836:128::o;6349:245::-;6428:6;6436;6489:2;6477:9;6468:7;6464:23;6460:32;6457:52;;;6505:1;6502;6495:12;6457:52;-1:-1:-1;;6528:16:11;;6584:2;6569:18;;;6563:25;6528:16;;6563:25;;-1:-1:-1;6349:245:11:o;6599:125::-;6639:4;6667:1;6664;6661:8;6658:34;;;6672:18;;:::i;:::-;-1:-1:-1;6709:9:11;;6599:125::o

Swarm Source

ipfs://71a1bf6462aead685e4e7772090adf4cc0ad8a81aa80bf51490562cc34816939

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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.