false
true
0

Contract Address Details

0x00e1351708150A43086c3EEEb99535b28D9b4405

Contract Name
UiStakeDataProvider
Creator
0x64e7ff–1c04a3 at 0x3e640a–0a7753
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
1 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
27876729
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
UiStakeDataProvider




Optimization enabled
true
Compiler version
v0.7.6+commit.7338295f




Optimization runs
200
EVM Version
istanbul




Verified at
2023-07-17T00:37:10.926332Z

Constructor Arguments

0x0000000000000000000000007f9d7476e6a2561fa011aa788979234de80900f7000000000000000000000000c14b5de7fbdff428f64aa9e7e240ea342ee9a3a30000000000000000000000009663c2d75ffd5f4017310405fce61720af45b829

Arg [0] (address) : 0x7f9d7476e6a2561fa011aa788979234de80900f7
Arg [1] (address) : 0xc14b5de7fbdff428f64aa9e7e240ea342ee9a3a3
Arg [2] (address) : 0x9663c2d75ffd5f4017310405fce61720af45b829

              

contracts/misc/UiStakeDataProvider.sol

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import "../dependencies/openzeppelin/contracts/SafeMath.sol";
import "../dependencies/openzeppelin/contracts/IERC20Metadata.sol";

import "../interfaces/IPriceOracleGetter.sol";
import "../interfaces/ILendingPool.sol";
import "../interfaces/IPhiatFeeDistribution.sol";
import "./interfaces/IUiStakeDataProvider.sol";

contract UiStakeDataProvider is IUiStakeDataProvider {
    using SafeMath for uint256;

    IPriceOracleGetter public immutable oracle;
    ILendingPool public immutable pool;

    mapping(address => address) private _aTokenMapping;

    constructor(IPriceOracleGetter oracle_, ILendingPool pool_, address phux) {
        oracle = oracle_;
        pool = pool_;
        _aTokenMapping[phux] = phux;
    }

    function updateTokenMapping() public {
        address[] memory reserves = pool.getReservesList();
        for (uint256 i = 0; i < reserves.length; i++) {
            DataTypes.ReserveData memory reserveData = pool.getReserveData(
                reserves[i]
            );
            _aTokenMapping[reserveData.aTokenAddress] = reserves[i];
        }
    }

    function getStakingData(
        IPhiatFeeDistribution feeDistributor
    ) public view override returns (StakingData memory data) {
        data.stakingToken = address(feeDistributor.stakingToken());
        data.totalSupply = feeDistributor.totalSupply();
        data.totalStakedSupply = feeDistributor.totalStakedSupply();
        data.stakingTokenPrecision = feeDistributor.stakingTokenPrecision();
        data.rewardDuration = feeDistributor.REWARD_DURATION();
        data.unstakeDuration = feeDistributor.UNSTAKE_DURATION();
        data.withdrawDuration = feeDistributor.WITHDRAW_DURATION();

        data.rewardsPerToken = feeDistributor.claimableRewards(address(0));
        uint256 durationRewardsInPls = 0;
        for (uint256 i = 0; i < data.rewardsPerToken.length; i++) {
            uint256 rewardAmount = feeDistributor.getRewardForDuration(
                data.rewardsPerToken[i].token
            );
            durationRewardsInPls = durationRewardsInPls.add(
                _getEquivalentPls(
                    _aTokenMapping[data.rewardsPerToken[i].token],
                    rewardAmount
                )
            );
            data.rewardsPerToken[i].amount = rewardAmount
                .mul(data.stakingTokenPrecision)
                .div(data.totalSupply);
        }
        uint256 stakingTokenTotalSupplyInPls = _getEquivalentPls(
            data.stakingToken,
            data.totalSupply
        );
        if (stakingTokenTotalSupplyInPls > 0) {
            data.rewardDurationReturn = durationRewardsInPls.mul(1e18).div(
                stakingTokenTotalSupplyInPls
            );
        }
    }

    function getStakingUserData(
        IPhiatFeeDistribution feeDistributor,
        address user
    )
        external
        view
        override
        returns (StakingData memory data, UserStakingData memory userData)
    {
        data = getStakingData(feeDistributor);

        userData.walletBalance = feeDistributor.stakingToken().balanceOf(user);
        userData.stakedBalance = feeDistributor.stakedBalance(user);
        IPhiatFeeDistribution.TimedBalance memory balance = feeDistributor
            .unstakedBalance(user);
        userData.unstakedBalance = balance.amount;
        userData.withdrawTimestamp = balance.time;
        balance = feeDistributor.withdrawableBalance(user);
        userData.withdrawableBalance = balance.amount;
        userData.expirationTimestamp = balance.time;
        userData.claimableRewards = feeDistributor.claimableRewards(user);
    }

    function _getEquivalentPls(
        address targetToken,
        uint256 amount
    ) private view returns (uint256 plsAmount) {
        plsAmount = amount.mul(oracle.getAssetPrice(targetToken)).div(
            10 ** IERC20Metadata(targetToken).decimals()
        );
    }
}
        

contracts/dependencies/openzeppelin/contracts/IERC20.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

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

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    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
     *
     * Emits an {Approval} event.
     */
    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.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

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

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

contracts/dependencies/openzeppelin/contracts/IERC20Capped.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./IERC20Metadata.sol";

/**
 * @dev Extension of {ERC20} that adds a cap to the supply of tokens.
 */
interface IERC20Capped is IERC20Metadata {
    /**
     * @dev Returns the cap on the token's total supply.
     */
    function cap() external view returns (uint256);
}
          

contracts/dependencies/openzeppelin/contracts/IERC20Metadata.sol

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

pragma solidity 0.7.6;

import "./IERC20.sol";

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

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

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

contracts/dependencies/openzeppelin/contracts/SafeMath.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}
          

contracts/interfaces/ILendingPool.sol

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import {ILendingPoolAddressesProvider} from "./ILendingPoolAddressesProvider.sol";
import {DataTypes} from "../protocol/libraries/types/DataTypes.sol";

