ETH Price: $2,026.42 (-0.99%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
OracleSwapFreezer

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
london EvmVersion
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
import {IPriceOracle} from '@aave/core-v3/contracts/interfaces/IPriceOracle.sol';
import {AutomationCompatibleInterface} from '../dependencies/chainlink/AutomationCompatibleInterface.sol';
import {IGsm} from '../interfaces/IGsm.sol';

/**
 * @title OracleSwapFreezer
 * @author Aave
 * @notice Swap freezer that enacts the freeze action based on underlying oracle price, GSM's state and predefined price boundaries
 * @dev Chainlink Automation-compatible contract using Aave V3 Price Oracle, where prices are USD denominated with 8-decimal precision
 * @dev Freeze action is executable if GSM is not seized, not frozen and price is outside of the freeze bounds
 * @dev Unfreeze action is executable if GSM is not seized, frozen, unfreezing is allowed and price is inside the unfreeze bounds
 */
contract OracleSwapFreezer is AutomationCompatibleInterface {
  enum Action {
    NONE,
    FREEZE,
    UNFREEZE
  }

  IGsm public immutable GSM;
  address public immutable UNDERLYING_ASSET;
  IPoolAddressesProvider public immutable ADDRESS_PROVIDER;
  uint128 internal immutable _freezeLowerBound;
  uint128 internal immutable _freezeUpperBound;
  uint128 internal immutable _unfreezeLowerBound;
  uint128 internal immutable _unfreezeUpperBound;
  bool internal immutable _allowUnfreeze;

  /**
   * @dev Constructor
   * @dev Freeze/unfreeze bounds are specified in USD with 8-decimal precision, like Aave v3 Price Oracles
   * @dev Unfreeze boundaries are "contained" in freeze boundaries, where freezeLowerBound < unfreezeLowerBound and unfreezeUpperBound < freezeUpperBound
   * @dev All bound ranges are inclusive
   * @param gsm The GSM that this contract will trigger freezes/unfreezes on
   * @param underlyingAsset The address of the collateral asset
   * @param addressProvider The Aave Addresses Provider for looking up the Price Oracle
   * @param freezeLowerBound The lower price bound for freeze operations
   * @param freezeUpperBound The upper price bound for freeze operations
   * @param unfreezeLowerBound The lower price bound for unfreeze operations, must be 0 if unfreezing not allowed
   * @param unfreezeUpperBound The upper price bound for unfreeze operations, must be 0 if unfreezing not allowed
   * @param allowUnfreeze True if bounds verification should factor in the unfreeze boundary, false otherwise
   */
  constructor(
    IGsm gsm,
    address underlyingAsset,
    IPoolAddressesProvider addressProvider,
    uint128 freezeLowerBound,
    uint128 freezeUpperBound,
    uint128 unfreezeLowerBound,
    uint128 unfreezeUpperBound,
    bool allowUnfreeze
  ) {
    require(gsm.UNDERLYING_ASSET() == underlyingAsset, 'UNDERLYING_ASSET_MISMATCH');
    require(
      _validateBounds(
        freezeLowerBound,
        freezeUpperBound,
        unfreezeLowerBound,
        unfreezeUpperBound,
        allowUnfreeze
      ),
      'BOUNDS_NOT_VALID'
    );
    GSM = gsm;
    UNDERLYING_ASSET = underlyingAsset;
    ADDRESS_PROVIDER = addressProvider;
    _freezeLowerBound = freezeLowerBound;
    _freezeUpperBound = freezeUpperBound;
    _unfreezeLowerBound = unfreezeLowerBound;
    _unfreezeUpperBound = unfreezeUpperBound;
    _allowUnfreeze = allowUnfreeze;
  }

  /// @inheritdoc AutomationCompatibleInterface
  function performUpkeep(bytes calldata) external {
    Action action = _getAction();
    if (action == Action.FREEZE) {
      GSM.setSwapFreeze(true);
    } else if (action == Action.UNFREEZE) {
      GSM.setSwapFreeze(false);
    }
  }

  /// @inheritdoc AutomationCompatibleInterface
  function checkUpkeep(bytes calldata) external view returns (bool, bytes memory) {
    return (_getAction() == Action.NONE ? false : true, '');
  }

  /**
   * @notice Returns whether or not the swap freezer can unfreeze a GSM
   * @return True if the freezer can unfreeze, false otherwise
   */
  function getCanUnfreeze() external view returns (bool) {
    return _allowUnfreeze;
  }

  /**
   * @notice Returns the bound used for freeze operations
   * @return The freeze lower bound (inclusive)
   * @return The freeze upper bound (inclusive)
   */
  function getFreezeBound() external view returns (uint128, uint128) {
    return (_freezeLowerBound, _freezeUpperBound);
  }

  /**
   * @notice Returns the bound used for unfreeze operations, or (0, 0) if unfreezing not allowed
   * @return The unfreeze lower bound (inclusive), or 0 if unfreezing not allowed
   * @return The unfreeze upper bound (inclusive), or 0 if unfreezing not allowed
   */
  function getUnfreezeBound() external view returns (uint128, uint128) {
    return (_unfreezeLowerBound, _unfreezeUpperBound);
  }

  /**
   * @notice Fetches price oracle data and checks whether a swap freeze or unfreeze action is required
   * @return The action to take (none, freeze, or unfreeze)
   */
  function _getAction() internal view returns (Action) {
    if (GSM.hasRole(GSM.SWAP_FREEZER_ROLE(), address(this))) {
      if (GSM.getIsSeized()) {
        return Action.NONE;
      } else if (!GSM.getIsFrozen()) {
        if (_isActionAllowed(Action.FREEZE)) {
          return Action.FREEZE;
        }
      } else if (_allowUnfreeze) {
        if (_isActionAllowed(Action.UNFREEZE)) {
          return Action.UNFREEZE;
        }
      }
    }
    return Action.NONE;
  }

  /**
   * @notice Checks whether the action is allowed, based on the action, oracle price and freeze/unfreeze bounds
   * @dev Freeze action is allowed if price is outside of the freeze bounds
   * @dev Unfreeze action is allowed if price is inside the unfreeze bounds
   * @param actionToExecute The requested action type to validate
   * @return True if conditions to execute the action passed are met, false otherwise
   */
  function _isActionAllowed(Action actionToExecute) internal view returns (bool) {
    uint256 oraclePrice = IPriceOracle(ADDRESS_PROVIDER.getPriceOracle()).getAssetPrice(
      UNDERLYING_ASSET
    );
    // Assume a 0 oracle price is invalid and no action should be taken based on that data
    if (oraclePrice == 0) {
      return false;
    } else if (actionToExecute == Action.FREEZE) {
      if (oraclePrice <= _freezeLowerBound || oraclePrice >= _freezeUpperBound) {
        return true;
      }
    } else if (actionToExecute == Action.UNFREEZE) {
      if (oraclePrice >= _unfreezeLowerBound && oraclePrice <= _unfreezeUpperBound) {
        return true;
      }
    }
    return false;
  }

  /**
   * @notice Verifies that the unfreeze bound and freeze bounds do not conflict, causing unexpected behaviour
   * @param freezeLowerBound The lower bound for freeze operations
   * @param freezeUpperBound The upper bound for freeze operations
   * @param unfreezeLowerBound The lower bound for unfreeze operations, must be 0 if unfreezing not allowed
   * @param unfreezeUpperBound The upper bound for unfreeze operations, must be 0 if unfreezing not allowed
   * @param allowUnfreeze True if bounds verification should factor in the unfreeze boundary, false otherwise
   * @return True if the bounds are valid and conflict-free, false otherwise
   */
  function _validateBounds(
    uint128 freezeLowerBound,
    uint128 freezeUpperBound,
    uint128 unfreezeLowerBound,
    uint128 unfreezeUpperBound,
    bool allowUnfreeze
  ) internal pure returns (bool) {
    if (freezeLowerBound >= freezeUpperBound) {
      return false;
    } else if (allowUnfreeze) {
      if (
        unfreezeLowerBound >= unfreezeUpperBound ||
        freezeLowerBound >= unfreezeLowerBound ||
        freezeUpperBound <= unfreezeUpperBound
      ) {
        return false;
      }
    } else {
      if (unfreezeLowerBound != 0 || unfreezeUpperBound != 0) {
        return false;
      }
    }
    return true;
  }
}

// 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;
}

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;

