ETH Price: $1,975.73 (-4.76%)

Contract

0x174d5B055E32ad466C19C4d9aBD23D3D4db8e2d0
 

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:
StakeConfigurator

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import '../../dependencies/openzeppelin/contracts/IERC20.sol';
import '../../tools/upgradeability/VersionedInitializable.sol';
import '../../access/interfaces/IMarketAccessController.sol';
import '../../interfaces/IDerivedToken.sol';
import '../../interfaces/IDepositToken.sol';
import '../../access/MarketAccessBitmask.sol';
import '../../access/AccessFlags.sol';
import '../../tools/upgradeability/IProxy.sol';
import '../../tools/upgradeability/ProxyAdmin.sol';
import './interfaces/IStakeConfigurator.sol';
import './interfaces/IInitializableStakeToken.sol';
import './interfaces/StakeTokenConfig.sol';
import './interfaces/IManagedStakeToken.sol';

contract StakeConfigurator is MarketAccessBitmask, VersionedInitializable, IStakeConfigurator {
  uint256 private constant CONFIGURATOR_REVISION = 3;

  mapping(uint256 => address) private _entries;
  uint256 private _entryCount;
  mapping(address => uint256) private _underlyings;

  ProxyAdmin private _proxies;
  uint256 private _legacyCount;

  constructor() MarketAccessBitmask(IMarketAccessController(address(0))) {}

  function getRevision() internal pure virtual override returns (uint256) {
    return CONFIGURATOR_REVISION;
  }

  // This initializer is invoked by AccessController.setAddressAsImpl
  function initialize(address addressesProvider) external initializer(CONFIGURATOR_REVISION) {
    _remoteAcl = IMarketAccessController(addressesProvider);
    if (address(_proxies) == address(0)) {
      _proxies = new ProxyAdmin();
      _legacyCount = _entryCount;
    }
  }

  function getProxyAdmin() public view returns (address) {
    return address(_proxies);
  }

  function list() public view override returns (address[] memory tokens) {
    return _list(_legacyCount);
  }

  function listAll() public view override returns (address[] memory tokens, uint256 genCount) {
    return (_list(0), _legacyCount);
  }

  function _list(uint256 base) internal view returns (address[] memory tokens) {
    if (_entryCount <= base) {
      return tokens;
    }
    tokens = new address[](_entryCount - base);
    base++;
    for (uint256 i = 0; i < tokens.length; i++) {
      tokens[i] = _entries[i + base];
    }
    return tokens;
  }

  function stakeTokenOf(address underlying) public view override returns (address) {
    uint256 i = _underlyings[underlying];
    if (i == 0) {
      return address(0);
    }
    return _entries[i];
  }

  function dataOf(address stakeToken) public view override returns (StakeTokenData memory data) {
    (data.config, data.stkTokenName, data.stkTokenSymbol) = IInitializableStakeToken(stakeToken)
      .initializedStakeTokenWith();
    data.token = stakeToken;

    return data;
  }

  function addStakeToken(address token) public aclHas(AccessFlags.STAKE_ADMIN) {
    require(token != address(0), 'unknown token');
    _addStakeToken(token, IDerivedToken(token).UNDERLYING_ASSET_ADDRESS());
  }

  function removeStakeTokenByUnderlying(address underlying) public aclHas(AccessFlags.STAKE_ADMIN) returns (bool) {
    require(underlying != address(0), 'unknown underlying');
    return _removeStakeToken(_underlyings[underlying], underlying);
  }

  function removeStakeToken(uint256 index) public aclHas(AccessFlags.STAKE_ADMIN) returns (bool) {
    return _removeStakeToken(index + 1, address(0));
  }

  function removeUnderlyings(address[] calldata underlyings) public aclHas(AccessFlags.STAKE_ADMIN) {
    for (uint256 i = underlyings.length; i > 0; ) {
      i--;
      _underlyings[underlyings[i]] = 0;
    }
  }

  function _removeStakeToken(uint256 i, address underlying) private returns (bool) {
    if (i == 0 || _entries[i] == address(0)) {
      return false;
    }

    emit StakeTokenRemoved(_entries[i], underlying);

    delete (_entries[i]);
    if (underlying == address(0)) {
      delete (_underlyings[underlying]);
    }
    return true;
  }

  function _addStakeToken(address token, address underlying) private {
    require(token != address(0), 'unknown token');
    require(underlying != address(0), 'unknown underlying');
    require(stakeTokenOf(underlying) == address(0), 'ambiguous underlying');

    _entryCount++;
    _entries[_entryCount] = token;
    _underlyings[underlying] = _entryCount;

    emit StakeTokenAdded(token, underlying);
  }

  function batchInitStakeTokens(InitStakeTokenData[] memory input) public aclHas(AccessFlags.STAKE_ADMIN) {
    for (uint256 i = 0; i < input.length; i++) {
      initStakeToken(input[i]);
    }
  }

  function initStakeToken(InitStakeTokenData memory input) private returns (address token) {
    StakeTokenConfig memory config = StakeTokenConfig(
      _remoteAcl,
      IERC20(input.stakedToken),
      IUnderlyingStrategy(input.strategy),
      input.cooldownPeriod,
      input.unstakePeriod,
      input.maxSlashable,
      input.stkTokenDecimals
    );

    bytes memory params = abi.encodeWithSelector(
      IInitializableStakeToken.initializeStakeToken.selector,
      config,
      input.stkTokenName,
      input.stkTokenSymbol
    );

    token = address(_remoteAcl.createProxy(address(_proxies), input.stakeTokenImpl, params));
    if (input.depositStake) {
      IDepositToken(input.stakedToken).addStakeOperator(token);
    }

    emit StakeTokenInitialized(token, input);

    _addStakeToken(token, input.stakedToken);

    return token;
  }

  function implementationOf(address token) external view returns (address) {
    return _proxies.getProxyImplementation(IProxy(token));
  }

  function updateStakeToken(UpdateStakeTokenData calldata input) external aclHas(AccessFlags.STAKE_ADMIN) {
    StakeTokenData memory data = dataOf(input.token);

    bytes memory params = abi.encodeWithSelector(
      IInitializableStakeToken.initializeStakeToken.selector,
      data.config,
      input.stkTokenName,
      input.stkTokenSymbol
    );

    _proxies.upgradeAndCall(IProxy(input.token), input.stakeTokenImpl, params);

    emit StakeTokenUpgraded(input.token, input);
  }

  function setCooldownForAll(uint32 cooldownPeriod, uint32 unstakePeriod)
    external
    override
    aclHas(AccessFlags.STAKE_ADMIN)
  {
    for (uint256 i = 1; i <= _entryCount; i++) {
      IManagedStakeToken(_entries[i]).setCooldown(cooldownPeriod, unstakePeriod);
    }
  }
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

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

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

  /**
   * @dev Moves `amount` tokens from the caller's account to `recipient`.
   *
   * Returns a boolean value indicating whether the operation succeeded.
   */
  function transfer(address recipient, 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
   */
  function approve(address spender, uint256 amount) external returns (bool);

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

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

/**
 * @title VersionedInitializable
 *
 * @dev Helper contract to implement versioned initializer functions. To use it, replace
 * the constructor with a function that has the `initializer` or `initializerRunAlways` modifier.
 * The revision number should be defined as a private constant, returned by getRevision() and used by initializer() modifier.
 *
 * ATTN: There is a built-in protection from implementation self-destruct exploits. This protection
 * prevents initializers from being called on an implementation inself, but only on proxied contracts.
 * To override this protection, call _unsafeResetVersionedInitializers() from a constructor.
 *
 * WARNING: Unlike constructors, initializer functions must be manually
 * invoked. This applies both to deploying an initializable contract, as well
 * as extending an initializable contract via inheritance.
 *
 * ATTN: When used with inheritance, parent initializers with `initializer` modifier are prevented by calling twice,
 * but can only be called in child-to-parent sequence.
 *
 * WARNING: When used with inheritance, parent initializers with `initializerRunAlways` modifier
 * are NOT protected from multiple calls by another initializer.
 */
abstract contract VersionedInitializable {
  uint256 private constant BLOCK_REVISION = type(uint256).max;
  // This revision number is applied to implementations
  uint256 private constant IMPL_REVISION = BLOCK_REVISION - 1;

  /// @dev Indicates that the contract has been initialized. The default value blocks initializers from being called on an implementation.
  uint256 private lastInitializedRevision = IMPL_REVISION;

  /// @dev Indicates that the contract is in the process of being initialized.
  uint256 private lastInitializingRevision = 0;

  /**
   * @dev There is a built-in protection from self-destruct of implementation exploits. This protection
   * prevents initializers from being called on an implementation inself, but only on proxied contracts.
   * Function _unsafeResetVersionedInitializers() can be called from a constructor to disable this protection.
   * It must be called before any initializers, otherwise it will fail.
   */
  function _unsafeResetVersionedInitializers() internal {
    require(isConstructor(), 'only for constructor');

    if (lastInitializedRevision == IMPL_REVISION) {
      lastInitializedRevision = 0;
    } else {
      require(lastInitializedRevision == 0, 'can only be called before initializer(s)');
    }
  }

  /// @dev Modifier to use in the initializer function of a contract.
  modifier initializer(uint256 localRevision) {
    (uint256 topRevision, bool initializing, bool skip) = _preInitializer(localRevision);

    if (!skip) {
      lastInitializingRevision = localRevision;
      _;
      lastInitializedRevision = localRevision;
    }

    if (!initializing) {
      lastInitializedRevision = topRevision;
      lastInitializingRevision = 0;
    }
  }

  modifier initializerRunAlways(uint256 localRevision) {
    (uint256 topRevision, bool initializing, bool skip) = _preInitializer(localRevision);

    if (!skip) {
      lastInitializingRevision = localRevision;
    }
    _;
    if (!skip) {
      lastInitializedRevision = localRevision;
    }

    if (!initializing) {
      lastInitializedRevision = topRevision;
      lastInitializingRevision = 0;
    }
  }

  function _preInitializer(uint256 localRevision)
    private
    returns (
      uint256 topRevision,
      bool initializing,
      bool skip
    )
  {
    topRevision = getRevision();
    require(topRevision < IMPL_REVISION, 'invalid contract revision');

    require(localRevision > 0, 'incorrect initializer revision');
    require(localRevision <= topRevision, 'inconsistent contract revision');

    if (lastInitializedRevision < IMPL_REVISION) {
      // normal initialization
      initializing = lastInitializingRevision > 0 && lastInitializedRevision < topRevision;
      require(initializing || isConstructor() || topRevision > lastInitializedRevision, 'already initialized');
    } else {
      // by default, initialization of implementation is only allowed inside a constructor
      require(lastInitializedRevision == IMPL_REVISION && isConstructor(), 'initializer blocked');

      // enable normal use of initializers inside a constructor
      lastInitializedRevision = 0;
      // but make sure to block initializers afterwards
      topRevision = BLOCK_REVISION;

      initializing = lastInitializingRevision > 0;
    }

    if (initializing) {
      require(lastInitializingRevision > localRevision, 'incorrect order of initializers');
    }

    if (localRevision <= lastInitializedRevision) {
      // prevent calling of parent's initializer when it was called before
      if (initializing) {
        // Can't set zero yet, as it is not a top-level call, otherwise `initializing` will become false.
        // Further calls will fail with the `incorrect order` assertion above.
        lastInitializingRevision = 1;
      }
      return (topRevision, initializing, true);
    }
    return (topRevision, initializing, false);
  }

  function isRevisionInitialized(uint256 localRevision) internal view returns (bool) {
    return lastInitializedRevision >= localRevision;
  }

  // solhint-disable-next-line func-name-mixedcase
  function REVISION() public pure returns (uint256) {
    return getRevision();
  }

  /**
   * @dev returns the revision number (< type(uint256).max - 1) of the contract.
   * The number should be defined as a private constant.
   **/
  function getRevision() internal pure virtual returns (uint256);

  /// @dev Returns true if and only if the function is running in the constructor
  function isConstructor() private view returns (bool) {
    uint256 cs;
    // solhint-disable-next-line no-inline-assembly
    assembly {
      cs := extcodesize(address())
    }
    return cs == 0;
  }

  // Reserved storage space to allow for layout changes in the future.
  uint256[4] private ______gap;
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import './IAccessController.sol';

/// @dev Main registry of addresses part of or connected to the protocol, including permissioned roles. Also acts a proxy factory.
interface IMarketAccessController is IAccessController {
  function getMarketId() external view returns (string memory);

  function getLendingPool() external view returns (address);

  function getPriceOracle() external view returns (address);

  function getLendingRateOracle() external view returns (address);
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

// solhint-disable func-name-mixedcase
interface IDerivedToken {
  /**
   * @dev Returns the address of the underlying asset of this token (E.g. WETH for agWETH)
   **/
  function UNDERLYING_ASSET_ADDRESS() external view returns (address);
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import '../dependencies/openzeppelin/contracts/IERC20.sol';
import './IScaledBalanceToken.sol';
import './IPoolToken.sol';

interface IDepositToken is IERC20, IPoolToken, IScaledBalanceToken {
  /**
   * @dev Emitted on mint
   * @param account The receiver of minted tokens
   * @param value The amount minted
   * @param index The new liquidity index of the reserve
   **/
  event Mint(address indexed account, uint256 value, uint256 index);

  /**
   * @dev Mints `amount` depositTokens to `user`
   * @param user The address receiving the minted tokens
   * @param amount The amount of tokens getting minted
   * @param index The new liquidity index of the reserve
   * @param repayOverdraft Enables to use this amount cover an overdraft
   * @return `true` if the the previous balance of the user was 0
   */
  function mint(
    address user,
    uint256 amount,
    uint256 index,
    bool repayOverdraft
  ) external returns (bool);

  /**
   * @dev Emitted on burn
   * @param account The owner of tokens burned
   * @param target The receiver of the underlying
   * @param value The amount burned
   * @param index The new liquidity index of the reserve
   **/
  event Burn(address indexed account, address indexed target, uint256 value, uint256 index);

  /**
   * @dev Emitted on transfer
   * @param from The sender
   * @param to The recipient
   * @param value The amount transferred
   * @param index The new liquidity index of the reserve
   **/
  event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index);

  /**
   * @dev Burns depositTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying`
   * @param user The owner of the depositTokens, getting them burned
   * @param receiverOfUnderlying The address that will receive the underlying
   * @param amount The amount being burned
   * @param index The new liquidity index of the reserve
   **/
  function burn(
    address user,
    address receiverOfUnderlying,
    uint256 amount,
    uint256 index
  ) external;

  /**
   * @dev Mints depositTokens to the reserve treasury
   * @param amount The amount of tokens getting minted
   * @param index The new liquidity index of the reserve
   */
  function mintToTreasury(uint256 amount, uint256 index) external;

  /**
   * @dev Transfers depositTokens in the event of a borrow being liquidated, in case the liquidators reclaims the depositToken
   * @param from The address getting liquidated, current owner of the depositTokens
   * @param to The recipient
   * @param value The amount of tokens getting transferred
   * @param index The liquidity index of the reserve
   * @param transferUnderlying is true when the underlying should be, otherwise the depositToken
   * @return true when transferUnderlying is false and the recipient had zero balance
   **/
  function transferOnLiquidation(
    address from,
    address to,
    uint256 value,
    uint256 index,
    bool transferUnderlying
  ) external returns (bool);

  /**
   * @dev Transfers the underlying asset to `target`. Used by the LendingPool to transfer
   * assets in borrow(), withdraw() and flashLoan()
   * @param user The recipient of the underlying
   * @param amount The amount getting transferred
   * @return The amount transferred
   **/
  function transferUnderlyingTo(address user, uint256 amount) external returns (uint256);

  function collateralBalanceOf(address) external view returns (uint256);

  /**
   * @dev Emitted on use of overdraft (by liquidation)
   * @param account The receiver of overdraft (user with shortage)
   * @param value The amount received
   * @param index The liquidity index of the reserve
   **/
  event OverdraftApplied(address indexed account, uint256 value, uint256 index);

  /**
   * @dev Emitted on return of overdraft allowance when it was fully or partially used
   * @param provider The provider of overdraft
   * @param recipient The receiver of overdraft
   * @param overdraft The amount overdraft that was covered by the provider
   * @param index The liquidity index of the reserve
   **/
  event OverdraftCovered(address indexed provider, address indexed recipient, uint256 overdraft, uint256 index);

  event SubBalanceProvided(address indexed provider, address indexed recipient, uint256 amount, uint256 index);
  event SubBalanceReturned(address indexed provider, address indexed recipient, uint256 amount, uint256 index);
  event SubBalanceLocked(address indexed provider, uint256 amount, uint256 index);
  event SubBalanceUnlocked(address indexed provider, uint256 amount, uint256 index);

  function updateTreasury() external;

  function addSubBalanceOperator(address addr) external;

  function addStakeOperator(address addr) external;

  function removeSubBalanceOperator(address addr) external;

  function provideSubBalance(
    address provider,
    address recipient,
    uint256 scaledAmount
  ) external;

  function returnSubBalance(
    address provider,
    address recipient,
    uint256 scaledAmount,
    bool preferOverdraft
  ) external returns (uint256 coveredOverdraft);

  function lockSubBalance(address provider, uint256 scaledAmount) external;

  function unlockSubBalance(
    address provider,
    uint256 scaledAmount,
    address transferTo
  ) external;

  function replaceSubBalance(
    address prevProvider,
    address recipient,
    uint256 prevScaledAmount,
    address newProvider,
    uint256 newScaledAmount
  ) external returns (uint256 coveredOverdraftByPrevProvider);

  function transferLockedBalance(
    address from,
    address to,
    uint256 scaledAmount
  ) external;
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import '../tools/Errors.sol';
import './interfaces/IMarketAccessController.sol';
import './AccessHelper.sol';
import './AccessFlags.sol';

// solhint-disable func-name-mixedcase
abstract contract MarketAccessBitmaskMin {
  using AccessHelper for IMarketAccessController;
  IMarketAccessController internal _remoteAcl;

  constructor(IMarketAccessController remoteAcl) {
    _remoteAcl = remoteAcl;
  }

  function _getRemoteAcl(address addr) internal view returns (uint256) {
    return _remoteAcl.getAcl(addr);
  }

  function hasRemoteAcl() internal view returns (bool) {
    return _remoteAcl != IMarketAccessController(address(0));
  }

  function acl_hasAnyOf(address subject, uint256 flags) internal view returns (bool) {
    return _remoteAcl.hasAnyOf(subject, flags);
  }

  modifier aclHas(uint256 flags) virtual {
    _remoteAcl.requireAnyOf(msg.sender, flags, Errors.TXT_ACCESS_RESTRICTED);
    _;
  }

  modifier aclAnyOf(uint256 flags) {
    _remoteAcl.requireAnyOf(msg.sender, flags, Errors.TXT_ACCESS_RESTRICTED);
    _;
  }

  modifier onlyPoolAdmin() {
    _remoteAcl.requireAnyOf(msg.sender, AccessFlags.POOL_ADMIN, Errors.CALLER_NOT_POOL_ADMIN);
    _;
  }

  modifier onlyRewardAdmin() {
    _remoteAcl.requireAnyOf(msg.sender, AccessFlags.REWARD_CONFIG_ADMIN, Errors.CALLER_NOT_REWARD_CONFIG_ADMIN);
    _;
  }

  modifier onlyRewardConfiguratorOrAdmin() {
    _remoteAcl.requireAnyOf(
      msg.sender,
      AccessFlags.REWARD_CONFIG_ADMIN | AccessFlags.REWARD_CONFIGURATOR,
      Errors.CALLER_NOT_REWARD_CONFIG_ADMIN
    );
    _;
  }
}

abstract contract MarketAccessBitmask is MarketAccessBitmaskMin {
  using AccessHelper for IMarketAccessController;

  constructor(IMarketAccessController remoteAcl) MarketAccessBitmaskMin(remoteAcl) {}

  modifier onlyEmergencyAdmin() {
    _remoteAcl.requireAnyOf(msg.sender, AccessFlags.EMERGENCY_ADMIN, Errors.CALLER_NOT_EMERGENCY_ADMIN);
    _;
  }

  function _onlySweepAdmin() internal view virtual {
    _remoteAcl.requireAnyOf(msg.sender, AccessFlags.SWEEP_ADMIN, Errors.CALLER_NOT_SWEEP_ADMIN);
  }

  modifier onlySweepAdmin() {
    _onlySweepAdmin();
    _;
  }
}

File 8 of 23 : AccessFlags.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

library AccessFlags {
  // roles that can be assigned to multiple addresses - use range [0..15]
  uint256 public constant EMERGENCY_ADMIN = 1 << 0;
  uint256 public constant POOL_ADMIN = 1 << 1;
  uint256 public constant TREASURY_ADMIN = 1 << 2;
  uint256 public constant REWARD_CONFIG_ADMIN = 1 << 3;
  uint256 public constant REWARD_RATE_ADMIN = 1 << 4;
  uint256 public constant STAKE_ADMIN = 1 << 5;
  uint256 public constant REFERRAL_ADMIN = 1 << 6;
  uint256 public constant LENDING_RATE_ADMIN = 1 << 7;
  uint256 public constant SWEEP_ADMIN = 1 << 8;
  uint256 public constant ORACLE_ADMIN = 1 << 9;

  uint256 public constant ROLES = (uint256(1) << 16) - 1;

  // singletons - use range [16..64] - can ONLY be assigned to a single address
  uint256 public constant SINGLETONS = ((uint256(1) << 64) - 1) & ~ROLES;

  // proxied singletons
  uint256 public constant LENDING_POOL = 1 << 16;
  uint256 public constant LENDING_POOL_CONFIGURATOR = 1 << 17;
  uint256 public constant LIQUIDITY_CONTROLLER = 1 << 18;
  uint256 public constant TREASURY = 1 << 19;
  uint256 public constant REWARD_TOKEN = 1 << 20;
  uint256 public constant REWARD_STAKE_TOKEN = 1 << 21;
  uint256 public constant REWARD_CONTROLLER = 1 << 22;
  uint256 public constant REWARD_CONFIGURATOR = 1 << 23;
  uint256 public constant STAKE_CONFIGURATOR = 1 << 24;
  uint256 public constant REFERRAL_REGISTRY = 1 << 25;

  uint256 public constant PROXIES = ((uint256(1) << 26) - 1) & ~ROLES;

  // non-proxied singletons, numbered down from 31 (as JS has problems with bitmasks over 31 bits)
  uint256 public constant WETH_GATEWAY = 1 << 27;
  uint256 public constant DATA_HELPER = 1 << 28;
  uint256 public constant PRICE_ORACLE = 1 << 29;
  uint256 public constant LENDING_RATE_ORACLE = 1 << 30;

  // any other roles - use range [64..]
  // these roles can be assigned to multiple addresses

  uint256 public constant TRUSTED_FLASHLOAN = 1 << 66;
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

interface IProxy {
  function upgradeToAndCall(address newImplementation, bytes calldata data) external payable;
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import './IProxy.sol';
import './ProxyAdminBase.sol';
import '../Errors.sol';

/// @dev This contract meant to be assigned as the admin of a {IProxy}. Adopted from the OpenZeppelin
contract ProxyAdmin is ProxyAdminBase {
  address private immutable _owner;

  constructor() {
    _owner = msg.sender;
  }

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

  /// @dev Throws if called by any account other than the owner.
  modifier onlyOwner() {
    require(_owner == msg.sender, Errors.TXT_CALLER_NOT_PROXY_OWNER);
    _;
  }

  /// @dev Returns the current implementation of `proxy`.
  function getProxyImplementation(IProxy proxy) public view virtual returns (address) {
    return _getProxyImplementation(proxy);
  }

  /// @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation.
  function upgradeAndCall(
    IProxy proxy,
    address implementation,
    bytes memory data
  ) public payable virtual onlyOwner {
    proxy.upgradeToAndCall{value: msg.value}(implementation, data);
  }
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import './StakeTokenConfig.sol';

interface IStakeConfigurator {
  struct InitStakeTokenData {
    address stakeTokenImpl;
    address stakedToken;
    address strategy;
    string stkTokenName;
    string stkTokenSymbol;
    uint32 cooldownPeriod;
    uint32 unstakePeriod;
    uint16 maxSlashable;
    uint8 stkTokenDecimals;
    bool depositStake;
  }

  struct UpdateStakeTokenData {
    address token;
    address stakeTokenImpl;
    string stkTokenName;
    string stkTokenSymbol;
  }

  struct StakeTokenData {
    address token;
    string stkTokenName;
    string stkTokenSymbol;
    StakeTokenConfig config;
  }

  event StakeTokenInitialized(address indexed token, InitStakeTokenData data);

  event StakeTokenUpgraded(address indexed token, UpdateStakeTokenData data);

  event StakeTokenAdded(address indexed token, address indexed underlying);

  event StakeTokenRemoved(address indexed token, address indexed underlying);

  function list() external view returns (address[] memory tokens);

  function listAll() external view returns (address[] memory tokens, uint256 genCount);

  function dataOf(address stakeToken) external view returns (StakeTokenData memory data);

  function stakeTokenOf(address underlying) external view returns (address);

  function setCooldownForAll(uint32 cooldownPeriod, uint32 unstakePeriod) external;
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import './StakeTokenConfig.sol';

/// @dev Interface for the initialize function on StakeToken
interface IInitializableStakeToken {
  event Initialized(StakeTokenConfig params, string tokenName, string tokenSymbol);

  function initializeStakeToken(
    StakeTokenConfig calldata params,
    string calldata name,
    string calldata symbol
  ) external;

  function initializedStakeTokenWith()
    external
    view
    returns (
      StakeTokenConfig memory params,
      string memory name,
      string memory symbol
    );
}

File 13 of 23 : StakeTokenConfig.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import '../../../dependencies/openzeppelin/contracts/IERC20.sol';
import '../../../access/interfaces/IMarketAccessController.sol';
import '../../../interfaces/IUnderlyingStrategy.sol';

struct StakeTokenConfig {
  IMarketAccessController stakeController;
  IERC20 stakedToken;
  IUnderlyingStrategy strategy;
  uint32 cooldownPeriod;
  uint32 unstakePeriod;
  uint16 maxSlashable;
  uint8 stakedTokenDecimals;
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import '../../../interfaces/IEmergencyAccess.sol';

interface IManagedStakeToken is IEmergencyAccess {
  event Slashed(address to, uint256 amount, uint256 totalBeforeSlash);

  event MaxSlashUpdated(uint16 maxSlash);
  event CooldownUpdated(uint32 cooldownPeriod, uint32 unstakePeriod);

  event RedeemableUpdated(bool redeemable);

  function setRedeemable(bool redeemable) external;

  function setMaxSlashablePercentage(uint16 percentage) external;

  function setCooldown(uint32 cooldownPeriod, uint32 unstakePeriod) external;

  function slashUnderlying(
    address destination,
    uint256 minAmount,
    uint256 maxAmount
  ) external returns (uint256 amount, bool erc20Transfer);
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import './IRemoteAccessBitmask.sol';
import '../../tools/upgradeability/IProxy.sol';

/// @dev Main registry of permissions and addresses
interface IAccessController is IRemoteAccessBitmask {
  function getAddress(uint256 id) external view returns (address);

  function createProxy(
    address admin,
    address impl,
    bytes calldata params
  ) external returns (IProxy);
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

interface IRemoteAccessBitmask {
  /**
   * @dev Returns access flags granted to the given address and limited by the filterMask. filterMask == 0 has a special meaning.
   * @param addr an to get access perfmissions for
   * @param filterMask limits a subset of flags to be checked.
   * NB! When filterMask == 0 then zero is returned no flags granted, or an unspecified non-zero value otherwise.
   * @return Access flags currently granted
   */
  function queryAccessControlMask(address addr, uint256 filterMask) external view returns (uint256);
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

interface IScaledBalanceToken {
  /**
   * @dev Returns the scaled balance of the user. The scaled balance is the sum of all the
   * updated stored balance divided by the reserve's liquidity index at the moment of the update
   * @param user The user whose balance is calculated
   * @return The scaled balance of the user
   **/
  function scaledBalanceOf(address user) external view returns (uint256);

  /**
   * @dev Returns the scaled balance of the user and the scaled total supply.
   * @param user The address of the user
   * @return The scaled balance of the user
   * @return The scaled balance and the scaled total supply
   **/
  function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256);

  /**
   * @dev Returns the scaled total supply of the variable debt token. Represents sum(debt/index)
   * @return The scaled total supply
   **/
  function scaledTotalSupply() external view returns (uint256);

  function getScaleIndex() external view returns (uint256);
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import './IDerivedToken.sol';

// solhint-disable func-name-mixedcase
interface IPoolToken is IDerivedToken {
  function POOL() external view returns (address);

  function updatePool() external;
}

File 19 of 23 : Errors.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

/**
 * @title Errors library
 * @notice Defines the error messages emitted by the different contracts
 * @dev Error messages prefix glossary:
 *  - VL = ValidationLogic
 *  - MATH = Math libraries
 *  - CT = Common errors between tokens (DepositToken, VariableDebtToken and StableDebtToken)
 *  - AT = DepositToken
 *  - SDT = StableDebtToken
 *  - VDT = VariableDebtToken
 *  - LP = LendingPool
 *  - LPAPR = AddressesProviderRegistry
 *  - LPC = LendingPoolConfiguration
 *  - RL = ReserveLogic
 *  - LPCM = LendingPoolExtension
 *  - ST = Stake
 */
library Errors {
  //contract specific errors
  string public constant VL_INVALID_AMOUNT = '1'; // Amount must be greater than 0
  string public constant VL_NO_ACTIVE_RESERVE = '2'; // Action requires an active reserve
  string public constant VL_RESERVE_FROZEN = '3'; // Action cannot be performed because the reserve is frozen
  string public constant VL_UNKNOWN_RESERVE = '4'; // Action requires an active reserve
  string public constant VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE = '5'; // User cannot withdraw more than the available balance (above min limit)
  string public constant VL_TRANSFER_NOT_ALLOWED = '6'; // Transfer cannot be allowed.
  string public constant VL_BORROWING_NOT_ENABLED = '7'; // Borrowing is not enabled
  string public constant VL_INVALID_INTEREST_RATE_MODE_SELECTED = '8'; // Invalid interest rate mode selected
  string public constant VL_COLLATERAL_BALANCE_IS_0 = '9'; // The collateral balance is 0
  string public constant VL_HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '10'; // Health factor is lesser than the liquidation threshold
  string public constant VL_COLLATERAL_CANNOT_COVER_NEW_BORROW = '11'; // There is not enough collateral to cover a new borrow
  string public constant VL_STABLE_BORROWING_NOT_ENABLED = '12'; // stable borrowing not enabled
  string public constant VL_COLLATERAL_SAME_AS_BORROWING_CURRENCY = '13'; // collateral is (mostly) the same currency that is being borrowed
  string public constant VL_AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE = '14'; // The requested amount is exceeds max size of a stable loan
  string public constant VL_NO_DEBT_OF_SELECTED_TYPE = '15'; // to repay a debt, user needs to specify a correct debt type (variable or stable)
  string public constant VL_NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '16'; // To repay on behalf of an user an explicit amount to repay is needed
  string public constant VL_NO_STABLE_RATE_LOAN_IN_RESERVE = '17'; // User does not have a stable rate loan in progress on this reserve
  string public constant VL_NO_VARIABLE_RATE_LOAN_IN_RESERVE = '18'; // User does not have a variable rate loan in progress on this reserve
  string public constant VL_UNDERLYING_BALANCE_NOT_GREATER_THAN_0 = '19'; // The collateral balance needs to be greater than 0
  string public constant VL_DEPOSIT_ALREADY_IN_USE = '20'; // User deposit is already being used as collateral
  string public constant VL_RESERVE_MUST_BE_COLLATERAL = '21'; // This reserve must be enabled as collateral
  string public constant LP_INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET = '22'; // Interest rate rebalance conditions were not met
  string public constant AT_OVERDRAFT_DISABLED = '23'; // User doesn't accept allocation of overdraft
  string public constant VL_INVALID_SUB_BALANCE_ARGS = '24';
  string public constant AT_INVALID_SLASH_DESTINATION = '25';

  string public constant LP_CALLER_NOT_LENDING_POOL_CONFIGURATOR = '27'; // The caller of the function is not the lending pool configurator

  string public constant LENDING_POOL_REQUIRED = '28'; // The caller of this function must be a lending pool
  string public constant CALLER_NOT_LENDING_POOL = '29'; // The caller of this function must be a lending pool
  string public constant AT_SUB_BALANCE_RESTIRCTED_FUNCTION = '30'; // The caller of this function must be a lending pool or a sub-balance operator

  string public constant RL_RESERVE_ALREADY_INITIALIZED = '32'; // Reserve has already been initialized
  string public constant CALLER_NOT_POOL_ADMIN = '33'; // The caller must be the pool admin
  string public constant LPC_RESERVE_LIQUIDITY_NOT_0 = '34'; // The liquidity of the reserve needs to be 0

  string public constant LPAPR_PROVIDER_NOT_REGISTERED = '41'; // Provider is not registered
  string public constant LPCM_HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '42'; // Health factor is not below the threshold
  string public constant LPCM_COLLATERAL_CANNOT_BE_LIQUIDATED = '43'; // The collateral chosen cannot be liquidated
  string public constant LPCM_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '44'; // User did not borrow the specified currency
  string public constant LPCM_NOT_ENOUGH_LIQUIDITY_TO_LIQUIDATE = '45'; // There isn't enough liquidity available to liquidate

  string public constant MATH_MULTIPLICATION_OVERFLOW = '48';
  string public constant MATH_ADDITION_OVERFLOW = '49';
  string public constant MATH_DIVISION_BY_ZERO = '50';
  string public constant RL_LIQUIDITY_INDEX_OVERFLOW = '51'; //  Liquidity index overflows uint128
  string public constant RL_VARIABLE_BORROW_INDEX_OVERFLOW = '52'; //  Variable borrow index overflows uint128
  string public constant RL_LIQUIDITY_RATE_OVERFLOW = '53'; //  Liquidity rate overflows uint128
  string public constant RL_VARIABLE_BORROW_RATE_OVERFLOW = '54'; //  Variable borrow rate overflows uint128
  string public constant RL_STABLE_BORROW_RATE_OVERFLOW = '55'; //  Stable borrow rate overflows uint128
  string public constant CT_INVALID_MINT_AMOUNT = '56'; //invalid amount to mint
  string public constant CALLER_NOT_STAKE_ADMIN = '57';
  string public constant CT_INVALID_BURN_AMOUNT = '58'; //invalid amount to burn
  string public constant BORROW_ALLOWANCE_NOT_ENOUGH = '59'; // User borrows on behalf, but allowance are too small
  string public constant CALLER_NOT_LIQUIDITY_CONTROLLER = '60';
  string public constant CALLER_NOT_REF_ADMIN = '61';
  string public constant VL_INSUFFICIENT_REWARD_AVAILABLE = '62';
  string public constant LP_CALLER_MUST_BE_DEPOSIT_TOKEN = '63';
  string public constant LP_IS_PAUSED = '64'; // Pool is paused
  string public constant LP_NO_MORE_RESERVES_ALLOWED = '65';
  string public constant LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN = '66';
  string public constant RC_INVALID_LTV = '67';
  string public constant RC_INVALID_LIQ_THRESHOLD = '68';
  string public constant RC_INVALID_LIQ_BONUS = '69';
  string public constant RC_INVALID_DECIMALS = '70';
  string public constant RC_INVALID_RESERVE_FACTOR = '71';
  string public constant LPAPR_INVALID_ADDRESSES_PROVIDER_ID = '72';
  string public constant VL_INCONSISTENT_FLASHLOAN_PARAMS = '73';
  string public constant VL_TREASURY_REQUIRED = '74';
  string public constant LPC_INVALID_CONFIGURATION = '75'; // Invalid risk parameters for the reserve
  string public constant CALLER_NOT_EMERGENCY_ADMIN = '76'; // The caller must be the emergency admin
  string public constant UL_INVALID_INDEX = '77';
  string public constant VL_CONTRACT_REQUIRED = '78';
  string public constant SDT_STABLE_DEBT_OVERFLOW = '79';
  string public constant SDT_BURN_EXCEEDS_BALANCE = '80';
  string public constant CALLER_NOT_REWARD_CONFIG_ADMIN = '81'; // The caller of this function must be a reward admin
  string public constant LP_INVALID_PERCENTAGE = '82'; // Percentage can't be more than 100%
  string public constant LP_IS_NOT_TRUSTED_FLASHLOAN = '83';
  string public constant CALLER_NOT_SWEEP_ADMIN = '84';
  string public constant LP_TOO_MANY_NESTED_CALLS = '85';
  string public constant LP_RESTRICTED_FEATURE = '86';
  string public constant LP_TOO_MANY_FLASHLOAN_CALLS = '87';
  string public constant RW_BASELINE_EXCEEDED = '88';
  string public constant CALLER_NOT_REWARD_RATE_ADMIN = '89';
  string public constant CALLER_NOT_REWARD_CONTROLLER = '90';
  string public constant RW_REWARD_PAUSED = '91';
  string public constant CALLER_NOT_TEAM_MANAGER = '92';
  string public constant STK_REDEEM_PAUSED = '93';
  string public constant STK_INSUFFICIENT_COOLDOWN = '94';
  string public constant STK_UNSTAKE_WINDOW_FINISHED = '95';
  string public constant STK_INVALID_BALANCE_ON_COOLDOWN = '96';
  string public constant STK_EXCESSIVE_SLASH_PCT = '97';
  string public constant STK_WRONG_COOLDOWN_OR_UNSTAKE = '98';
  string public constant STK_PAUSED = '99';

  string public constant TXT_OWNABLE_CALLER_NOT_OWNER = 'Ownable: caller is not the owner';
  string public constant TXT_CALLER_NOT_PROXY_OWNER = 'ProxyOwner: caller is not the owner';
  string public constant TXT_ACCESS_RESTRICTED = 'RESTRICTED';
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import './interfaces/IRemoteAccessBitmask.sol';

/// @dev Helper/wrapper around IRemoteAccessBitmask
library AccessHelper {
  function getAcl(IRemoteAccessBitmask remote, address subject) internal view returns (uint256) {
    return remote.queryAccessControlMask(subject, ~uint256(0));
  }

  function queryAcl(
    IRemoteAccessBitmask remote,
    address subject,
    uint256 filterMask
  ) internal view returns (uint256) {
    return remote.queryAccessControlMask(subject, filterMask);
  }

  function hasAnyOf(
    IRemoteAccessBitmask remote,
    address subject,
    uint256 flags
  ) internal view returns (bool) {
    uint256 found = queryAcl(remote, subject, flags);
    return found & flags != 0;
  }

  function hasAny(IRemoteAccessBitmask remote, address subject) internal view returns (bool) {
    return remote.queryAccessControlMask(subject, 0) != 0;
  }

  function hasNone(IRemoteAccessBitmask remote, address subject) internal view returns (bool) {
    return remote.queryAccessControlMask(subject, 0) == 0;
  }

  function requireAnyOf(
    IRemoteAccessBitmask remote,
    address subject,
    uint256 flags,
    string memory text
  ) internal view {
    require(hasAnyOf(remote, subject, flags), text);
  }
}

File 21 of 23 : ProxyAdminBase.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

import './IProxy.sol';

abstract contract ProxyAdminBase {
  /// @dev Returns the current implementation of an owned `proxy`.
  function _getProxyImplementation(IProxy proxy) internal view returns (address) {
    // We need to manually run the static call since the getter cannot be flagged as view
    // bytes4(keccak256('implementation()')) == 0x5c60da1b
    (bool success, bytes memory returndata) = address(proxy).staticcall(hex'5c60da1b');
    require(success);
    return abi.decode(returndata, (address));
  }
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

interface IUnderlyingStrategy {
  function getUnderlying(address asset) external view returns (address);

  function delegatedWithdrawUnderlying(
    address asset,
    uint256 amount,
    address to
  ) external returns (uint256);
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.4;

interface IEmergencyAccess {
  function setPaused(bool paused) external;

  function isPaused() external view returns (bool);

  event EmergencyPaused(address indexed by, bool paused);
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"underlying","type":"address"}],"name":"StakeTokenAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"components":[{"internalType":"address","name":"stakeTokenImpl","type":"address"},{"internalType":"address","name":"stakedToken","type":"address"},{"internalType":"address","name":"strategy","type":"address"},{"internalType":"string","name":"stkTokenName","type":"string"},{"internalType":"string","name":"stkTokenSymbol","type":"string"},{"internalType":"uint32","name":"cooldownPeriod","type":"uint32"},{"internalType":"uint32","name":"unstakePeriod","type":"uint32"},{"internalType":"uint16","name":"maxSlashable","type":"uint16"},{"internalType":"uint8","name":"stkTokenDecimals","type":"uint8"},{"internalType":"bool","name":"depositStake","type":"bool"}],"indexed":false,"internalType":"struct IStakeConfigurator.InitStakeTokenData","name":"data","type":"tuple"}],"name":"StakeTokenInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"underlying","type":"address"}],"name":"StakeTokenRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"stakeTokenImpl","type":"address"},{"internalType":"string","name":"stkTokenName","type":"string"},{"internalType":"string","name":"stkTokenSymbol","type":"string"}],"indexed":false,"internalType":"struct IStakeConfigurator.UpdateStakeTokenData","name":"data","type":"tuple"}],"name":"StakeTokenUpgraded","type":"event"},{"inputs":[],"name":"REVISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"addStakeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"stakeTokenImpl","type":"address"},{"internalType":"address","name":"stakedToken","type":"address"},{"internalType":"address","name":"strategy","type":"address"},{"internalType":"string","name":"stkTokenName","type":"string"},{"internalType":"string","name":"stkTokenSymbol","type":"string"},{"internalType":"uint32","name":"cooldownPeriod","type":"uint32"},{"internalType":"uint32","name":"unstakePeriod","type":"uint32"},{"internalType":"uint16","name":"maxSlashable","type":"uint16"},{"internalType":"uint8","name":"stkTokenDecimals","type":"uint8"},{"internalType":"bool","name":"depositStake","type":"bool"}],"internalType":"struct IStakeConfigurator.InitStakeTokenData[]","name":"input","type":"tuple[]"}],"name":"batchInitStakeTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakeToken","type":"address"}],"name":"dataOf","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"string","name":"stkTokenName","type":"string"},{"internalType":"string","name":"stkTokenSymbol","type":"string"},{"components":[{"internalType":"contract IMarketAccessController","name":"stakeController","type":"address"},{"internalType":"contract IERC20","name":"stakedToken","type":"address"},{"internalType":"contract IUnderlyingStrategy","name":"strategy","type":"address"},{"internalType":"uint32","name":"cooldownPeriod","type":"uint32"},{"internalType":"uint32","name":"unstakePeriod","type":"uint32"},{"internalType":"uint16","name":"maxSlashable","type":"uint16"},{"internalType":"uint8","name":"stakedTokenDecimals","type":"uint8"}],"internalType":"struct StakeTokenConfig","name":"config","type":"tuple"}],"internalType":"struct IStakeConfigurator.StakeTokenData","name":"data","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProxyAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"implementationOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addressesProvider","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"list","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"listAll","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256","name":"genCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"removeStakeToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"removeStakeTokenByUnderlying","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"underlyings","type":"address[]"}],"name":"removeUnderlyings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"cooldownPeriod","type":"uint32"},{"internalType":"uint32","name":"unstakePeriod","type":"uint32"}],"name":"setCooldownForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"stakeTokenOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"stakeTokenImpl","type":"address"},{"internalType":"string","name":"stkTokenName","type":"string"},{"internalType":"string","name":"stkTokenSymbol","type":"string"}],"internalType":"struct IStakeConfigurator.UpdateStakeTokenData","name":"input","type":"tuple"}],"name":"updateStakeToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052610011600160001961003b565b600155600060025534801561002557600080fd5b50600080546001600160a01b031916905561005e565b60008282101561005957634e487b7160e01b81526011600452602481fd5b500390565b6123598061006d6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063a84ce13d11610097578063c4d66de811610066578063c4d66de81461020a578063d221cd181461021d578063dde43cba14610230578063e5a5d4d71461023f57600080fd5b8063a84ce13d146101b1578063b211ddf2146101c4578063bb3d4562146101d7578063c0b08af3146101f757600080fd5b806378a9eeed116100d357806378a9eeed146101405780637ca59ec5146101565780638b3240a0146101795780638b4872b81461019e57600080fd5b80630f560cd7146100fa5780631fecb71a146101185780637428f5801461012d575b600080fd5b610102610252565b60405161010f91906119b2565b60405180910390f35b61012b610126366004611574565b610264565b005b61012b61013b3660046115b3565b61036e565b610148610424565b60405161010f9291906119c5565b610169610164366004611818565b61043d565b604051901515815260200161010f565b600a546001600160a01b03165b6040516001600160a01b03909116815260200161010f565b6101866101ac366004611574565b61049d565b6101696101bf366004611574565b610521565b6101866101d2366004611574565b6105d1565b6101ea6101e5366004611574565b610616565b60405161010f9190611b6f565b61012b610205366004611848565b6106ff565b61012b610218366004611574565b6107d7565b61012b61022b366004611623565b61088c565b6040516003815260200161010f565b61012b61024d3660046117e0565b610921565b606061025f600b54610ac0565b905090565b60408051808201909152600a815269149154d5149250d5115160b21b60208281019190915260005490916102a5916001600160a01b03169033908490610bc3565b6001600160a01b0382166102f05760405162461bcd60e51b815260206004820152600d60248201526c3ab735b737bbb7103a37b5b2b760991b60448201526064015b60405180910390fd5b61036a82836001600160a01b031663b16a19de6040518163ffffffff1660e01b815260040160206040518083038186803b15801561032d57600080fd5b505afa158015610341573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103659190611597565b610bed565b5050565b60408051808201909152600a815269149154d5149250d5115160b21b60208281019190915260005490916103af916001600160a01b03169033908490610bc3565b815b801561041e57806103c181611df0565b9150506000600960008686858181106103ea57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906103ff9190611574565b6001600160a01b031681526020810191909152604001600020556103b1565b50505050565b606060006104326000610ac0565b600b54915091509091565b60408051808201909152600a815269149154d5149250d5115160b21b60208281019190915260008054909261047f916001600160a01b03169033908490610bc3565b61049461048d846001611d95565b6000610d59565b91505b50919050565b600a546040516310270e3d60e11b81526001600160a01b038381166004830152600092169063204e1c7a9060240160206040518083038186803b1580156104e357600080fd5b505afa1580156104f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051b9190611597565b92915050565b60408051808201909152600a815269149154d5149250d5115160b21b602082810191909152600080549092610563916001600160a01b03169033908490610bc3565b6001600160a01b0383166105ae5760405162461bcd60e51b8152602060048201526012602482015271756e6b6e6f776e20756e6465726c79696e6760701b60448201526064016102e7565b6001600160a01b0383166000908152600960205260409020546104949084610d59565b6001600160a01b038116600090815260096020526040812054806105f85750600092915050565b6000908152600760205260409020546001600160a01b031692915050565b6040805160808082018352600080835260606020808501829052848601829052855160e08101875283815290810183905294850182905284810182905291840181905260a0840181905260c0840152810191909152816001600160a01b03166326cc73a46040518163ffffffff1660e01b815260040160006040518083038186803b1580156106a457600080fd5b505afa1580156106b8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106e091908101906116e5565b6040840152602083015260608201526001600160a01b03909116815290565b60408051808201909152600a815269149154d5149250d5115160b21b6020828101919091526000549091610740916001600160a01b03169033908490610bc3565b60015b600854811161041e576000818152600760205260409081902054905163034d53c960e61b815263ffffffff8087166004830152851660248201526001600160a01b039091169063d354f24090604401600060405180830381600087803b1580156107ac57600080fd5b505af11580156107c0573d6000803e3d6000fd5b5050505080806107cf90611e07565b915050610743565b600360008060006107e784610e1b565b92509250925080610875576002849055600080546001600160a01b0319166001600160a01b0387811691909117909155600a541661086f5760405161082b90611378565b604051809103906000f080158015610847573d6000803e3d6000fd5b50600a80546001600160a01b0319166001600160a01b0392909216919091179055600854600b555b60018490555b8161088557600183905560006002555b5050505050565b60408051808201909152600a815269149154d5149250d5115160b21b60208281019190915260005490916108cd916001600160a01b03169033908490610bc3565b60005b825181101561091c576109098382815181106108fc57634e487b7160e01b600052603260045260246000fd5b6020026020010151611093565b508061091481611e07565b9150506108d0565b505050565b60408051808201909152600a815269149154d5149250d5115160b21b6020828101919091526000549091610962916001600160a01b03169033908490610bc3565b60006109746101e56020850185611574565b606081015190915060009063029cc27560e31b906109956040870187611c5e565b6109a26060890189611c5e565b6040516024016109b6959493929190611aeb565b60408051601f19818403018152919052602080820180516001600160e01b03166001600160e01b031990941693909317909252600a549092506001600160a01b031690639623609d90610a0b90870187611574565b610a1b6040880160208901611574565b846040518463ffffffff1660e01b8152600401610a3a9392919061197d565b600060405180830381600087803b158015610a5457600080fd5b505af1158015610a68573d6000803e3d6000fd5b50610a7a925050506020850185611574565b6001600160a01b03167f73fbc15c12587628a9b73620b8c8344925a246233d8a913f2648074eb659801e85604051610ab29190611bd9565b60405180910390a250505050565b60608160085411610ad057919050565b81600854610ade9190611dad565b67ffffffffffffffff811115610b0457634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610b2d578160200160208202803683370190505b50905081610b3a81611e07565b92505060005b81518110156104975760076000610b578584611d95565b815260200190815260200160002060009054906101000a90046001600160a01b0316828281518110610b9957634e487b7160e01b600052603260045260246000fd5b6001600160a01b039092166020928302919091019091015280610bbb81611e07565b915050610b40565b610bce8484846112d1565b81906108855760405162461bcd60e51b81526004016102e791906119e7565b6001600160a01b038216610c335760405162461bcd60e51b815260206004820152600d60248201526c3ab735b737bbb7103a37b5b2b760991b60448201526064016102e7565b6001600160a01b038116610c7e5760405162461bcd60e51b8152602060048201526012602482015271756e6b6e6f776e20756e6465726c79696e6760701b60448201526064016102e7565b6000610c89826105d1565b6001600160a01b031614610cd65760405162461bcd60e51b8152602060048201526014602482015273616d626967756f757320756e6465726c79696e6760601b60448201526064016102e7565b60088054906000610ce683611e07565b909155505060088054600090815260076020908152604080832080546001600160a01b0319166001600160a01b038881169182179092559454908616808552600990935281842055519092917f8a52a82e364afc632091797d755ced6da40de72c9a0ce9cdd85e7519036fd01b91a35050565b6000821580610d7d57506000838152600760205260409020546001600160a01b0316155b15610d8a5750600061051b565b6000838152600760205260408082205490516001600160a01b03808616939216917f1bb2e84515df1bee0c5326e6dd3cc5f17229f9bc9e7ca060c8b7ecc76e12aafc91a3600083815260076020526040902080546001600160a01b03191690556001600160a01b038216610e12576001600160a01b0382166000908152600960205260408120555b50600192915050565b6003600080610e2d6001600019611dad565b8310610e7b5760405162461bcd60e51b815260206004820152601960248201527f696e76616c696420636f6e7472616374207265766973696f6e0000000000000060448201526064016102e7565b60008411610ecb5760405162461bcd60e51b815260206004820152601e60248201527f696e636f727265637420696e697469616c697a6572207265766973696f6e000060448201526064016102e7565b82841115610f1b5760405162461bcd60e51b815260206004820152601e60248201527f696e636f6e73697374656e7420636f6e7472616374207265766973696f6e000060448201526064016102e7565b610f286001600019611dad565b6001541015610fa4576000600254118015610f44575082600154105b91508180610f515750303b155b80610f5d575060015483115b610f9f5760405162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016102e7565b611014565b610fb16001600019611dad565b600154148015610fc05750303b155b6110025760405162461bcd60e51b81526020600482015260136024820152721a5b9a5d1a585b1a5e995c88189b1bd8dad959606a1b60448201526064016102e7565b60006001556002546000199350151591505b811561106b57836002541161106b5760405162461bcd60e51b815260206004820152601f60248201527f696e636f7272656374206f72646572206f6620696e697469616c697a6572730060448201526064016102e7565b60015484116110885781156110805760016002555b50600161108c565b5060005b9193909250565b6000806040518060e0016040528060008054906101000a90046001600160a01b03166001600160a01b0316815260200184602001516001600160a01b0316815260200184604001516001600160a01b031681526020018460a0015163ffffffff1681526020018460c0015163ffffffff1681526020018460e0015161ffff16815260200184610100015160ff16815250905060006314e613a860e01b828560600151866080015160405160240161114c93929190611b2f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600054600a5487519351633eba8a9760e11b81529294506001600160a01b0391821693637d75152e936111ba939290921691869060040161197d565b602060405180830381600087803b1580156111d457600080fd5b505af11580156111e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120c9190611597565b92508361012001511561127b5760208401516040516314b31be760e11b81526001600160a01b0385811660048301529091169063296637ce90602401600060405180830381600087803b15801561126257600080fd5b505af1158015611276573d6000803e3d6000fd5b505050505b826001600160a01b03167f9aa34738f5695809e68b6ff39406c2e7246909c8cb7bce7455ae70273665bcd2856040516112b491906119fa565b60405180910390a26112ca838560200151610bed565b5050919050565b6000806112df8585856112ec565b9092161515949350505050565b60405163cc8b29c160e01b81526001600160a01b038381166004830152602482018390526000919085169063cc8b29c19060440160206040518083038186803b15801561133857600080fd5b505afa15801561134c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113709190611830565b949350505050565b61048c80611e9883390190565b803561139081611e4e565b919050565b8035801515811461139057600080fd5b600082601f8301126113b5578081fd5b81356113c86113c382611d28565b611cf7565b8181528460208386010111156113dc578283fd5b816020850160208301379081016020019190915292915050565b600082601f830112611406578081fd5b81516114146113c382611d28565b818152846020838601011115611428578283fd5b611370826020830160208701611dc4565b6000610140828403121561144b578081fd5b611453611caa565b905061145e82611385565b815261146c60208301611385565b602082015261147d60408301611385565b6040820152606082013567ffffffffffffffff8082111561149d57600080fd5b6114a9858386016113a5565b606084015260808401359150808211156114c257600080fd5b506114cf848285016113a5565b6080830152506114e160a08301611548565b60a08201526114f260c08301611548565b60c082015261150360e08301611532565b60e082015261010061151681840161155e565b90820152610120611528838201611395565b9082015292915050565b803561139081611e66565b805161139081611e66565b803561139081611e76565b805161139081611e76565b803561139081611e88565b805161139081611e88565b600060208284031215611585578081fd5b813561159081611e4e565b9392505050565b6000602082840312156115a8578081fd5b815161159081611e4e565b600080602083850312156115c5578081fd5b823567ffffffffffffffff808211156115dc578283fd5b818501915085601f8301126115ef578283fd5b8135818111156115fd578384fd5b8660208260051b8501011115611611578384fd5b60209290920196919550909350505050565b60006020808385031215611635578182fd5b823567ffffffffffffffff8082111561164c578384fd5b818501915085601f83011261165f578384fd5b81358181111561167157611671611e38565b8060051b611680858201611cf7565b8281528581019085870183870188018b101561169a578889fd5b8893505b848410156116d7578035868111156116b457898afd5b6116c28c8a838b0101611439565b8452506001939093019291870191870161169e565b509998505050505050505050565b60008060008385036101208112156116fb578182fd5b60e0811215611708578182fd5b50611711611cd4565b845161171c81611e4e565b8152602085015161172c81611e4e565b6020820152604085015161173f81611e4e565b6040820152606085015161175281611e76565b606082015261176360808601611553565b608082015261177460a0860161153d565b60a082015261178560c08601611569565b60c082015260e085015190935067ffffffffffffffff808211156117a7578283fd5b6117b3878388016113f6565b93506101008601519150808211156117c9578283fd5b506117d6868287016113f6565b9150509250925092565b6000602082840312156117f1578081fd5b813567ffffffffffffffff811115611807578182fd5b820160808185031215611590578182fd5b600060208284031215611829578081fd5b5035919050565b600060208284031215611841578081fd5b5051919050565b6000806040838503121561185a578182fd5b823561186581611e76565b9150602083013561187581611e76565b809150509250929050565b6000815180845260208085019450808401835b838110156118b85781516001600160a01b031687529582019590820190600101611893565b509495945050505050565b600081518084526118db816020860160208601611dc4565b601f01601f19169290920160200192915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b0380825116835280602083015116602084015280604083015116604084015250606081015163ffffffff8082166060850152806080840151166080850152505061ffff60a08201511660a083015260ff60c08201511660c08301525050565b6001600160a01b038481168252831660208201526060604082018190526000906119a9908301846118c3565b95945050505050565b6020815260006115906020830184611880565b6040815260006119d86040830185611880565b90508260208301529392505050565b60208152600061159060208301846118c3565b60208152611a146020820183516001600160a01b03169052565b60006020830151611a3060408401826001600160a01b03169052565b5060408301516001600160a01b0381166060840152506060830151610140806080850152611a626101608501836118c3565b91506080850151601f198584030160a0860152611a7f83826118c3565b92505060a0850151611a9960c086018263ffffffff169052565b5060c085015163ffffffff811660e08601525060e0850151610100611ac38187018361ffff169052565b8601519050610120611ad98682018360ff169052565b90950151151593019290925250919050565b6000610120611afa8389611918565b8060e0840152611b0d81840187896118ef565b9050828103610100840152611b238185876118ef565b98975050505050505050565b6000610120611b3e8387611918565b8060e0840152611b50818401866118c3565b9050828103610100840152611b6581856118c3565b9695505050505050565b602080825282516001600160a01b0316828201528201516101406040830152600090611b9f6101608401826118c3565b90506040840151601f19848303016060850152611bbc82826118c3565b9150506060840151611bd16080850182611918565b509392505050565b6020815260008235611bea81611e4e565b6001600160a01b0390811660208481019190915284013590611c0b82611e4e565b80821660408501525050611c226040840184611d50565b60806060850152611c3760a0850182846118ef565b915050611c476060850185611d50565b848303601f19016080860152611b658382846118ef565b6000808335601e19843603018112611c74578283fd5b83018035915067ffffffffffffffff821115611c8e578283fd5b602001915036819003821315611ca357600080fd5b9250929050565b604051610140810167ffffffffffffffff81118282101715611cce57611cce611e38565b60405290565b60405160e0810167ffffffffffffffff81118282101715611cce57611cce611e38565b604051601f8201601f1916810167ffffffffffffffff81118282101715611d2057611d20611e38565b604052919050565b600067ffffffffffffffff821115611d4257611d42611e38565b50601f01601f191660200190565b6000808335601e19843603018112611d66578283fd5b830160208101925035905067ffffffffffffffff811115611d8657600080fd5b803603831315611ca357600080fd5b60008219821115611da857611da8611e22565b500190565b600082821015611dbf57611dbf611e22565b500390565b60005b83811015611ddf578181015183820152602001611dc7565b8381111561041e5750506000910152565b600081611dff57611dff611e22565b506000190190565b6000600019821415611e1b57611e1b611e22565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611e6357600080fd5b50565b61ffff81168114611e6357600080fd5b63ffffffff81168114611e6357600080fd5b60ff81168114611e6357600080fdfe60a060405234801561001057600080fd5b5033606081901b608052610455610037600039600081816084015260da01526104556000f3fe6080604052600436106100345760003560e01c8063204e1c7a146100395780638da5cb5b146100755780639623609d146100a8575b600080fd5b34801561004557600080fd5b5061005961005436600461025f565b6100bd565b6040516001600160a01b03909116815260200160405180910390f35b34801561008157600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610059565b6100bb6100b636600461027b565b6100ce565b005b60006100c8826101ab565b92915050565b336001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146040518060600160405280602381526020016103fd60239139906101435760405162461bcd60e51b815260040161013a91906103bb565b60405180910390fd5b5060405163278f794360e11b81526001600160a01b03841690634f1ef2869034906101749086908690600401610397565b6000604051808303818588803b15801561018d57600080fd5b505af11580156101a1573d6000803e3d6000fd5b5050505050505050565b6000806000836001600160a01b03166040516101d190635c60da1b60e01b815260040190565b600060405180830381855afa9150503d806000811461020c576040519150601f19603f3d011682016040523d82523d6000602084013e610211565b606091505b50915091508161022057600080fd5b80806020019051810190610234919061023c565b949350505050565b60006020828403121561024d578081fd5b8151610258816103e4565b9392505050565b600060208284031215610270578081fd5b8135610258816103e4565b60008060006060848603121561028f578182fd5b833561029a816103e4565b925060208401356102aa816103e4565b9150604084013567ffffffffffffffff808211156102c6578283fd5b818601915086601f8301126102d9578283fd5b8135818111156102eb576102eb6103ce565b604051601f8201601f19908116603f01168101908382118183101715610313576103136103ce565b8160405282815289602084870101111561032b578586fd5b82602086016020830137856020848301015280955050505050509250925092565b60008151808452815b8181101561037157602081850181015186830182015201610355565b818111156103825782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b03831681526040602082018190526000906102349083018461034c565b602081526000610258602083018461034c565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146103f957600080fd5b5056fe50726f78794f776e65723a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220fce73874609aee182d8e44606007c0b6b6f18a996714ca0d4b1d33977d30a0d864736f6c63430008040033a26469706673582212203d3d9944ac36fedb479dda9707a1f4d043df3fc5fbcf21d48386f4a732ff273664736f6c63430008040033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100f55760003560e01c8063a84ce13d11610097578063c4d66de811610066578063c4d66de81461020a578063d221cd181461021d578063dde43cba14610230578063e5a5d4d71461023f57600080fd5b8063a84ce13d146101b1578063b211ddf2146101c4578063bb3d4562146101d7578063c0b08af3146101f757600080fd5b806378a9eeed116100d357806378a9eeed146101405780637ca59ec5146101565780638b3240a0146101795780638b4872b81461019e57600080fd5b80630f560cd7146100fa5780631fecb71a146101185780637428f5801461012d575b600080fd5b610102610252565b60405161010f91906119b2565b60405180910390f35b61012b610126366004611574565b610264565b005b61012b61013b3660046115b3565b61036e565b610148610424565b60405161010f9291906119c5565b610169610164366004611818565b61043d565b604051901515815260200161010f565b600a546001600160a01b03165b6040516001600160a01b03909116815260200161010f565b6101866101ac366004611574565b61049d565b6101696101bf366004611574565b610521565b6101866101d2366004611574565b6105d1565b6101ea6101e5366004611574565b610616565b60405161010f9190611b6f565b61012b610205366004611848565b6106ff565b61012b610218366004611574565b6107d7565b61012b61022b366004611623565b61088c565b6040516003815260200161010f565b61012b61024d3660046117e0565b610921565b606061025f600b54610ac0565b905090565b60408051808201909152600a815269149154d5149250d5115160b21b60208281019190915260005490916102a5916001600160a01b03169033908490610bc3565b6001600160a01b0382166102f05760405162461bcd60e51b815260206004820152600d60248201526c3ab735b737bbb7103a37b5b2b760991b60448201526064015b60405180910390fd5b61036a82836001600160a01b031663b16a19de6040518163ffffffff1660e01b815260040160206040518083038186803b15801561032d57600080fd5b505afa158015610341573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103659190611597565b610bed565b5050565b60408051808201909152600a815269149154d5149250d5115160b21b60208281019190915260005490916103af916001600160a01b03169033908490610bc3565b815b801561041e57806103c181611df0565b9150506000600960008686858181106103ea57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906103ff9190611574565b6001600160a01b031681526020810191909152604001600020556103b1565b50505050565b606060006104326000610ac0565b600b54915091509091565b60408051808201909152600a815269149154d5149250d5115160b21b60208281019190915260008054909261047f916001600160a01b03169033908490610bc3565b61049461048d846001611d95565b6000610d59565b91505b50919050565b600a546040516310270e3d60e11b81526001600160a01b038381166004830152600092169063204e1c7a9060240160206040518083038186803b1580156104e357600080fd5b505afa1580156104f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051b9190611597565b92915050565b60408051808201909152600a815269149154d5149250d5115160b21b602082810191909152600080549092610563916001600160a01b03169033908490610bc3565b6001600160a01b0383166105ae5760405162461bcd60e51b8152602060048201526012602482015271756e6b6e6f776e20756e6465726c79696e6760701b60448201526064016102e7565b6001600160a01b0383166000908152600960205260409020546104949084610d59565b6001600160a01b038116600090815260096020526040812054806105f85750600092915050565b6000908152600760205260409020546001600160a01b031692915050565b6040805160808082018352600080835260606020808501829052848601829052855160e08101875283815290810183905294850182905284810182905291840181905260a0840181905260c0840152810191909152816001600160a01b03166326cc73a46040518163ffffffff1660e01b815260040160006040518083038186803b1580156106a457600080fd5b505afa1580156106b8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106e091908101906116e5565b6040840152602083015260608201526001600160a01b03909116815290565b60408051808201909152600a815269149154d5149250d5115160b21b6020828101919091526000549091610740916001600160a01b03169033908490610bc3565b60015b600854811161041e576000818152600760205260409081902054905163034d53c960e61b815263ffffffff8087166004830152851660248201526001600160a01b039091169063d354f24090604401600060405180830381600087803b1580156107ac57600080fd5b505af11580156107c0573d6000803e3d6000fd5b5050505080806107cf90611e07565b915050610743565b600360008060006107e784610e1b565b92509250925080610875576002849055600080546001600160a01b0319166001600160a01b0387811691909117909155600a541661086f5760405161082b90611378565b604051809103906000f080158015610847573d6000803e3d6000fd5b50600a80546001600160a01b0319166001600160a01b0392909216919091179055600854600b555b60018490555b8161088557600183905560006002555b5050505050565b60408051808201909152600a815269149154d5149250d5115160b21b60208281019190915260005490916108cd916001600160a01b03169033908490610bc3565b60005b825181101561091c576109098382815181106108fc57634e487b7160e01b600052603260045260246000fd5b6020026020010151611093565b508061091481611e07565b9150506108d0565b505050565b60408051808201909152600a815269149154d5149250d5115160b21b6020828101919091526000549091610962916001600160a01b03169033908490610bc3565b60006109746101e56020850185611574565b606081015190915060009063029cc27560e31b906109956040870187611c5e565b6109a26060890189611c5e565b6040516024016109b6959493929190611aeb565b60408051601f19818403018152919052602080820180516001600160e01b03166001600160e01b031990941693909317909252600a549092506001600160a01b031690639623609d90610a0b90870187611574565b610a1b6040880160208901611574565b846040518463ffffffff1660e01b8152600401610a3a9392919061197d565b600060405180830381600087803b158015610a5457600080fd5b505af1158015610a68573d6000803e3d6000fd5b50610a7a925050506020850185611574565b6001600160a01b03167f73fbc15c12587628a9b73620b8c8344925a246233d8a913f2648074eb659801e85604051610ab29190611bd9565b60405180910390a250505050565b60608160085411610ad057919050565b81600854610ade9190611dad565b67ffffffffffffffff811115610b0457634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610b2d578160200160208202803683370190505b50905081610b3a81611e07565b92505060005b81518110156104975760076000610b578584611d95565b815260200190815260200160002060009054906101000a90046001600160a01b0316828281518110610b9957634e487b7160e01b600052603260045260246000fd5b6001600160a01b039092166020928302919091019091015280610bbb81611e07565b915050610b40565b610bce8484846112d1565b81906108855760405162461bcd60e51b81526004016102e791906119e7565b6001600160a01b038216610c335760405162461bcd60e51b815260206004820152600d60248201526c3ab735b737bbb7103a37b5b2b760991b60448201526064016102e7565b6001600160a01b038116610c7e5760405162461bcd60e51b8152602060048201526012602482015271756e6b6e6f776e20756e6465726c79696e6760701b60448201526064016102e7565b6000610c89826105d1565b6001600160a01b031614610cd65760405162461bcd60e51b8152602060048201526014602482015273616d626967756f757320756e6465726c79696e6760601b60448201526064016102e7565b60088054906000610ce683611e07565b909155505060088054600090815260076020908152604080832080546001600160a01b0319166001600160a01b038881169182179092559454908616808552600990935281842055519092917f8a52a82e364afc632091797d755ced6da40de72c9a0ce9cdd85e7519036fd01b91a35050565b6000821580610d7d57506000838152600760205260409020546001600160a01b0316155b15610d8a5750600061051b565b6000838152600760205260408082205490516001600160a01b03808616939216917f1bb2e84515df1bee0c5326e6dd3cc5f17229f9bc9e7ca060c8b7ecc76e12aafc91a3600083815260076020526040902080546001600160a01b03191690556001600160a01b038216610e12576001600160a01b0382166000908152600960205260408120555b50600192915050565b6003600080610e2d6001600019611dad565b8310610e7b5760405162461bcd60e51b815260206004820152601960248201527f696e76616c696420636f6e7472616374207265766973696f6e0000000000000060448201526064016102e7565b60008411610ecb5760405162461bcd60e51b815260206004820152601e60248201527f696e636f727265637420696e697469616c697a6572207265766973696f6e000060448201526064016102e7565b82841115610f1b5760405162461bcd60e51b815260206004820152601e60248201527f696e636f6e73697374656e7420636f6e7472616374207265766973696f6e000060448201526064016102e7565b610f286001600019611dad565b6001541015610fa4576000600254118015610f44575082600154105b91508180610f515750303b155b80610f5d575060015483115b610f9f5760405162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016102e7565b611014565b610fb16001600019611dad565b600154148015610fc05750303b155b6110025760405162461bcd60e51b81526020600482015260136024820152721a5b9a5d1a585b1a5e995c88189b1bd8dad959606a1b60448201526064016102e7565b60006001556002546000199350151591505b811561106b57836002541161106b5760405162461bcd60e51b815260206004820152601f60248201527f696e636f7272656374206f72646572206f6620696e697469616c697a6572730060448201526064016102e7565b60015484116110885781156110805760016002555b50600161108c565b5060005b9193909250565b6000806040518060e0016040528060008054906101000a90046001600160a01b03166001600160a01b0316815260200184602001516001600160a01b0316815260200184604001516001600160a01b031681526020018460a0015163ffffffff1681526020018460c0015163ffffffff1681526020018460e0015161ffff16815260200184610100015160ff16815250905060006314e613a860e01b828560600151866080015160405160240161114c93929190611b2f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600054600a5487519351633eba8a9760e11b81529294506001600160a01b0391821693637d75152e936111ba939290921691869060040161197d565b602060405180830381600087803b1580156111d457600080fd5b505af11580156111e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120c9190611597565b92508361012001511561127b5760208401516040516314b31be760e11b81526001600160a01b0385811660048301529091169063296637ce90602401600060405180830381600087803b15801561126257600080fd5b505af1158015611276573d6000803e3d6000fd5b505050505b826001600160a01b03167f9aa34738f5695809e68b6ff39406c2e7246909c8cb7bce7455ae70273665bcd2856040516112b491906119fa565b60405180910390a26112ca838560200151610bed565b5050919050565b6000806112df8585856112ec565b9092161515949350505050565b60405163cc8b29c160e01b81526001600160a01b038381166004830152602482018390526000919085169063cc8b29c19060440160206040518083038186803b15801561133857600080fd5b505afa15801561134c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113709190611830565b949350505050565b61048c80611e9883390190565b803561139081611e4e565b919050565b8035801515811461139057600080fd5b600082601f8301126113b5578081fd5b81356113c86113c382611d28565b611cf7565b8181528460208386010111156113dc578283fd5b816020850160208301379081016020019190915292915050565b600082601f830112611406578081fd5b81516114146113c382611d28565b818152846020838601011115611428578283fd5b611370826020830160208701611dc4565b6000610140828403121561144b578081fd5b611453611caa565b905061145e82611385565b815261146c60208301611385565b602082015261147d60408301611385565b6040820152606082013567ffffffffffffffff8082111561149d57600080fd5b6114a9858386016113a5565b606084015260808401359150808211156114c257600080fd5b506114cf848285016113a5565b6080830152506114e160a08301611548565b60a08201526114f260c08301611548565b60c082015261150360e08301611532565b60e082015261010061151681840161155e565b90820152610120611528838201611395565b9082015292915050565b803561139081611e66565b805161139081611e66565b803561139081611e76565b805161139081611e76565b803561139081611e88565b805161139081611e88565b600060208284031215611585578081fd5b813561159081611e4e565b9392505050565b6000602082840312156115a8578081fd5b815161159081611e4e565b600080602083850312156115c5578081fd5b823567ffffffffffffffff808211156115dc578283fd5b818501915085601f8301126115ef578283fd5b8135818111156115fd578384fd5b8660208260051b8501011115611611578384fd5b60209290920196919550909350505050565b60006020808385031215611635578182fd5b823567ffffffffffffffff8082111561164c578384fd5b818501915085601f83011261165f578384fd5b81358181111561167157611671611e38565b8060051b611680858201611cf7565b8281528581019085870183870188018b101561169a578889fd5b8893505b848410156116d7578035868111156116b457898afd5b6116c28c8a838b0101611439565b8452506001939093019291870191870161169e565b509998505050505050505050565b60008060008385036101208112156116fb578182fd5b60e0811215611708578182fd5b50611711611cd4565b845161171c81611e4e565b8152602085015161172c81611e4e565b6020820152604085015161173f81611e4e565b6040820152606085015161175281611e76565b606082015261176360808601611553565b608082015261177460a0860161153d565b60a082015261178560c08601611569565b60c082015260e085015190935067ffffffffffffffff808211156117a7578283fd5b6117b3878388016113f6565b93506101008601519150808211156117c9578283fd5b506117d6868287016113f6565b9150509250925092565b6000602082840312156117f1578081fd5b813567ffffffffffffffff811115611807578182fd5b820160808185031215611590578182fd5b600060208284031215611829578081fd5b5035919050565b600060208284031215611841578081fd5b5051919050565b6000806040838503121561185a578182fd5b823561186581611e76565b9150602083013561187581611e76565b809150509250929050565b6000815180845260208085019450808401835b838110156118b85781516001600160a01b031687529582019590820190600101611893565b509495945050505050565b600081518084526118db816020860160208601611dc4565b601f01601f19169290920160200192915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b0380825116835280602083015116602084015280604083015116604084015250606081015163ffffffff8082166060850152806080840151166080850152505061ffff60a08201511660a083015260ff60c08201511660c08301525050565b6001600160a01b038481168252831660208201526060604082018190526000906119a9908301846118c3565b95945050505050565b6020815260006115906020830184611880565b6040815260006119d86040830185611880565b90508260208301529392505050565b60208152600061159060208301846118c3565b60208152611a146020820183516001600160a01b03169052565b60006020830151611a3060408401826001600160a01b03169052565b5060408301516001600160a01b0381166060840152506060830151610140806080850152611a626101608501836118c3565b91506080850151601f198584030160a0860152611a7f83826118c3565b92505060a0850151611a9960c086018263ffffffff169052565b5060c085015163ffffffff811660e08601525060e0850151610100611ac38187018361ffff169052565b8601519050610120611ad98682018360ff169052565b90950151151593019290925250919050565b6000610120611afa8389611918565b8060e0840152611b0d81840187896118ef565b9050828103610100840152611b238185876118ef565b98975050505050505050565b6000610120611b3e8387611918565b8060e0840152611b50818401866118c3565b9050828103610100840152611b6581856118c3565b9695505050505050565b602080825282516001600160a01b0316828201528201516101406040830152600090611b9f6101608401826118c3565b90506040840151601f19848303016060850152611bbc82826118c3565b9150506060840151611bd16080850182611918565b509392505050565b6020815260008235611bea81611e4e565b6001600160a01b0390811660208481019190915284013590611c0b82611e4e565b80821660408501525050611c226040840184611d50565b60806060850152611c3760a0850182846118ef565b915050611c476060850185611d50565b848303601f19016080860152611b658382846118ef565b6000808335601e19843603018112611c74578283fd5b83018035915067ffffffffffffffff821115611c8e578283fd5b602001915036819003821315611ca357600080fd5b9250929050565b604051610140810167ffffffffffffffff81118282101715611cce57611cce611e38565b60405290565b60405160e0810167ffffffffffffffff81118282101715611cce57611cce611e38565b604051601f8201601f1916810167ffffffffffffffff81118282101715611d2057611d20611e38565b604052919050565b600067ffffffffffffffff821115611d4257611d42611e38565b50601f01601f191660200190565b6000808335601e19843603018112611d66578283fd5b830160208101925035905067ffffffffffffffff811115611d8657600080fd5b803603831315611ca357600080fd5b60008219821115611da857611da8611e22565b500190565b600082821015611dbf57611dbf611e22565b500390565b60005b83811015611ddf578181015183820152602001611dc7565b8381111561041e5750506000910152565b600081611dff57611dff611e22565b506000190190565b6000600019821415611e1b57611e1b611e22565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611e6357600080fd5b50565b61ffff81168114611e6357600080fd5b63ffffffff81168114611e6357600080fd5b60ff81168114611e6357600080fdfe60a060405234801561001057600080fd5b5033606081901b608052610455610037600039600081816084015260da01526104556000f3fe6080604052600436106100345760003560e01c8063204e1c7a146100395780638da5cb5b146100755780639623609d146100a8575b600080fd5b34801561004557600080fd5b5061005961005436600461025f565b6100bd565b6040516001600160a01b03909116815260200160405180910390f35b34801561008157600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610059565b6100bb6100b636600461027b565b6100ce565b005b60006100c8826101ab565b92915050565b336001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146040518060600160405280602381526020016103fd60239139906101435760405162461bcd60e51b815260040161013a91906103bb565b60405180910390fd5b5060405163278f794360e11b81526001600160a01b03841690634f1ef2869034906101749086908690600401610397565b6000604051808303818588803b15801561018d57600080fd5b505af11580156101a1573d6000803e3d6000fd5b5050505050505050565b6000806000836001600160a01b03166040516101d190635c60da1b60e01b815260040190565b600060405180830381855afa9150503d806000811461020c576040519150601f19603f3d011682016040523d82523d6000602084013e610211565b606091505b50915091508161022057600080fd5b80806020019051810190610234919061023c565b949350505050565b60006020828403121561024d578081fd5b8151610258816103e4565b9392505050565b600060208284031215610270578081fd5b8135610258816103e4565b60008060006060848603121561028f578182fd5b833561029a816103e4565b925060208401356102aa816103e4565b9150604084013567ffffffffffffffff808211156102c6578283fd5b818601915086601f8301126102d9578283fd5b8135818111156102eb576102eb6103ce565b604051601f8201601f19908116603f01168101908382118183101715610313576103136103ce565b8160405282815289602084870101111561032b578586fd5b82602086016020830137856020848301015280955050505050509250925092565b60008151808452815b8181101561037157602081850181015186830182015201610355565b818111156103825782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b03831681526040602082018190526000906102349083018461034c565b602081526000610258602083018461034c565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146103f957600080fd5b5056fe50726f78794f776e65723a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220fce73874609aee182d8e44606007c0b6b6f18a996714ca0d4b1d33977d30a0d864736f6c63430008040033a26469706673582212203d3d9944ac36fedb479dda9707a1f4d043df3fc5fbcf21d48386f4a732ff273664736f6c63430008040033

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.