interface ILendingPool {
    /**
     * @dev Emitted on deposit()
     * @param reserve The address of the underlying asset of the reserve
     * @param user The address initiating the deposit
     * @param onBehalfOf The beneficiary of the deposit, receiving the aTokens
     * @param amount The amount deposited
     * @param referral The referral code used
     **/
    event Deposit(
        address indexed reserve,
        address user,
        address indexed onBehalfOf,
        uint256 amount,
        uint16 indexed referral
    );

    /**
     * @dev Emitted on withdraw()
     * @param reserve The address of the underlyng asset being withdrawn
     * @param user The address initiating the withdrawal, owner of aTokens
     * @param to Address that will receive the underlying
     * @param amount The amount to be withdrawn
     **/
    event Withdraw(
        address indexed reserve,
        address indexed user,
        address indexed to,
        uint256 amount
    );

    /**
     * @dev Emitted on borrow() and flashLoan() when debt needs to be opened
     * @param reserve The address of the underlying asset being borrowed
     * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just
     * initiator of the transaction on flashLoan()
     * @param onBehalfOf The address that will be getting the debt
     * @param amount The amount borrowed out
     * @param borrowRateMode The rate mode: 1 for Stable, 2 for Variable
     * @param borrowRate The numeric rate at which the user has borrowed
     * @param referral The referral code used
     **/
    event Borrow(
        address indexed reserve,
        address user,
        address indexed onBehalfOf,
        uint256 amount,
        uint256 borrowRateMode,
        uint256 borrowRate,
        uint16 indexed referral
    );

    /**
     * @dev Emitted on repay()
     * @param reserve The address of the underlying asset of the reserve
     * @param user The beneficiary of the repayment, getting his debt reduced
     * @param repayer The address of the user initiating the repay(), providing the funds
     * @param amount The amount repaid
     **/
    event Repay(
        address indexed reserve,
        address indexed user,
        address indexed repayer,
        uint256 amount
    );

    /**
     * @dev Emitted on swapBorrowRateMode()
     * @param reserve The address of the underlying asset of the reserve
     * @param user The address of the user swapping his rate mode
     * @param rateMode The rate mode that the user wants to swap to
     **/
    event Swap(address indexed reserve, address indexed user, uint256 rateMode);

    /**
     * @dev Emitted on setUserUseReserveAsCollateral()
     * @param reserve The address of the underlying asset of the reserve
     * @param user The address of the user enabling the usage as collateral
     **/
    event ReserveUsedAsCollateralEnabled(
        address indexed reserve,
        address indexed user
    );

    /**
     * @dev Emitted on setUserUseReserveAsCollateral()
     * @param reserve The address of the underlying asset of the reserve
     * @param user The address of the user enabling the usage as collateral
     **/
    event ReserveUsedAsCollateralDisabled(
        address indexed reserve,
        address indexed user
    );

    /**
     * @dev Emitted on rebalanceStableBorrowRate()
     * @param reserve The address of the underlying asset of the reserve
     * @param user The address of the user for which the rebalance has been executed
     **/
    event RebalanceStableBorrowRate(
        address indexed reserve,
        address indexed user
    );

    /**
     * @dev Emitted on flashLoan()
     * @param target The address of the flash loan receiver contract
     * @param initiator The address initiating the flash loan
     * @param asset The address of the asset being flash borrowed
     * @param amount The amount flash borrowed
     * @param premium The fee flash borrowed
     * @param referralCode The referral code used
     **/
    event FlashLoan(
        address indexed target,
        address indexed initiator,
        address indexed asset,
        uint256 amount,
        uint256 premium,
        uint16 referralCode
    );

    /**
     * @dev Emitted when the pause is triggered.
     */
    event Paused();

    /**
     * @dev Emitted when the pause is lifted.
     */
    event Unpaused();

    /**
     * @dev Emitted when a borrower is liquidated. This event is emitted by the LendingPool via
     * LendingPoolCollateral manager using a DELEGATECALL
     * This allows to have the events in the generated ABI for LendingPool.
     * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
     * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
     * @param user The address of the borrower getting liquidated
     * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
     * @param liquidatedCollateralAmount The amount of collateral received by the liiquidator
     * @param liquidator The address of the liquidator
     * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants
     * to receive the underlying collateral asset directly
     **/
    event LiquidationCall(
        address indexed collateralAsset,
        address indexed debtAsset,
        address indexed user,
        uint256 debtToCover,
        uint256 liquidatedCollateralAmount,
        address liquidator,
        bool receiveAToken
    );

    /**
     * @dev Emitted when a borrower is blacklisted.
     * @param user The address of the borrower getting liquidated
     **/
    event Blacklist(address indexed user);

    /**
     * @dev Emitted when the state of a reserve is updated. NOTE: This event is actually declared
     * in the ReserveLogic library and emitted in the updateInterestRates() function. Since the function is internal,
     * the event will actually be fired by the LendingPool contract. The event is therefore replicated here so it
     * gets added to the LendingPool ABI
     * @param reserve The address of the underlying asset of the reserve
     * @param liquidityRate The new liquidity rate
     * @param stableBorrowRate The new stable borrow rate
     * @param variableBorrowRate The new variable borrow rate
     * @param liquidityIndex The new liquidity index
     * @param variableBorrowIndex The new variable borrow index
     **/
    event ReserveDataUpdated(
        address indexed reserve,
        uint256 liquidityRate,
        uint256 stableBorrowRate,
        uint256 variableBorrowRate,
        uint256 liquidityIndex,
        uint256 variableBorrowIndex
    );

    function isBlacklisted(address user) external returns (bool);