/**
 * @title IPriceOracle
 * @author Aave
 * @notice Defines the basic interface for a Price oracle.
 */
interface IPriceOracle {
  /**
   * @notice Returns the asset price in the base currency
   * @param asset The address of the asset
   * @return The price of the asset
   */
  function getAssetPrice(address asset) external view returns (uint256);

  /**
   * @notice Set the price of the asset
   * @param asset The address of the asset
   * @param price The price of the asset
   */
  function setAssetPrice(address asset, uint256 price) external;
}

// SPDX-License-Identifier: MIT
// Chainlink Contracts v0.8
pragma solidity ^0.8.0;

interface AutomationCompatibleInterface {
  /**
   * @notice method that is simulated by the keepers to see if any work actually
   * needs to be performed. This method does does not actually need to be
   * executable, and since it is only ever simulated it can consume lots of gas.
   * @dev To ensure that it is never called, you may want to add the
   * cannotExecute modifier from KeeperBase to your implementation of this
   * method.
   * @param checkData specified in the upkeep registration so it is always the
   * same for a registered upkeep. This can easily be broken down into specific
   * arguments using `abi.decode`, so multiple upkeeps can be registered on the
   * same contract and easily differentiated by the contract.
   * @return upkeepNeeded boolean to indicate whether the keeper should call
   * performUpkeep or not.
   * @return performData bytes that the keeper should call performUpkeep with, if
   * upkeep is needed. If you would like to encode data to decode later, try
   * `abi.encode`.
   */
  function checkUpkeep(
    bytes calldata checkData
  ) external returns (bool upkeepNeeded, bytes memory performData);

  /**
   * @notice method that is actually executed by the keepers, via the registry.
   * The data returned by the checkUpkeep simulation will be passed into
   * this method to actually be executed.
   * @dev The input to this method should not be trusted, and the caller of the
   * method should not even be restricted to any single registry. Anyone should
   * be able call it, and the input should be validated, there is no guarantee
   * that the data passed in is the performData returned from checkUpkeep. This
   * could happen due to malicious keepers, racing keepers, or simply a state
   * change while the performUpkeep transaction is waiting for confirmation.
   * Always validate the data passed in.
   * @param performData is the data which was passed back from the checkData
   * simulation. If it is encoded, it can easily be decoded into other types by
   * calling `abi.decode`. This data should not be trusted, and should be
   * validated against the contract's current state.
   */
  function performUpkeep(bytes calldata performData) external;
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IAccessControl} from '@openzeppelin/contracts/access/IAccessControl.sol';
import {IGhoFacilitator} from '../../../gho/interfaces/IGhoFacilitator.sol';

/**
 * @title IGsm
 * @author Aave
 * @notice Defines the behaviour of a GHO Stability Module
 */
interface IGsm is IAccessControl, IGhoFacilitator {
  /**
   * @dev Emitted when a user buys an asset (selling GHO) in the GSM
   * @param originator The address of the buyer originating the request
   * @param receiver The address of the receiver of the underlying asset
   * @param underlyingAmount The amount of the underlying asset bought
   * @param ghoAmount The amount of GHO sold, inclusive of fee
   * @param fee The fee paid by the buyer, in GHO
   */
  event BuyAsset(
    address indexed originator,
    address indexed receiver,
    uint256 underlyingAmount,
    uint256 ghoAmount,
    uint256 fee
  );

  /**
   * @dev Emitted when a user sells an asset (buying GHO) in the GSM
   * @param originator The address of the seller originating the request
   * @param receiver The address of the receiver of GHO
   * @param underlyingAmount The amount of the underlying asset sold
   * @param ghoAmount The amount of GHO bought, inclusive of fee
   * @param fee The fee paid by the buyer, in GHO
   */
  event SellAsset(
    address indexed originator,
    address indexed receiver,
    uint256 underlyingAmount,
    uint256 ghoAmount,
    uint256 fee
  );

  /**
   * @dev Emitted when the Swap Freezer freezes buys/sells
   * @param freezer The address of the Swap Freezer
   * @param enabled True if swap functions are frozen, False otherwise
   */
  event SwapFreeze(address indexed freezer, bool enabled);

  /**
   * @dev Emitted when a Liquidator seizes GSM funds
   * @param seizer The address originating the seizure request
   * @param recipient The address of the recipient of seized funds
   * @param underlyingAmount The amount of the underlying asset seized
   * @param ghoOutstanding The amount of remaining GHO that the GSM had minted
   */
  event Seized(
    address indexed seizer,
    address indexed recipient,
    uint256 underlyingAmount,
    uint256 ghoOutstanding
  );

  /**
   * @dev Emitted when burning GHO after a seizure of GSM funds
   * @param burner The address of the burner
   * @param amount The amount of GHO burned
   * @param ghoOutstanding The amount of remaining GHO that the GSM had minted
   */
  event BurnAfterSeize(address indexed burner, uint256 amount, uint256 ghoOutstanding);

  /**
   * @dev Emitted when the Fee Strategy is updated
   * @param oldFeeStrategy The address of the old Fee Strategy
   * @param newFeeStrategy The address of the new Fee Strategy
   */
  event FeeStrategyUpdated(address indexed oldFeeStrategy, address indexed newFeeStrategy);

  /**
   * @dev Emitted when the GSM underlying asset Exposure Cap is updated
   * @param oldExposureCap The amount of the old Exposure Cap
   * @param newExposureCap The amount of the new Exposure Cap
   */
  event ExposureCapUpdated(uint256 oldExposureCap, uint256 newExposureCap);

  /**
   * @dev Emitted when tokens are rescued from the GSM
   * @param tokenRescued The address of the rescued token
   * @param recipient The address that received the rescued tokens
   * @param amountRescued The amount of token rescued
   */
  event TokensRescued(
    address indexed tokenRescued,
    address indexed recipient,
    uint256 amountRescued
  );

  /**
   * @notice Buys the GSM underlying asset in exchange for selling GHO
   * @dev Use `getAssetAmountForBuyAsset` function to calculate the amount based on the GHO amount to sell
   * @param minAmount The minimum amount of the underlying asset to buy
   * @param receiver Recipient address of the underlying asset being purchased
   * @return The amount of underlying asset bought
   * @return The amount of GHO sold by the user
   */
  function buyAsset(uint256 minAmount, address receiver) external returns (uint256, uint256);