    /**
     * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
     * - E.g. User deposits 100 USDC and gets in return 100 aUSDC
     * @param asset The address of the underlying asset to deposit
     * @param amount The amount to be deposited
     * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
     *   wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
     *   is a different wallet
     * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
     *   0 if the action is executed directly by the user, without any middle-man
     **/
    function deposit(
        address asset,
        uint256 amount,
        address onBehalfOf,
        uint16 referralCode
    ) external;

    /**
     * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
     * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
     * @param asset The address of the underlying asset to withdraw
     * @param amount The underlying amount to be withdrawn
     *   - Send the value type(uint256).max in order to withdraw the whole aToken balance
     * @param to Address that will receive the underlying, same as msg.sender if the user
     *   wants to receive it on his own wallet, or a different address if the beneficiary is a
     *   different wallet
     * @return The final amount withdrawn
     **/
    function withdraw(
        address asset,
        uint256 amount,
        address to
    ) external returns (uint256);

    /**
     * @dev Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower
     * already deposited enough collateral, or he was given enough allowance by a credit delegator on the
     * corresponding debt token (StableDebtToken or VariableDebtToken)
     * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
     *   and 100 stable/variable debt tokens, depending on the `interestRateMode`
     * @param asset The address of the underlying asset to borrow
     * @param amount The amount to be borrowed
     * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable
     * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
     *   0 if the action is executed directly by the user, without any middle-man
     * @param onBehalfOf Address of the user who will receive the debt. Should be the address of the borrower itself
     * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator
     * if he has been given credit delegation allowance
     **/
    function borrow(
        address asset,
        uint256 amount,
        uint256 interestRateMode,
        uint16 referralCode,
        address onBehalfOf
    ) external;

    /**
     * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned
     * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address
     * @param asset The address of the borrowed underlying asset previously borrowed
     * @param amount The amount to repay
     * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
     * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
     * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the
     * user calling the function if he wants to reduce/remove his own debt, or the address of any other
     * other borrower whose debt should be removed
     * @return The final amount repaid
     **/
    function repay(
        address asset,
        uint256 amount,
        uint256 rateMode,
        address onBehalfOf
    ) external returns (uint256);

    /**
     * @notice Repay all debts of the user and blacklist that user.
     * @param user Address of the user who will get his debt removed. Should be the address of the
     * user calling the function if he wants to reduce/remove his own debt, or the address of any other
     * other borrower whose debt should be removed
     **/
    function repayAllAndBlacklist(address user) external;

    /**
     * @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa
     * @param asset The address of the underlying asset borrowed
     * @param rateMode The rate mode that the user wants to swap to
     **/
    function swapBorrowRateMode(address asset, uint256 rateMode) external;

    /**
     * @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve.
     * - Users can be rebalanced if the following conditions are satisfied:
     *     1. Usage ratio is above 95%
     *     2. the current deposit APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too much has been
     *        borrowed at a stable rate and depositors are not earning enough
     * @param asset The address of the underlying asset borrowed
     * @param user The address of the user to be rebalanced
     **/
    function rebalanceStableBorrowRate(address asset, address user) external;

    /**
     * @dev Allows depositors to enable/disable a specific deposited asset as collateral
     * @param asset The address of the underlying asset deposited
     * @param useAsCollateral `true` if the user wants to use the deposit as collateral, `false` otherwise
     **/
    function setUserUseReserveAsCollateral(address asset, bool useAsCollateral)
        external;

    /**
     * @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1
     * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
     *   a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
     * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
     * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
     * @param user The address of the borrower getting liquidated
     * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
     * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants
     * to receive the underlying collateral asset directly
     **/
    function liquidationCall(
        address collateralAsset,
        address debtAsset,
        address user,
        uint256 debtToCover,
        bool receiveAToken
    ) external;

    /**
     * @dev Allows smartcontracts to access the liquidity of the pool within one transaction,
     * as long as the amount taken plus a fee is returned.
     * IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept into consideration.
     * For further details please visit https://developers.aave.com
     * @param receiverAddress The address of the contract receiving the funds, implementing the IFlashLoanReceiver interface
     * @param assets The addresses of the assets being flash-borrowed
     * @param amounts The amounts amounts being flash-borrowed
     * @param params Variadic packed params to pass to the receiver as extra information
     * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
     *   0 if the action is executed directly by the user, without any middle-man
     **/
    function flashLoan(
        address receiverAddress,
        address[] calldata assets,
        uint256[] calldata amounts,
        bytes calldata params,
        uint16 referralCode
    ) external;

    /**
     * @dev Returns the user account data across all the reserves
     * @param user The address of the user
     * @return totalCollateralETH the total collateral in ETH of the user
     * @return totalDebtETH the total debt in ETH of the user
     * @return availableBorrowsETH the borrowing power left of the user
     * @return currentLiquidationThreshold the liquidation threshold of the user
     * @return ltv the loan to value of the user
     * @return healthFactor the current health factor of the user
     **/
    function getUserAccountData(address user)
        external
        view
        returns (
            uint256 totalCollateralETH,
            uint256 totalDebtETH,
            uint256 availableBorrowsETH,
            uint256 currentLiquidationThreshold,
            uint256 ltv,
            uint256 healthFactor
        );

    function initReserve(
        address reserve,
        address aTokenAddress,
        address stableDebtAddress,
        address variableDebtAddress,
        address interestRateStrategyAddress
    ) external;

    function setReserveInterestRateStrategyAddress(
        address reserve,
        address rateStrategyAddress
    ) external;

    function setConfiguration(address reserve, uint256 configuration) external;

    function setLimits(
        address reserve,
        DataTypes.ReserveLimits calldata reserveLimits
    ) external;

    /**
     * @dev Returns the configuration of the reserve
     * @param asset The address of the underlying asset of the reserve
     * @return The configuration of the reserve
     **/
    function getConfiguration(address asset)
        external
        view
        returns (DataTypes.ReserveConfigurationMap memory);