  /**
   * @notice Buys the GSM underlying asset in exchange for selling GHO, using an EIP-712 signature
   * @dev Use `getAssetAmountForBuyAsset` function to calculate the amount based on the GHO amount to sell
   * @param originator The signer of the request
   * @param minAmount The minimum amount of the underlying asset to buy
   * @param receiver Recipient address of the underlying asset being purchased
   * @param deadline Signature expiration deadline
   * @param signature Signature data
   * @return The amount of underlying asset bought
   * @return The amount of GHO sold by the user
   */
  function buyAssetWithSig(
    address originator,
    uint256 minAmount,
    address receiver,
    uint256 deadline,
    bytes calldata signature
  ) external returns (uint256, uint256);

  /**
   * @notice Sells the GSM underlying asset in exchange for buying GHO
   * @dev Use `getAssetAmountForSellAsset` function to calculate the amount based on the GHO amount to buy
   * @param maxAmount The maximum amount of the underlying asset to sell
   * @param receiver Recipient address of the GHO being purchased
   * @return The amount of underlying asset sold
   * @return The amount of GHO bought by the user
   */
  function sellAsset(uint256 maxAmount, address receiver) external returns (uint256, uint256);

  /**
   * @notice Sells the GSM underlying asset in exchange for buying GHO, using an EIP-712 signature
   * @dev Use `getAssetAmountForSellAsset` function to calculate the amount based on the GHO amount to buy
   * @param originator The signer of the request
   * @param maxAmount The maximum amount of the underlying asset to sell
   * @param receiver Recipient address of the GHO being purchased
   * @param deadline Signature expiration deadline
   * @param signature Signature data
   * @return The amount of underlying asset sold
   * @return The amount of GHO bought by the user
   */
  function sellAssetWithSig(
    address originator,
    uint256 maxAmount,
    address receiver,
    uint256 deadline,
    bytes calldata signature
  ) external returns (uint256, uint256);

  /**
   * @notice Rescue and transfer tokens locked in this contract
   * @param token The address of the token
   * @param to The address of the recipient
   * @param amount The amount of token to transfer
   */
  function rescueTokens(address token, address to, uint256 amount) external;

  /**
   * @notice Enable or disable the swap freeze
   * @param enable True to freeze swap functions, false otherwise
   */
  function setSwapFreeze(bool enable) external;

  /**
   * @notice Seizes all of the underlying asset from the GSM, sending to the Treasury
   * @dev Seizing is a last resort mechanism to provide the Treasury with the entire amount of underlying asset
   * so it can be used to backstop any potential event impacting the functionality of the Gsm.
   * @dev Seizing disables the swap feature
   * @return The amount of underlying asset seized and transferred to Treasury
   */
  function seize() external returns (uint256);

  /**
   * @notice Burns an amount of GHO after seizure reducing the facilitator bucket level effectively
   * @dev Passing an amount higher than the facilitator bucket level will result in burning all minted GHO
   * @dev Only callable if the GSM has assets seized, helpful to wind down the facilitator
   * @param amount The amount of GHO to burn
   * @return The amount of GHO burned
   */
  function burnAfterSeize(uint256 amount) external returns (uint256);

  /**
   * @notice Updates the address of the Fee Strategy
   * @param feeStrategy The address of the new FeeStrategy
   */
  function updateFeeStrategy(address feeStrategy) external;

  /**
   * @notice Updates the exposure cap of the underlying asset
   * @param exposureCap The new value for the exposure cap (in underlying asset terms)
   */
  function updateExposureCap(uint128 exposureCap) external;

  /**
   * @notice Returns the EIP712 domain separator
   * @return The EIP712 domain separator
   */
  function DOMAIN_SEPARATOR() external view returns (bytes32);

  /**
   * @notice Returns the total amount of GHO, gross amount and fee result of buying assets
   * @param minAssetAmount The minimum amount of underlying asset to buy
   * @return The exact amount of underlying asset to be bought
   * @return The total amount of GHO the user sells (gross amount in GHO plus fee)
   * @return The gross amount of GHO
   * @return The fee amount in GHO, applied on top of gross amount of GHO
   */
  function getGhoAmountForBuyAsset(
    uint256 minAssetAmount
  ) external view returns (uint256, uint256, uint256, uint256);

  /**
   * @notice Returns the total amount of GHO, gross amount and fee result of selling assets
   * @param maxAssetAmount The maximum amount of underlying asset to sell
   * @return The exact amount of underlying asset to sell
   * @return The total amount of GHO the user buys (gross amount in GHO minus fee)
   * @return The gross amount of GHO
   * @return The fee amount in GHO, applied to the gross amount of GHO
   */
  function getGhoAmountForSellAsset(
    uint256 maxAssetAmount
  ) external view returns (uint256, uint256, uint256, uint256);

  /**
   * @notice Returns the amount of underlying asset, gross amount of GHO and fee result of buying assets
   * @param maxGhoAmount The maximum amount of GHO the user provides for buying underlying asset
   * @return The amount of underlying asset the user buys
   * @return The exact amount of GHO the user provides
   * @return The gross amount of GHO corresponding to the given total amount of GHO
   * @return The fee amount in GHO, charged for buying assets
   */
  function getAssetAmountForBuyAsset(
    uint256 maxGhoAmount
  ) external view returns (uint256, uint256, uint256, uint256);

  /**
   * @notice Returns the amount of underlying asset, gross amount of GHO and fee result of selling assets
   * @param minGhoAmount The minimum amount of GHO the user must receive for selling underlying asset
   * @return The amount of underlying asset the user sells
   * @return The exact amount of GHO the user receives in exchange
   * @return The gross amount of GHO corresponding to the given total amount of GHO
   * @return The fee amount in GHO, charged for selling assets
   */
  function getAssetAmountForSellAsset(
    uint256 minGhoAmount
  ) external view returns (uint256, uint256, uint256, uint256);

  /**
   * @notice Returns the remaining GSM exposure capacity
   * @return The amount of underlying asset that can be sold to the GSM
   */
  function getAvailableUnderlyingExposure() external view returns (uint256);

  /**
   * @notice Returns the exposure limit to the underlying asset
   * @return The maximum amount of underlying asset that can be sold to the GSM
   */
  function getExposureCap() external view returns (uint128);

  /**
   * @notice Returns the actual underlying asset balance immediately available in the GSM
   * @return The amount of underlying asset that can be bought from the GSM
   */
  function getAvailableLiquidity() external view returns (uint256);

  /**
   * @notice Returns the Fee Strategy for the GSM
   * @dev It returns 0x0 in case of no fee strategy
   * @return The address of the FeeStrategy
   */
  function getFeeStrategy() external view returns (address);

  /**
   * @notice Returns the amount of current accrued fees
   * @dev It does not factor in potential fees that can be accrued upon distribution of fees
   * @return The amount of accrued fees
   */
  function getAccruedFees() external view returns (uint256);

  /**
   * @notice Returns the freeze status of the GSM
   * @return True if frozen, false if not
   */
  function getIsFrozen() external view returns (bool);

  /**
   * @notice Returns the current seizure status of the GSM
   * @return True if the GSM has been seized, false if not
   */
  function getIsSeized() external view returns (bool);

  /**
   * @notice Returns whether or not swaps via buyAsset/sellAsset are currently possible
   * @return True if the GSM has swapping enabled, false otherwise
   */
  function canSwap() external view returns (bool);

  /**
   * @notice Returns the GSM revision number
   * @return The revision number
   */
  function GSM_REVISION() external pure returns (uint256);

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

  /**
   * @notice Returns the underlying asset of the GSM
   * @return The address of the underlying asset
   */
  function UNDERLYING_ASSET() external view returns (address);

  /**
   * @notice Returns the price strategy of the GSM
   * @return The address of the price strategy
   */
  function PRICE_STRATEGY() external view returns (address);

  /**
   * @notice Returns the current nonce (for EIP-712 signature methods) of an address
   * @param user The address of the user
   * @return The current nonce of the user
   */
  function nonces(address user) external view returns (uint256);

  /**
   * @notice Returns the identifier of the Configurator Role
   * @return The bytes32 id hash of the Configurator role
   */
  function CONFIGURATOR_ROLE() external pure returns (bytes32);

  /**
   * @notice Returns the identifier of the Token Rescuer Role
   * @return The bytes32 id hash of the TokenRescuer role
   */
  function TOKEN_RESCUER_ROLE() external pure returns (bytes32);

  /**
   * @notice Returns the identifier of the Swap Freezer Role
   * @return The bytes32 id hash of the SwapFreezer role
   */
  function SWAP_FREEZER_ROLE() external pure returns (bytes32);

  /**
   * @notice Returns the identifier of the Liquidator Role
   * @return The bytes32 id hash of the Liquidator role
   */
  function LIQUIDATOR_ROLE() external pure returns (bytes32);

  /**
   * @notice Returns the EIP-712 signature typehash for buyAssetWithSig
   * @return The bytes32 signature typehash for buyAssetWithSig
   */
  function BUY_ASSET_WITH_SIG_TYPEHASH() external pure returns (bytes32);

  /**
   * @notice Returns the EIP-712 signature typehash for sellAssetWithSig
   * @return The bytes32 signature typehash for sellAssetWithSig
   */
  function SELL_ASSET_WITH_SIG_TYPEHASH() external pure returns (bytes32);
}

// 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;
}

// 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);
}