    /**
     * @dev Returns the configuration of the user across all the reserves
     * @param user The user address
     * @return The configuration of the user
     **/
    function getUserConfiguration(address user)
        external
        view
        returns (DataTypes.UserConfigurationMap memory);

    /**
     * @dev Returns the normalized income normalized income of the reserve
     * @param asset The address of the underlying asset of the reserve
     * @return The reserve's normalized income
     */
    function getReserveNormalizedIncome(address asset)
        external
        view
        returns (uint256);

    /**
     * @dev Returns the normalized variable debt per unit of asset
     * @param asset The address of the underlying asset of the reserve
     * @return The reserve normalized variable debt
     */
    function getReserveNormalizedVariableDebt(address asset)
        external
        view
        returns (uint256);

    /**
     * @dev Returns the state and configuration of the reserve
     * @param asset The address of the underlying asset of the reserve
     * @return The state of the reserve
     **/
    function getReserveData(address asset)
        external
        view
        returns (DataTypes.ReserveData memory);

    /**
     * @dev Returns the limits of the reserve
     * @param asset The address of the underlying asset of the reserve
     * @return The limits of the reserve
     **/
    function getReserveLimits(address asset)
        external
        view
        returns (DataTypes.ReserveLimits memory);

    function finalizeTransfer(
        address asset,
        address from,
        address to,
        uint256 amount,
        uint256 balanceFromAfter,
        uint256 balanceToBefore
    ) external;

    function getReservesList() external view returns (address[] memory);

    function getAddressesProvider()
        external
        view
        returns (ILendingPoolAddressesProvider);

    function setPause(bool val) external;

    function paused() external view returns (bool);

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

contracts/interfaces/ILendingPoolAddressesProvider.sol

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.6;

/**
 * @title LendingPoolAddressesProvider contract
 * @dev Main registry of addresses part of or connected to the protocol, including permissioned roles
 * - Acting also as factory of proxies and admin of those, so with right to change its implementations
 * - Owned by the Aave Governance
 * @author Aave
 **/
interface ILendingPoolAddressesProvider {
    event MarketIdSet(string newMarketId);
    event LendingPoolUpdated(address indexed newAddress);
    event ConfigurationAdminUpdated(address indexed newAddress);
    event EmergencyAdminUpdated(address indexed newAddress);
    event LendingPoolConfiguratorUpdated(address indexed newAddress);
    event LendingPoolCollateralManagerUpdated(address indexed newAddress);
    event PriceOracleUpdated(address indexed newAddress);
    event LendingRateOracleUpdated(address indexed newAddress);
    event IncentivesControllerUpdated(address indexed newAddress);
    event ProxyCreated(bytes32 id, address indexed newAddress);
    event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy);

    function getMarketId() external view returns (string memory);

    function setMarketId(string calldata marketId) external;

    function setAddress(bytes32 id, address newAddress) external;

    function setAddressAsProxy(bytes32 id, address impl) external;

    function getAddress(bytes32 id) external view returns (address);

    function getLendingPool() external view returns (address);

    function setLendingPoolImpl(address pool) external;

    function getLendingPoolConfigurator() external view returns (address);

    function setLendingPoolConfiguratorImpl(address configurator) external;

    function getLendingPoolCollateralManager() external view returns (address);

    function setLendingPoolCollateralManager(address manager) external;

    function getPoolAdmin() external view returns (address);

    function setPoolAdmin(address admin) external;

    function getEmergencyAdmin() external view returns (address);

    function setEmergencyAdmin(address admin) external;

    function getPriceOracle() external view returns (address);

    function setPriceOracle(address priceOracle) external;

    function getLendingRateOracle() external view returns (address);

    function setLendingRateOracle(address lendingRateOracle) external;

    function getIncentivesController() external view returns (address);

    function setIncentivesController(address lendingRateOracle) external;
}
          

contracts/interfaces/IPhiatFeeDistribution.sol

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.6;
pragma abicoder v2;

import "../dependencies/openzeppelin/contracts/IERC20Capped.sol";

interface IPhiatFeeDistribution {
    /* ========== STATE VARIABLES ========== */

    struct TokenReward {
        // updated via _getReward <- getReward
        uint256 periodFinish;
        // updated via _getReward <- getReward
        // every second how many rewards are accumulated for 1 wei
        // should divide by REWARD_RATE_PRECISION_ASSIST to get true reward rate
        uint256 rewardRate;
        // updated via _updateReward / _getReward <- stake / withdraw / getReward
        uint256 lastUpdateTime;
        // how much rewards have been accumulated so far
        // should divide by REWARD_RATE_PRECISION_ASSIST to get true reward
        // updated via _updateReward <- stake / withdraw / getReward
        uint256 rewardStored;
        // tracks already-added balances to handle accrued interest in phToken rewards
        // updated via _getReward <- getReward
        uint256 balance;
    }
    struct TimedBalance {
        uint256 amount;
        uint256 time; // when user can withdraw or unstaking expires
    }
    struct RewardAmount {
        address token;
        uint256 amount;
    }

    /* ========== EVENTS ========== */

    event Staked(address indexed user, uint256 amount);
    event Unstaked(address indexed user, uint256 amount);
    event UnstakeCancelled(address indexed user);
    event Withdrawn(address indexed user, uint256 receivedAmount);
    event RewardPaid(
        address indexed user,
        address indexed rewardToken,
        uint256 reward
    );

    function stakingToken() external view returns (IERC20Capped);

    function stakingTokenPrecision() external view returns (uint256);

    function totalSupply() external view returns (uint256);

    function totalStakedSupply() external view returns (uint256);

    function REWARD_DURATION() external view returns (uint256);

    function UNSTAKE_DURATION() external view returns (uint256);

    function WITHDRAW_DURATION() external view returns (uint256);

    function REWARD_RATE_PRECISION_ASSIST() external view returns (uint256);

    /* ========== REWARD VIEWS ========== */

    function lastTimeRewardApplicable(address tokenAddress)
        external
        view
        returns (uint256);

    // should divide by REWARD_RATE_PRECISION_ASSIST to get true reward per token
    // token's decimals are kept
    // staking token's decimals are removed
    function rewardPerToken(address tokenAddress)
        external
        view
        returns (uint256);

    function getRewardForDuration(address tokenAddress)
        external
        view
        returns (uint256);

    // Address and claimable amount of all reward tokens for the given account
    function claimableRewards(address account)
        external
        view
        returns (RewardAmount[] memory rewards);

    /* ========== STAKING VIEWS ========== */

    // Total staked balance of an account, including unstaked tokens that haven't been withdrawn
    function stakedBalance(address user) external view returns (uint256 amount);

    // Total unstaked balance for an account (in the process of unstaking)
    function unstakedBalance(address user)
        external
        view
        returns (TimedBalance memory balance);

    // Total withdrawable balance for an account
    function withdrawableBalance(address user)
        external
        view
        returns (TimedBalance memory balance);

    function getReward() external;
}
          

contracts/interfaces/IPriceOracleGetter.sol

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.6;

/**
 * @title IPriceOracleGetter interface
 * @notice Interface for the Aave price oracle.
 **/

interface IPriceOracleGetter {
    /**
     * @dev returns the asset price in ETH
     * @param asset the address of the asset
     * @return the ETH price of the asset
     **/
    function getAssetPrice(address asset) external view returns (uint256);
}
          

contracts/misc/interfaces/IUiStakeDataProvider.sol

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import "../../interfaces/IPhiatFeeDistribution.sol";

interface IUiStakeDataProvider {
    struct StakingData {
        address stakingToken;
        uint256 totalSupply;
        uint256 totalStakedSupply;
        uint256 stakingTokenPrecision;
        uint256 rewardDuration;
        uint256 unstakeDuration;
        uint256 withdrawDuration;
        IPhiatFeeDistribution.RewardAmount[] rewardsPerToken;
        uint256 rewardDurationReturn;
    }

    struct UserStakingData {
        uint256 walletBalance;
        uint256 stakedBalance;
        uint256 unstakedBalance;
        uint256 withdrawTimestamp;
        uint256 withdrawableBalance;
        uint256 expirationTimestamp;
        IPhiatFeeDistribution.RewardAmount[] claimableRewards;
    }

    function getStakingData(IPhiatFeeDistribution feeDistributor)
        external
        view
        returns (StakingData memory data);

    function getStakingUserData(
        IPhiatFeeDistribution feeDistributor,
        address user
    )
        external
        view
        returns (StakingData memory data, UserStakingData memory userData);
}
          

contracts/protocol/libraries/types/DataTypes.sol

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.6;

library DataTypes {
    // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
    struct ReserveData {
        //stores the reserve configuration
        ReserveConfigurationMap configuration;
        //the liquidity index. Expressed in ray
        uint128 liquidityIndex;
        //variable borrow index. Expressed in ray
        uint128 variableBorrowIndex;
        //the current supply rate. Expressed in ray
        uint128 currentLiquidityRate;
        //the current variable borrow rate. Expressed in ray
        uint128 currentVariableBorrowRate;
        //the current stable borrow rate. Expressed in ray
        uint128 currentStableBorrowRate;
        uint40 lastUpdateTimestamp;
        //tokens addresses
        address aTokenAddress;
        address stableDebtTokenAddress;
        address variableDebtTokenAddress;
        //address of the interest rate strategy
        address interestRateStrategyAddress;
        //the id of the reserve. Represents the position in the list of the active reserves
        uint8 id;
    }

    struct ReserveConfigurationMap {
        //bit 0-15: LTV
        //bit 16-31: Liq. threshold
        //bit 32-47: Liq. bonus
        //bit 48-55: Decimals
        //bit 56: Reserve is active
        //bit 57: reserve is frozen
        //bit 58: borrowing is enabled
        //bit 59: stable rate borrowing enabled
        //bit 60-63: reserved
        //bit 64-79: reserve factor
        uint256 data;
    }

    struct ReserveLimits {
        uint256 maxGlobalDepositSize;
        uint256 maxIndividualDepositSize;
        uint256 minIndividualDepositSize;
        uint256 maxGlobalBorrowSize;
        uint256 maxIndividualBorrowSize;
        uint256 maxBorrowBps;
    }

    struct UserConfigurationMap {
        uint256 data;
    }

    enum InterestRateMode {
        NONE,
        STABLE,
        VARIABLE
    }
}
          

Compiler Settings

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

Contract ABI

[{"type":"constructor","inputs":[{"type":"address","name":"oracle_","internalType":"contract IPriceOracleGetter"},{"type":"address","name":"pool_","internalType":"contract ILendingPool"},{"type":"address","name":"phux","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"data","internalType":"struct IUiStakeDataProvider.StakingData","components":[{"type":"address"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"tuple[]","components":[{"type":"address"},{"type":"uint256"}]},{"type":"uint256"}]}],"name":"getStakingData","inputs":[{"type":"address","name":"feeDistributor","internalType":"contract IPhiatFeeDistribution"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"data","internalType":"struct IUiStakeDataProvider.StakingData","components":[{"type":"address"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"tuple[]","components":[{"type":"address"},{"type":"uint256"}]},{"type":"uint256"}]},{"type":"tuple","name":"userData","internalType":"struct IUiStakeDataProvider.UserStakingData","components":[{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"tuple[]","components":[{"type":"address"},{"type":"uint256"}]}]}],"name":"getStakingUserData","inputs":[{"type":"address","name":"feeDistributor","internalType":"contract IPhiatFeeDistribution"},{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IPriceOracleGetter"}],"name":"oracle","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ILendingPool"}],"name":"pool","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateTokenMapping","inputs":[]}]
              

Contract Creation Code