Settings
{
  "remappings": [
    "@aave/core-v3/=lib/aave-v3-core/",
    "@aave/periphery-v3/=lib/aave-v3-periphery/",
    "@aave/=lib/aave-token/",
    "@openzeppelin/=lib/openzeppelin-contracts/",
    "aave-stk-v1-5/=lib/aave-stk-v1-5/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "eth-gas-reporter/=node_modules/eth-gas-reporter/",
    "forge-std/=lib/forge-std/src/",
    "hardhat-deploy/=node_modules/hardhat-deploy/",
    "hardhat/=node_modules/hardhat/",
    "aave-address-book/=lib/aave-address-book/src/",
    "aave-helpers/=lib/aave-stk-v1-5/lib/aave-helpers/",
    "aave-v3-core/=lib/aave-address-book/lib/aave-v3-core/",
    "aave-v3-periphery/=lib/aave-address-book/lib/aave-v3-periphery/",
    "erc4626-tests/=lib/aave-stk-v1-5/lib/openzeppelin-contracts/lib/erc4626-tests/",
    "openzeppelin-contracts/=lib/aave-stk-v1-5/lib/openzeppelin-contracts/",
    "solidity-utils/=lib/solidity-utils/src/",
    "aave-token/=lib/aave-token/contracts/",
    "safety-module/=lib/safety-module/contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"contract IGsm","name":"gsm","type":"address"},{"internalType":"address","name":"underlyingAsset","type":"address"},{"internalType":"contract IPoolAddressesProvider","name":"addressProvider","type":"address"},{"internalType":"uint128","name":"freezeLowerBound","type":"uint128"},{"internalType":"uint128","name":"freezeUpperBound","type":"uint128"},{"internalType":"uint128","name":"unfreezeLowerBound","type":"uint128"},{"internalType":"uint128","name":"unfreezeUpperBound","type":"uint128"},{"internalType":"bool","name":"allowUnfreeze","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ADDRESS_PROVIDER","outputs":[{"internalType":"contract IPoolAddressesProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GSM","outputs":[{"internalType":"contract IGsm","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNDERLYING_ASSET","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCanUnfreeze","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFreezeBound","outputs":[{"internalType":"uint128","name":"","type":"uint128"},{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnfreezeBound","outputs":[{"internalType":"uint128","name":"","type":"uint128"},{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"performUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101806040523480156200001257600080fd5b5060405162000e2e38038062000e2e83398101604081905262000035916200029e565b866001600160a01b0316886001600160a01b031663e60253936040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200007e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000a4919062000356565b6001600160a01b031614620001005760405162461bcd60e51b815260206004820152601960248201527f554e4445524c59494e475f41535345545f4d49534d415443480000000000000060448201526064015b60405180910390fd5b6200010f858585858562000199565b620001505760405162461bcd60e51b815260206004820152601060248201526f1093d5539114d7d393d517d59053125160821b6044820152606401620000f7565b6001600160a01b0397881660805295871660a0529390951660c0526001600160801b0391821660e05281166101005292831661012052909116610140521515610160526200037d565b6000846001600160801b0316866001600160801b031610620001be575060006200025f565b81156200022c57826001600160801b0316846001600160801b0316101580620001f95750836001600160801b0316866001600160801b031610155b80620002175750826001600160801b0316856001600160801b031611155b1562000226575060006200025f565b6200025b565b6001600160801b0384161515806200024c57506001600160801b03831615155b156200025b575060006200025f565b5060015b95945050505050565b6001600160a01b03811681146200027e57600080fd5b50565b80516001600160801b03811681146200029957600080fd5b919050565b600080600080600080600080610100898b031215620002bc57600080fd5b8851620002c98162000268565b60208a0151909850620002dc8162000268565b60408a0151909750620002ef8162000268565b9550620002ff60608a0162000281565b94506200030f60808a0162000281565b93506200031f60a08a0162000281565b92506200032f60c08a0162000281565b915060e089015180151581146200034557600080fd5b809150509295985092959890939650565b6000602082840312156200036957600080fd5b8151620003768162000268565b9392505050565b60805160a05160c05160e051610100516101205161014051610160516109f36200043b6000396000818161016f01526105ea0152600081816101bd015261082801526000818161019c01526107f401526000818160f4015261079901526000818160d301526107660152600081816092015261062e01526000818161020d01526106c50152600081816101e60152818161026b01528181610304015281816103a1015281816103d0015281816104bd015261054a01526109f36000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063778c276d1161005b578063778c276d1461016a578063b0dab50c1461019a578063b5c885e6146101e1578063e60253931461020857600080fd5b80631848effa1461008d5780633c0787ff146100d15780634585e33b146101345780636e04ff0d14610149575b600080fd5b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000005b604080516001600160801b039384168152929091166020830152016100c8565b61014761014236600461086b565b61022f565b005b61015c61015736600461086b565b610355565b6040516100c89291906108dd565b6040517f0000000000000000000000000000000000000000000000000000000000000000151581526020016100c8565b7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610114565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b600061023961039d565b9050600181600281111561024f5761024f61093c565b14156102d45760405163655a35e360e11b8152600160048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063cab46bc690602401600060405180830381600087803b1580156102b757600080fd5b505af11580156102cb573d6000803e3d6000fd5b50505050505050565b60028160028111156102e8576102e861093c565b14156103505760405163655a35e360e11b8152600060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063cab46bc690602401600060405180830381600087803b1580156102b757600080fd5b505050565b600060608161036261039d565b60028111156103735761037361093c565b1461037f576001610382565b60005b60405180602001604052806000815250915091509250929050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166391d148547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663353f03bd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561042c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104509190610952565b6040516001600160e01b031960e084901b1681526004810191909152306024820152604401602060405180830381865afa158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b6919061096b565b15610623577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166380bc659a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610519573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053d919061096b565b156105485750600090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663236fc8ad6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ca919061096b565b6105e8576105d86001610629565b156105e35750600190565b610623565b7f000000000000000000000000000000000000000000000000000000000000000015610623576106186002610629565b156106235750600290565b50600090565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663fca513a86040518163ffffffff1660e01b8152600401602060405180830381865afa15801561068a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ae9190610994565b60405163b3596f0760e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152919091169063b3596f0790602401602060405180830381865afa158015610716573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073a9190610952565b90508061074a5750600092915050565b600183600281111561075e5761075e61093c565b14156107d8577f00000000000000000000000000000000000000000000000000000000000000006001600160801b0316811115806107c557507f00000000000000000000000000000000000000000000000000000000000000006001600160801b03168110155b156107d35750600192915050565b610862565b60028360028111156107ec576107ec61093c565b1415610862577f00000000000000000000000000000000000000000000000000000000000000006001600160801b0316811015801561085457507f00000000000000000000000000000000000000000000000000000000000000006001600160801b03168111155b156108625750600192915050565b50600092915050565b6000806020838503121561087e57600080fd5b823567ffffffffffffffff8082111561089657600080fd5b818501915085601f8301126108aa57600080fd5b8135818111156108b957600080fd5b8660208285010111156108cb57600080fd5b60209290920196919550909350505050565b821515815260006020604081840152835180604085015260005b81811015610913578581018301518582016060015282016108f7565b81811115610925576000606083870101525b50601f01601f191692909201606001949350505050565b634e487b7160e01b600052602160045260246000fd5b60006020828403121561096457600080fd5b5051919050565b60006020828403121561097d57600080fd5b8151801515811461098d57600080fd5b9392505050565b6000602082840312156109a657600080fd5b81516001600160a01b038116811461098d57600080fdfea26469706673582212206a72582fabb60dc46b58c2ed08ad6a7ff78a399718f8c26b859b41ee50d0bafa64736f6c634300080a003300000000000000000000000044ad2faaa66ac9326101a8d12717374a55943fe100000000000000000000000073eddfa87c71addc275c2b9890f5c3a8480bc9e60000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e0000000000000000000000000000000000000000000000000000000005e69ec000000000000000000000000000000000000000000000000000000000060523400000000000000000000000000000000000000000000000000000000005ee3fe00000000000000000000000000000000000000000000000000000000005fd82200000000000000000000000000000000000000000000000000000000000000001

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063778c276d1161005b578063778c276d1461016a578063b0dab50c1461019a578063b5c885e6146101e1578063e60253931461020857600080fd5b80631848effa1461008d5780633c0787ff146100d15780634585e33b146101345780636e04ff0d14610149575b600080fd5b6100b47f0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e81565b6040516001600160a01b0390911681526020015b60405180910390f35b7f0000000000000000000000000000000000000000000000000000000005e69ec07f00000000000000000000000000000000000000000000000000000000060523405b604080516001600160801b039384168152929091166020830152016100c8565b61014761014236600461086b565b61022f565b005b61015c61015736600461086b565b610355565b6040516100c89291906108dd565b6040517f0000000000000000000000000000000000000000000000000000000000000001151581526020016100c8565b7f0000000000000000000000000000000000000000000000000000000005ee3fe07f0000000000000000000000000000000000000000000000000000000005fd8220610114565b6100b47f00000000000000000000000044ad2faaa66ac9326101a8d12717374a55943fe181565b6100b47f00000000000000000000000073eddfa87c71addc275c2b9890f5c3a8480bc9e681565b600061023961039d565b9050600181600281111561024f5761024f61093c565b14156102d45760405163655a35e360e11b8152600160048201527f00000000000000000000000044ad2faaa66ac9326101a8d12717374a55943fe16001600160a01b03169063cab46bc690602401600060405180830381600087803b1580156102b757600080fd5b505af11580156102cb573d6000803e3d6000fd5b50505050505050565b60028160028111156102e8576102e861093c565b14156103505760405163655a35e360e11b8152600060048201527f00000000000000000000000044ad2faaa66ac9326101a8d12717374a55943fe16001600160a01b03169063cab46bc690602401600060405180830381600087803b1580156102b757600080fd5b505050565b600060608161036261039d565b60028111156103735761037361093c565b1461037f576001610382565b60005b60405180602001604052806000815250915091509250929050565b60007f00000000000000000000000044ad2faaa66ac9326101a8d12717374a55943fe16001600160a01b03166391d148547f00000000000000000000000044ad2faaa66ac9326101a8d12717374a55943fe16001600160a01b031663353f03bd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561042c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104509190610952565b6040516001600160e01b031960e084901b1681526004810191909152306024820152604401602060405180830381865afa158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b6919061096b565b15610623577f00000000000000000000000044ad2faaa66ac9326101a8d12717374a55943fe16001600160a01b03166380bc659a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610519573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053d919061096b565b156105485750600090565b7f00000000000000000000000044ad2faaa66ac9326101a8d12717374a55943fe16001600160a01b031663236fc8ad6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ca919061096b565b6105e8576105d86001610629565b156105e35750600190565b610623565b7f000000000000000000000000000000000000000000000000000000000000000115610623576106186002610629565b156106235750600290565b50600090565b6000807f0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e6001600160a01b031663fca513a86040518163ffffffff1660e01b8152600401602060405180830381865afa15801561068a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ae9190610994565b60405163b3596f0760e01b81526001600160a01b037f00000000000000000000000073eddfa87c71addc275c2b9890f5c3a8480bc9e681166004830152919091169063b3596f0790602401602060405180830381865afa158015610716573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073a9190610952565b90508061074a5750600092915050565b600183600281111561075e5761075e61093c565b14156107d8577f0000000000000000000000000000000000000000000000000000000005e69ec06001600160801b0316811115806107c557507f00000000000000000000000000000000000000000000000000000000060523406001600160801b03168110155b156107d35750600192915050565b610862565b60028360028111156107ec576107ec61093c565b1415610862577f0000000000000000000000000000000000000000000000000000000005ee3fe06001600160801b0316811015801561085457507f0000000000000000000000000000000000000000000000000000000005fd82206001600160801b03168111155b156108625750600192915050565b50600092915050565b6000806020838503121561087e57600080fd5b823567ffffffffffffffff8082111561089657600080fd5b818501915085601f8301126108aa57600080fd5b8135818111156108b957600080fd5b8660208285010111156108cb57600080fd5b60209290920196919550909350505050565b821515815260006020604081840152835180604085015260005b81811015610913578581018301518582016060015282016108f7565b81811115610925576000606083870101525b50601f01601f191692909201606001949350505050565b634e487b7160e01b600052602160045260246000fd5b60006020828403121561096457600080fd5b5051919050565b60006020828403121561097d57600080fd5b8151801515811461098d57600080fd5b9392505050565b6000602082840312156109a657600080fd5b81516001600160a01b038116811461098d57600080fdfea26469706673582212206a72582fabb60dc46b58c2ed08ad6a7ff78a399718f8c26b859b41ee50d0bafa64736f6c634300080a0033

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

00000000000000000000000044ad2faaa66ac9326101a8d12717374a55943fe100000000000000000000000073eddfa87c71addc275c2b9890f5c3a8480bc9e60000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e0000000000000000000000000000000000000000000000000000000005e69ec000000000000000000000000000000000000000000000000000000000060523400000000000000000000000000000000000000000000000000000000005ee3fe00000000000000000000000000000000000000000000000000000000005fd82200000000000000000000000000000000000000000000000000000000000000001

-----Decoded View---------------
Arg [0] : gsm (address): 0x44aD2FaaA66aC9326101a8D12717374A55943Fe1
Arg [1] : underlyingAsset (address): 0x73edDFa87C71ADdC275c2b9890f5c3a8480bC9E6
Arg [2] : addressProvider (address): 0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e
Arg [3] : freezeLowerBound (uint128): 99000000
Arg [4] : freezeUpperBound (uint128): 101000000
Arg [5] : unfreezeLowerBound (uint128): 99500000
Arg [6] : unfreezeUpperBound (uint128): 100500000
Arg [7] : allowUnfreeze (bool): True

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 00000000000000000000000044ad2faaa66ac9326101a8d12717374a55943fe1
Arg [1] : 00000000000000000000000073eddfa87c71addc275c2b9890f5c3a8480bc9e6
Arg [2] : 0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e
Arg [3] : 0000000000000000000000000000000000000000000000000000000005e69ec0
Arg [4] : 0000000000000000000000000000000000000000000000000000000006052340
Arg [5] : 0000000000000000000000000000000000000000000000000000000005ee3fe0
Arg [6] : 0000000000000000000000000000000000000000000000000000000005fd8220
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000001


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

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