0x60c06040523480156200001157600080fd5b506040516200155d3803806200155d83398101604081905262000034916200007d565b6001600160601b0319606093841b81166080529190921b1660a0526001600160a01b0316600081815260208190526040902080546001600160a01b0319169091179055620000e9565b60008060006060848603121562000092578283fd5b83516200009f81620000d0565b6020850151909350620000b281620000d0565b6040850151909250620000c581620000d0565b809150509250925092565b6001600160a01b0381168114620000e657600080fd5b50565b60805160601c60a05160601c61143c620001216000398060cf52806109c35280610a6852508061099d5280610bf0525061143c6000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806316f0115b1461005c57806367a7b5f61461007a5780636fec74b21461009a5780637dc0d1d0146100bb578063b914c5e2146100c3575b600080fd5b6100646100cd565b60405161007191906112f0565b60405180910390f35b61008d610088366004611069565b6100f1565b6040516100719190611304565b6100ad6100a8366004611085565b610660565b604051610071929190611317565b61006461099b565b6100cb6109bf565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b6100f9610dbb565b816001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b15801561013257600080fd5b505afa158015610146573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016a919061104d565b6001600160a01b039081168252604080516318160ddd60e01b81529051918416916318160ddd91600480820192602092909190829003018186803b1580156101b157600080fd5b505afa1580156101c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e991906111f5565b816020018181525050816001600160a01b031663bcdc3cfc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561022b57600080fd5b505afa15801561023f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026391906111f5565b816040018181525050816001600160a01b0316636746c7b16040518163ffffffff1660e01b815260040160206040518083038186803b1580156102a557600080fd5b505afa1580156102b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102dd91906111f5565b816060018181525050816001600160a01b0316635ade228a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561031f57600080fd5b505afa158015610333573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035791906111f5565b816080018181525050816001600160a01b03166328a9e1ff6040518163ffffffff1660e01b815260040160206040518083038186803b15801561039957600080fd5b505afa1580156103ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d191906111f5565b8160a0018181525050816001600160a01b031663779133226040518163ffffffff1660e01b815260040160206040518083038186803b15801561041357600080fd5b505afa158015610427573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061044b91906111f5565b60c082015260405163dc01f60d60e01b81526001600160a01b0383169063dc01f60d9061047d906000906004016112f0565b60006040518083038186803b15801561049557600080fd5b505afa1580156104a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526104d19190810190610f7c565b60e08201526000805b8260e001515181101561061f576000846001600160a01b031663bcd110148560e00151848151811061050857fe5b6020026020010151600001516040518263ffffffff1660e01b815260040161053091906112f0565b60206040518083038186803b15801561054857600080fd5b505afa15801561055c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058091906111f5565b90506105d16105ca6000808760e00151868151811061059b57fe5b602090810291909101810151516001600160a01b03908116835290820192909252604001600020541683610b6f565b8490610c98565b92506105f884602001516105f2866060015184610cfb90919063ffffffff16565b90610d54565b8460e00151838151811061060857fe5b6020908102919091018101510152506001016104da565b50600061063483600001518460200151610b6f565b9050801561065957610652816105f284670de0b6b3a7640000610cfb565b6101008401525b5050919050565b610668610dbb565b610670610e10565b610679846100f1565b9150836001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b1580156106b457600080fd5b505afa1580156106c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ec919061104d565b6001600160a01b03166370a08231846040518263ffffffff1660e01b815260040161071791906112f0565b60206040518083038186803b15801561072f57600080fd5b505afa158015610743573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076791906111f5565b8152604051636021726760e01b81526001600160a01b038516906360217267906107959086906004016112f0565b60206040518083038186803b1580156107ad57600080fd5b505afa1580156107c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e591906111f5565b60208201526040516323ac34d560e21b81526000906001600160a01b03861690638eb0d354906108199087906004016112f0565b604080518083038186803b15801561083057600080fd5b505afa158015610844573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086891906111ad565b805160408085019190915260208201516060850152516256c52760e31b81529091506001600160a01b038616906302b62938906108a99087906004016112f0565b604080518083038186803b1580156108c057600080fd5b505afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906111ad565b80516080840152602081015160a084015260405163dc01f60d60e01b81529091506001600160a01b0386169063dc01f60d906109389087906004016112f0565b60006040518083038186803b15801561095057600080fd5b505afa158015610964573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261098c9190810190610f7c565b60c08301525090939092509050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d1946dbc6040518163ffffffff1660e01b815260040160006040518083038186803b158015610a1a57600080fd5b505afa158015610a2e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a569190810190610ede565b905060005b8151811015610b6b5760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166335ea6a75848481518110610aa157fe5b60200260200101516040518263ffffffff1660e01b8152600401610ac591906112f0565b6101806040518083038186803b158015610ade57600080fd5b505afa158015610af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1691906110bd565b9050828281518110610b2457fe5b60209081029190910181015160e092909201516001600160a01b03908116600090815291829052604090912080546001600160a01b03191691909216179055600101610a5b565b5050565b6000610c91836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610bad57600080fd5b505afa158015610bc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be5919061120d565b60ff16600a0a6105f27f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b3596f07876040518263ffffffff1660e01b8152600401610c3a91906112f0565b60206040518083038186803b158015610c5257600080fd5b505afa158015610c66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8a91906111f5565b8590610cfb565b9392505050565b600082820183811015610cf2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600082610d0a57506000610cf5565b82820282848281610d1757fe5b0414610cf25760405162461bcd60e51b81526004018080602001828103825260218152602001806113e66021913960400191505060405180910390fd5b6000808211610daa576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381610db357fe5b049392505050565b60405180610120016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160608152602001600081525090565b6040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081525090565b8051610e58816113cd565b919050565b600060208284031215610e6e578081fd5b6040516020810181811067ffffffffffffffff82111715610e8b57fe5b6040529151825250919050565b80516fffffffffffffffffffffffffffffffff81168114610e5857600080fd5b805164ffffffffff81168114610e5857600080fd5b805160ff81168114610e5857600080fd5b60006020808385031215610ef0578182fd5b825167ffffffffffffffff811115610f06578283fd5b8301601f81018513610f16578283fd5b8051610f29610f24826113af565b61138b565b8181528381019083850185840285018601891015610f45578687fd5b8694505b83851015610f70578051610f5c816113cd565b835260019490940193918501918501610f49565b50979650505050505050565b60006020808385031215610f8e578182fd5b825167ffffffffffffffff80821115610fa5578384fd5b818501915085601f830112610fb8578384fd5b8151610fc6610f24826113af565b818152848101908486016040808502870188018b1015610fe4578889fd5b8896505b8487101561103e5780828c031215610ffe578889fd5b8051818101818110888211171561101157fe5b8252825161101e816113cd565b815282890151898201528452600196909601959287019290810190610fe8565b50909998505050505050505050565b60006020828403121561105e578081fd5b8151610cf2816113cd565b60006020828403121561107a578081fd5b8135610cf2816113cd565b60008060408385031215611097578081fd5b82356110a2816113cd565b915060208301356110b2816113cd565b809150509250929050565b60006101808083850312156110d0578182fd5b6110d98161138b565b90506110e58484610e5d565b81526110f360208401610e98565b602082015261110460408401610e98565b604082015261111560608401610e98565b606082015261112660808401610e98565b608082015261113760a08401610e98565b60a082015261114860c08401610eb8565b60c082015261115960e08401610e4d565b60e082015261010061116c818501610e4d565b9082015261012061117e848201610e4d565b90820152610140611190848201610e4d565b908201526101606111a2848201610ecd565b908201529392505050565b6000604082840312156111be578081fd5b6040516040810181811067ffffffffffffffff821117156111db57fe5b604052825181526020928301519281019290925250919050565b600060208284031215611206578081fd5b5051919050565b60006020828403121561121e578081fd5b610c9182610ecd565b6000815180845260208085019450808401835b8381101561126a57815180516001600160a01b03168852830151838801526040909601959082019060010161123a565b509495945050505050565b600061012060018060a01b0383511684526020830151602085015260408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e08301518160e08601526112d982860182611227565b610100948501519590940194909452509092915050565b6001600160a01b0391909116815260200190565b600060208252610c916020830184611275565b60006040825261132a6040830185611275565b8281036020840152835181526020840151602082015260408401516040820152606084015160608201526080840151608082015260a084015160a082015260c084015160e060c083015261138160e0830182611227565b9695505050505050565b60405181810167ffffffffffffffff811182821017156113a757fe5b604052919050565b600067ffffffffffffffff8211156113c357fe5b5060209081020190565b6001600160a01b03811681146113e257600080fd5b5056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212200472a2f0cc4d0a701339b0a41c53f9ee542814f5badf70399c10a86655e4684f64736f6c634300070600330000000000000000000000007f9d7476e6a2561fa011aa788979234de80900f7000000000000000000000000c14b5de7fbdff428f64aa9e7e240ea342ee9a3a30000000000000000000000009663c2d75ffd5f4017310405fce61720af45b829

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106100575760003560e01c806316f0115b1461005c57806367a7b5f61461007a5780636fec74b21461009a5780637dc0d1d0146100bb578063b914c5e2146100c3575b600080fd5b6100646100cd565b60405161007191906112f0565b60405180910390f35b61008d610088366004611069565b6100f1565b6040516100719190611304565b6100ad6100a8366004611085565b610660565b604051610071929190611317565b61006461099b565b6100cb6109bf565b005b7f000000000000000000000000c14b5de7fbdff428f64aa9e7e240ea342ee9a3a381565b6100f9610dbb565b816001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b15801561013257600080fd5b505afa158015610146573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016a919061104d565b6001600160a01b039081168252604080516318160ddd60e01b81529051918416916318160ddd91600480820192602092909190829003018186803b1580156101b157600080fd5b505afa1580156101c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e991906111f5565b816020018181525050816001600160a01b031663bcdc3cfc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561022b57600080fd5b505afa15801561023f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026391906111f5565b816040018181525050816001600160a01b0316636746c7b16040518163ffffffff1660e01b815260040160206040518083038186803b1580156102a557600080fd5b505afa1580156102b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102dd91906111f5565b816060018181525050816001600160a01b0316635ade228a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561031f57600080fd5b505afa158015610333573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035791906111f5565b816080018181525050816001600160a01b03166328a9e1ff6040518163ffffffff1660e01b815260040160206040518083038186803b15801561039957600080fd5b505afa1580156103ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d191906111f5565b8160a0018181525050816001600160a01b031663779133226040518163ffffffff1660e01b815260040160206040518083038186803b15801561041357600080fd5b505afa158015610427573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061044b91906111f5565b60c082015260405163dc01f60d60e01b81526001600160a01b0383169063dc01f60d9061047d906000906004016112f0565b60006040518083038186803b15801561049557600080fd5b505afa1580156104a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526104d19190810190610f7c565b60e08201526000805b8260e001515181101561061f576000846001600160a01b031663bcd110148560e00151848151811061050857fe5b6020026020010151600001516040518263ffffffff1660e01b815260040161053091906112f0565b60206040518083038186803b15801561054857600080fd5b505afa15801561055c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058091906111f5565b90506105d16105ca6000808760e00151868151811061059b57fe5b602090810291909101810151516001600160a01b03908116835290820192909252604001600020541683610b6f565b8490610c98565b92506105f884602001516105f2866060015184610cfb90919063ffffffff16565b90610d54565b8460e00151838151811061060857fe5b6020908102919091018101510152506001016104da565b50600061063483600001518460200151610b6f565b9050801561065957610652816105f284670de0b6b3a7640000610cfb565b6101008401525b5050919050565b610668610dbb565b610670610e10565b610679846100f1565b9150836001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b1580156106b457600080fd5b505afa1580156106c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ec919061104d565b6001600160a01b03166370a08231846040518263ffffffff1660e01b815260040161071791906112f0565b60206040518083038186803b15801561072f57600080fd5b505afa158015610743573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076791906111f5565b8152604051636021726760e01b81526001600160a01b038516906360217267906107959086906004016112f0565b60206040518083038186803b1580156107ad57600080fd5b505afa1580156107c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e591906111f5565b60208201526040516323ac34d560e21b81526000906001600160a01b03861690638eb0d354906108199087906004016112f0565b604080518083038186803b15801561083057600080fd5b505afa158015610844573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086891906111ad565b805160408085019190915260208201516060850152516256c52760e31b81529091506001600160a01b038616906302b62938906108a99087906004016112f0565b604080518083038186803b1580156108c057600080fd5b505afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906111ad565b80516080840152602081015160a084015260405163dc01f60d60e01b81529091506001600160a01b0386169063dc01f60d906109389087906004016112f0565b60006040518083038186803b15801561095057600080fd5b505afa158015610964573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261098c9190810190610f7c565b60c08301525090939092509050565b7f0000000000000000000000007f9d7476e6a2561fa011aa788979234de80900f781565b60007f000000000000000000000000c14b5de7fbdff428f64aa9e7e240ea342ee9a3a36001600160a01b031663d1946dbc6040518163ffffffff1660e01b815260040160006040518083038186803b158015610a1a57600080fd5b505afa158015610a2e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a569190810190610ede565b905060005b8151811015610b6b5760007f000000000000000000000000c14b5de7fbdff428f64aa9e7e240ea342ee9a3a36001600160a01b03166335ea6a75848481518110610aa157fe5b60200260200101516040518263ffffffff1660e01b8152600401610ac591906112f0565b6101806040518083038186803b158015610ade57600080fd5b505afa158015610af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1691906110bd565b9050828281518110610b2457fe5b60209081029190910181015160e092909201516001600160a01b03908116600090815291829052604090912080546001600160a01b03191691909216179055600101610a5b565b5050565b6000610c91836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610bad57600080fd5b505afa158015610bc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be5919061120d565b60ff16600a0a6105f27f0000000000000000000000007f9d7476e6a2561fa011aa788979234de80900f76001600160a01b031663b3596f07876040518263ffffffff1660e01b8152600401610c3a91906112f0565b60206040518083038186803b158015610c5257600080fd5b505afa158015610c66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8a91906111f5565b8590610cfb565b9392505050565b600082820183811015610cf2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600082610d0a57506000610cf5565b82820282848281610d1757fe5b0414610cf25760405162461bcd60e51b81526004018080602001828103825260218152602001806113e66021913960400191505060405180910390fd5b6000808211610daa576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381610db357fe5b049392505050565b60405180610120016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160608152602001600081525090565b6040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081525090565b8051610e58816113cd565b919050565b600060208284031215610e6e578081fd5b6040516020810181811067ffffffffffffffff82111715610e8b57fe5b6040529151825250919050565b80516fffffffffffffffffffffffffffffffff81168114610e5857600080fd5b805164ffffffffff81168114610e5857600080fd5b805160ff81168114610e5857600080fd5b60006020808385031215610ef0578182fd5b825167ffffffffffffffff811115610f06578283fd5b8301601f81018513610f16578283fd5b8051610f29610f24826113af565b61138b565b8181528381019083850185840285018601891015610f45578687fd5b8694505b83851015610f70578051610f5c816113cd565b835260019490940193918501918501610f49565b50979650505050505050565b60006020808385031215610f8e578182fd5b825167ffffffffffffffff80821115610fa5578384fd5b818501915085601f830112610fb8578384fd5b8151610fc6610f24826113af565b818152848101908486016040808502870188018b1015610fe4578889fd5b8896505b8487101561103e5780828c031215610ffe578889fd5b8051818101818110888211171561101157fe5b8252825161101e816113cd565b815282890151898201528452600196909601959287019290810190610fe8565b50909998505050505050505050565b60006020828403121561105e578081fd5b8151610cf2816113cd565b60006020828403121561107a578081fd5b8135610cf2816113cd565b60008060408385031215611097578081fd5b82356110a2816113cd565b915060208301356110b2816113cd565b809150509250929050565b60006101808083850312156110d0578182fd5b6110d98161138b565b90506110e58484610e5d565b81526110f360208401610e98565b602082015261110460408401610e98565b604082015261111560608401610e98565b606082015261112660808401610e98565b608082015261113760a08401610e98565b60a082015261114860c08401610eb8565b60c082015261115960e08401610e4d565b60e082015261010061116c818501610e4d565b9082015261012061117e848201610e4d565b90820152610140611190848201610e4d565b908201526101606111a2848201610ecd565b908201529392505050565b6000604082840312156111be578081fd5b6040516040810181811067ffffffffffffffff821117156111db57fe5b604052825181526020928301519281019290925250919050565b600060208284031215611206578081fd5b5051919050565b60006020828403121561121e578081fd5b610c9182610ecd565b6000815180845260208085019450808401835b8381101561126a57815180516001600160a01b03168852830151838801526040909601959082019060010161123a565b509495945050505050565b600061012060018060a01b0383511684526020830151602085015260408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e08301518160e08601526112d982860182611227565b610100948501519590940194909452509092915050565b6001600160a01b0391909116815260200190565b600060208252610c916020830184611275565b60006040825261132a6040830185611275565b8281036020840152835181526020840151602082015260408401516040820152606084015160608201526080840151608082015260a084015160a082015260c084015160e060c083015261138160e0830182611227565b9695505050505050565b60405181810167ffffffffffffffff811182821017156113a757fe5b604052919050565b600067ffffffffffffffff8211156113c357fe5b5060209081020190565b6001600160a01b03811681146113e257600080fd5b5056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212200472a2f0cc4d0a701339b0a41c53f9ee542814f5badf70399c10a86655e4684f64736f6c63430007060033