Source Code
Overview
S Balance
0 S
More Info
ContractCreator
Loading...
Loading
Contract Name:
StableAndVariableTokensHelper
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 2000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; pragma experimental ABIEncoderV2; import {StableDebtToken} from '../protocol/tokenization/StableDebtToken.sol'; import {VariableDebtToken} from '../protocol/tokenization/VariableDebtToken.sol'; import {LendingRateOracle} from '../mocks/oracle/LendingRateOracle.sol'; import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol'; contract StableAndVariableTokensHelper is Ownable { address payable private pool; address private addressesProvider; event deployedContracts(address stableToken, address variableToken); constructor(address payable _pool, address _addressesProvider) { pool = _pool; addressesProvider = _addressesProvider; } function initDeployment(address[] calldata tokens, string[] calldata symbols) external onlyOwner { require(tokens.length == symbols.length, 'Arrays not same length'); require(pool != address(0), 'Pool can not be zero address'); for (uint256 i = 0; i < tokens.length; i++) { emit deployedContracts(address(new StableDebtToken()), address(new VariableDebtToken())); } } function setOracleBorrowRates( address[] calldata assets, uint256[] calldata rates, address oracle ) external onlyOwner { require(assets.length == rates.length, 'Arrays not same length'); for (uint256 i = 0; i < assets.length; i++) { // LendingRateOracle owner must be this contract LendingRateOracle(oracle).setMarketBorrowRate(assets[i], rates[i]); } } function setOracleOwnership(address oracle, address admin) external onlyOwner { require(admin != address(0), 'owner can not be zero'); require(LendingRateOracle(oracle).owner() == address(this), 'helper is not owner'); LendingRateOracle(oracle).transferOwnership(admin); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; /** * @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); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; import {IERC20} from './IERC20.sol'; interface IERC20Detailed is IERC20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import './Context.sol'; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @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 == _msgSender(), 'Ownable: caller is not the owner'); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), 'Ownable: new owner is the zero address'); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; /** * @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, 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) { return sub(a, b, 'SafeMath: subtraction overflow'); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * 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); uint256 c = a - b; return c; } /** * @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) { // 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 0; } uint256 c = a * b; require(c / a == b, 'SafeMath: multiplication overflow'); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts 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) { return div(a, b, 'SafeMath: division by zero'); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message 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, string memory errorMessage ) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts 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) { return mod(a, b, 'SafeMath: modulo by zero'); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message 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, string memory errorMessage ) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; pragma experimental ABIEncoderV2; interface IAaveIncentivesController { event RewardsAccrued(address indexed user, uint256 amount); event RewardsClaimed(address indexed user, address indexed to, uint256 amount); event RewardsClaimed( address indexed user, address indexed to, address indexed claimer, uint256 amount ); event ClaimerSet(address indexed user, address indexed claimer); /* * @dev Returns the configuration of the distribution for a certain asset * @param asset The address of the reference asset of the distribution * @return The asset index, the emission per second and the last updated timestamp **/ function getAssetData(address asset) external view returns ( uint256, uint256, uint256 ); /** * @dev Whitelists an address to claim the rewards on behalf of another address * @param user The address of the user * @param claimer The address of the claimer */ function setClaimer(address user, address claimer) external; /** * @dev Returns the whitelisted claimer for a certain address (0x0 if not set) * @param user The address of the user * @return The claimer address */ function getClaimer(address user) external view returns (address); /** * @dev Configure assets for a certain rewards emission * @param assets The assets to incentivize * @param emissionsPerSecond The emission for each asset */ function configureAssets(address[] calldata assets, uint256[] calldata emissionsPerSecond) external; /** * @dev Called by the corresponding asset on any update that affects the rewards distribution * @param user The address of the user * @param userBalance The balance of the user of the asset in the lending pool * @param totalSupply The total supply of the asset in the lending pool **/ function handleAction( address user, uint256 userBalance, uint256 totalSupply ) external; /** * @dev Returns the total of rewards of an user, already accrued + not yet accrued * @param user The address of the user * @return The rewards **/ function getRewardsBalance(address[] calldata assets, address user) external view returns (uint256); /** * @dev Claims reward for an user, on all the assets of the lending pool, accumulating the pending rewards * @param amount Amount of rewards to claim * @param to Address that will be receiving the rewards * @return Rewards claimed **/ function claimRewards( address[] calldata assets, uint256 amount, address to ) external returns (uint256); /** * @dev Claims reward for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards. The caller must * be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager * @param amount Amount of rewards to claim * @param user Address to check and claim rewards * @param to Address that will be receiving the rewards * @return Rewards claimed **/ function claimRewardsOnBehalf( address[] calldata assets, uint256 amount, address user, address to ) external returns (uint256); /** * @dev returns the unclaimed rewards of the user * @param user the address of the user * @return the unclaimed user rewards */ function getUserUnclaimedRewards(address user) external view returns (uint256); /** * @dev returns the unclaimed rewards of the user * @param user the address of the user * @param asset The asset to incentivize * @return the user index for the asset */ function getUserAssetData(address user, address asset) external view returns (uint256); /** * @dev for backward compatibility with previous implementation of the Incentives controller */ function REWARD_TOKEN() external view returns (address); /** * @dev for backward compatibility with previous implementation of the Incentives controller */ function PRECISION() external view returns (uint8); /** * @dev Gets the distribution end timestamp of the emissions */ function DISTRIBUTION_END() external view returns (uint256); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; interface ICreditDelegationToken { event BorrowAllowanceDelegated( address indexed fromUser, address indexed toUser, address asset, uint256 amount ); /** * @dev delegates borrowing power to a user on the specific debt token * @param delegatee the address receiving the delegated borrowing power * @param amount the maximum amount being delegated. Delegation will still * respect the liquidation constraints (even if delegated, a delegatee cannot * force a delegator HF to go below 1) **/ function approveDelegation(address delegatee, uint256 amount) external; /** * @dev returns the borrow allowance of the user * @param fromUser The user to giving allowance * @param toUser The user to give allowance to * @return the current allowance of toUser **/ function borrowAllowance(address fromUser, address toUser) external view returns (uint256); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; import {ILendingPool} from './ILendingPool.sol'; import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; /** * @title IInitializableDebtToken * @notice Interface for the initialize function common between debt tokens * @author Aave **/ interface IInitializableDebtToken { /** * @dev Emitted when a debt token is initialized * @param underlyingAsset The address of the underlying asset * @param pool The address of the associated lending pool * @param incentivesController The address of the incentives controller for this aToken * @param debtTokenDecimals the decimals of the debt token * @param debtTokenName the name of the debt token * @param debtTokenSymbol the symbol of the debt token * @param params A set of encoded parameters for additional initialization **/ event Initialized( address indexed underlyingAsset, address indexed pool, address incentivesController, uint8 debtTokenDecimals, string debtTokenName, string debtTokenSymbol, bytes params ); /** * @dev Initializes the debt token. * @param pool The address of the lending pool where this aToken will be used * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) * @param incentivesController The smart contract managing potential incentives distribution * @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's * @param debtTokenName The name of the token * @param debtTokenSymbol The symbol of the token */ function initialize( ILendingPool pool, address underlyingAsset, IAaveIncentivesController incentivesController, uint8 debtTokenDecimals, string memory debtTokenName, string memory debtTokenSymbol, bytes calldata params ) external; }
// 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 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 ); /** * @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); /** * @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 modes Types of the debt to open if the flash loan is not returned: * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver * 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2 * @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, uint256[] calldata modes, address onBehalfOf, 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; /** * @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); 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); }
// 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 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; }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; /** * @title ILendingRateOracle interface * @notice Interface for the Aave borrow rate oracle. Provides the average market borrow rate to be used as a base for the stable borrow rate calculations **/ interface ILendingRateOracle { /** @dev returns the market borrow rate in ray **/ function getMarketBorrowRate(address asset) external view returns (uint256); /** @dev sets the market borrow rate. Rate value must be in ray **/ function setMarketBorrowRate(address asset, uint256 rate) external; }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; /************ @title IPriceOracle interface @notice Interface for the Aave price oracle.*/ interface IPriceOracle { /*********** @dev returns the asset price in ETH */ function getAssetPrice(address asset) external view returns (uint256); /*********** @dev sets the asset price, in wei */ function setAssetPrice(address asset, uint256 price) external; }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; 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); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; import {IInitializableDebtToken} from './IInitializableDebtToken.sol'; import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; /** * @title IStableDebtToken * @notice Defines the interface for the stable debt token * @dev It does not inherit from IERC20 to save in code size * @author Aave **/ interface IStableDebtToken is IInitializableDebtToken { /** * @dev Emitted when new stable debt is minted * @param user The address of the user who triggered the minting * @param onBehalfOf The recipient of stable debt tokens * @param amount The amount minted * @param currentBalance The current balance of the user * @param balanceIncrease The increase in balance since the last action of the user * @param newRate The rate of the debt after the minting * @param avgStableRate The new average stable rate after the minting * @param newTotalSupply The new total supply of the stable debt token after the action **/ event Mint( address indexed user, address indexed onBehalfOf, uint256 amount, uint256 currentBalance, uint256 balanceIncrease, uint256 newRate, uint256 avgStableRate, uint256 newTotalSupply ); /** * @dev Emitted when new stable debt is burned * @param user The address of the user * @param amount The amount being burned * @param currentBalance The current balance of the user * @param balanceIncrease The the increase in balance since the last action of the user * @param avgStableRate The new average stable rate after the burning * @param newTotalSupply The new total supply of the stable debt token after the action **/ event Burn( address indexed user, uint256 amount, uint256 currentBalance, uint256 balanceIncrease, uint256 avgStableRate, uint256 newTotalSupply ); /** * @dev Mints debt token to the `onBehalfOf` address. * - The resulting rate is the weighted average between the rate of the new debt * and the rate of the previous debt * @param user The address receiving the borrowed underlying, being the delegatee in case * of credit delegate, or same as `onBehalfOf` otherwise * @param onBehalfOf The address receiving the debt tokens * @param amount The amount of debt tokens to mint * @param rate The rate of the debt being minted **/ function mint( address user, address onBehalfOf, uint256 amount, uint256 rate ) external returns (bool); /** * @dev Burns debt of `user` * - The resulting rate is the weighted average between the rate of the new debt * and the rate of the previous debt * @param user The address of the user getting his debt burned * @param amount The amount of debt tokens getting burned **/ function burn(address user, uint256 amount) external; /** * @dev Returns the average rate of all the stable rate loans. * @return The average stable rate **/ function getAverageStableRate() external view returns (uint256); /** * @dev Returns the stable rate of the user debt * @return The stable rate of the user **/ function getUserStableRate(address user) external view returns (uint256); /** * @dev Returns the timestamp of the last update of the user * @return The timestamp **/ function getUserLastUpdated(address user) external view returns (uint40); /** * @dev Returns the principal, the total supply and the average stable rate **/ function getSupplyData() external view returns ( uint256, uint256, uint256, uint40 ); /** * @dev Returns the timestamp of the last update of the total supply * @return The timestamp **/ function getTotalSupplyLastUpdated() external view returns (uint40); /** * @dev Returns the total supply and the average stable rate **/ function getTotalSupplyAndAvgRate() external view returns (uint256, uint256); /** * @dev Returns the principal debt balance of the user * @return The debt balance of the user since the last burn/mint action **/ function principalBalanceOf(address user) external view returns (uint256); /** * @dev Returns the address of the incentives controller contract **/ function getIncentivesController() external view returns (IAaveIncentivesController); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; import {IScaledBalanceToken} from './IScaledBalanceToken.sol'; import {IInitializableDebtToken} from './IInitializableDebtToken.sol'; import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; /** * @title IVariableDebtToken * @author Aave * @notice Defines the basic interface for a variable debt token. **/ interface IVariableDebtToken is IScaledBalanceToken, IInitializableDebtToken { /** * @dev Emitted after the mint action * @param from The address performing the mint * @param onBehalfOf The address of the user on which behalf minting has been performed * @param value The amount to be minted * @param index The last index of the reserve **/ event Mint(address indexed from, address indexed onBehalfOf, uint256 value, uint256 index); /** * @dev Mints debt token to the `onBehalfOf` address * @param user The address receiving the borrowed underlying, being the delegatee in case * of credit delegate, or same as `onBehalfOf` otherwise * @param onBehalfOf The address receiving the debt tokens * @param amount The amount of debt being minted * @param index The variable debt index of the reserve * @return `true` if the the previous balance of the user is 0 **/ function mint( address user, address onBehalfOf, uint256 amount, uint256 index ) external returns (bool); /** * @dev Emitted when variable debt is burnt * @param user The user which debt has been burned * @param amount The amount of debt being burned * @param index The index of the user **/ event Burn(address indexed user, uint256 amount, uint256 index); /** * @dev Burns user variable debt * @param user The user which debt is burnt * @param index The variable debt index of the reserve **/ function burn( address user, uint256 amount, uint256 index ) external; /** * @dev Returns the address of the incentives controller contract **/ function getIncentivesController() external view returns (IAaveIncentivesController); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; import {ILendingRateOracle} from '../../interfaces/ILendingRateOracle.sol'; import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; contract LendingRateOracle is ILendingRateOracle, Ownable { mapping(address => uint256) borrowRates; mapping(address => uint256) liquidityRates; function getMarketBorrowRate(address _asset) external view override returns (uint256) { return borrowRates[_asset]; } function setMarketBorrowRate(address _asset, uint256 _rate) external override onlyOwner { borrowRates[_asset] = _rate; } function getMarketLiquidityRate(address _asset) external view returns (uint256) { return liquidityRates[_asset]; } function setMarketLiquidityRate(address _asset, uint256 _rate) external onlyOwner { liquidityRates[_asset] = _rate; } }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; /** * @title VersionedInitializable * * @dev Helper contract to implement initializer functions. To use it, replace * the constructor with a function that has the `initializer` modifier. * 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. * WARNING: When used with inheritance, manual care must be taken to not invoke * a parent initializer twice, or ensure that all initializers are idempotent, * because this is not dealt with automatically as with constructors. * * @author Aave, inspired by the OpenZeppelin Initializable contract */ abstract contract VersionedInitializable { /** * @dev Indicates that the contract has been initialized. */ uint256 private lastInitializedRevision = 0; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private initializing; /** * @dev Modifier to use in the initializer function of a contract. */ modifier initializer() { uint256 revision = getRevision(); require( initializing || isConstructor() || revision > lastInitializedRevision, 'Contract instance has already been initialized' ); bool isTopLevelCall = !initializing; if (isTopLevelCall) { initializing = true; lastInitializedRevision = revision; } _; if (isTopLevelCall) { initializing = false; } } /** * @dev returns the revision number of the contract * Needs to be defined in the inherited class as a 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) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. uint256 cs; //solium-disable-next-line assembly { cs := extcodesize(address()) } return cs == 0; } // Reserved storage space to allow for layout changes in the future. uint256[50] private ______gap; }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; /** * @title Errors library * @author Aave * @notice Defines the error messages emitted by the different contracts of the Aave protocol * @dev Error messages prefix glossary: * - VL = ValidationLogic * - MATH = Math libraries * - CT = Common errors between tokens (AToken, VariableDebtToken and StableDebtToken) * - AT = AToken * - SDT = StableDebtToken * - VDT = VariableDebtToken * - LP = LendingPool * - LPAPR = LendingPoolAddressesProviderRegistry * - LPC = LendingPoolConfiguration * - RL = ReserveLogic * - LPCM = LendingPoolCollateralManager * - P = Pausable */ library Errors { //common errors string public constant CALLER_NOT_POOL_ADMIN = '33'; // 'The caller must be the pool admin' string public constant BORROW_ALLOWANCE_NOT_ENOUGH = '59'; // User borrows on behalf, but allowance are too small //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_CURRENT_AVAILABLE_LIQUIDITY_NOT_ENOUGH = '4'; // 'The current liquidity is not enough' string public constant VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE = '5'; // 'User cannot withdraw more than the available balance' 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 greater than the max loan size in stable rate mode string public constant VL_NO_DEBT_OF_SELECTED_TYPE = '15'; // 'for repayment of stable debt, the user needs to have stable debt, otherwise, he needs to have variable debt' 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 underlying 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 LP_NOT_ENOUGH_STABLE_BORROW_BALANCE = '21'; // 'User does not have any stable rate loan for this reserve' string public constant LP_INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET = '22'; // 'Interest rate rebalance conditions were not met' string public constant LP_LIQUIDATION_CALL_FAILED = '23'; // 'Liquidation call failed' string public constant LP_NOT_ENOUGH_LIQUIDITY_TO_BORROW = '24'; // 'There is not enough liquidity available to borrow' string public constant LP_REQUESTED_AMOUNT_TOO_SMALL = '25'; // 'The requested amount is too small for a FlashLoan.' string public constant LP_INCONSISTENT_PROTOCOL_ACTUAL_BALANCE = '26'; // 'The actual balance of the protocol is inconsistent' string public constant LP_CALLER_NOT_LENDING_POOL_CONFIGURATOR = '27'; // 'The caller of the function is not the lending pool configurator' string public constant LP_INCONSISTENT_FLASHLOAN_PARAMS = '28'; string public constant CT_CALLER_MUST_BE_LENDING_POOL = '29'; // 'The caller of this function must be a lending pool' string public constant CT_CANNOT_GIVE_ALLOWANCE_TO_HIMSELF = '30'; // 'User cannot give allowance to himself' string public constant CT_TRANSFER_AMOUNT_NOT_GT_0 = '31'; // 'Transferred amount needs to be greater than zero' string public constant RL_RESERVE_ALREADY_INITIALIZED = '32'; // 'Reserve has already been initialized' string public constant LPC_RESERVE_LIQUIDITY_NOT_0 = '34'; // 'The liquidity of the reserve needs to be 0' string public constant LPC_INVALID_ATOKEN_POOL_ADDRESS = '35'; // 'The liquidity of the reserve needs to be 0' string public constant LPC_INVALID_STABLE_DEBT_TOKEN_POOL_ADDRESS = '36'; // 'The liquidity of the reserve needs to be 0' string public constant LPC_INVALID_VARIABLE_DEBT_TOKEN_POOL_ADDRESS = '37'; // 'The liquidity of the reserve needs to be 0' string public constant LPC_INVALID_STABLE_DEBT_TOKEN_UNDERLYING_ADDRESS = '38'; // 'The liquidity of the reserve needs to be 0' string public constant LPC_INVALID_VARIABLE_DEBT_TOKEN_UNDERLYING_ADDRESS = '39'; // 'The liquidity of the reserve needs to be 0' string public constant LPC_INVALID_ADDRESSES_PROVIDER_ID = '40'; // 'The liquidity of the reserve needs to be 0' string public constant LPC_INVALID_CONFIGURATION = '75'; // 'Invalid risk parameters for the reserve' string public constant LPC_CALLER_NOT_EMERGENCY_ADMIN = '76'; // 'The caller must be the emergency admin' 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 LPCM_NO_ERRORS = '46'; // 'No errors' string public constant LP_INVALID_FLASHLOAN_MODE = '47'; //Invalid flashloan mode selected 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 LP_FAILED_REPAY_WITH_COLLATERAL = '57'; string public constant CT_INVALID_BURN_AMOUNT = '58'; //invalid amount to burn string public constant LP_FAILED_COLLATERAL_SWAP = '60'; string public constant LP_INVALID_EQUAL_ASSETS_TO_SWAP = '61'; string public constant LP_REENTRANCY_NOT_ALLOWED = '62'; string public constant LP_CALLER_MUST_BE_AN_ATOKEN = '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 LP_INCONSISTENT_PARAMS_LENGTH = '74'; string public constant UL_INVALID_INDEX = '77'; string public constant LP_NOT_CONTRACT = '78'; string public constant SDT_STABLE_DEBT_OVERFLOW = '79'; string public constant SDT_BURN_EXCEEDS_BALANCE = '80'; enum CollateralManagerErrors { NO_ERROR, NO_COLLATERAL_AVAILABLE, COLLATERAL_CANNOT_BE_LIQUIDATED, CURRRENCY_NOT_BORROWED, HEALTH_FACTOR_ABOVE_THRESHOLD, NOT_ENOUGH_LIQUIDITY, NO_ACTIVE_RESERVE, HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD, INVALID_EQUAL_ASSETS_TO_SWAP, FROZEN_RESERVE } }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; import {SafeMath} from '../../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {WadRayMath} from './WadRayMath.sol'; library MathUtils { using SafeMath for uint256; using WadRayMath for uint256; /// @dev Ignoring leap years uint256 internal constant SECONDS_PER_YEAR = 365 days; /** * @dev Function to calculate the interest accumulated using a linear interest rate formula * @param rate The interest rate, in ray * @param lastUpdateTimestamp The timestamp of the last update of the interest * @return The interest rate linearly accumulated during the timeDelta, in ray **/ function calculateLinearInterest(uint256 rate, uint40 lastUpdateTimestamp) internal view returns (uint256) { //solium-disable-next-line uint256 timeDifference = block.timestamp.sub(uint256(lastUpdateTimestamp)); return (rate.mul(timeDifference) / SECONDS_PER_YEAR).add(WadRayMath.ray()); } /** * @dev Function to calculate the interest using a compounded interest rate formula * To avoid expensive exponentiation, the calculation is performed using a binomial approximation: * * (1+x)^n = 1+n*x+[n/2*(n-1)]*x^2+[n/6*(n-1)*(n-2)*x^3... * * The approximation slightly underpays liquidity providers and undercharges borrowers, with the advantage of great gas cost reductions * The whitepaper contains reference to the approximation and a table showing the margin of error per different time periods * * @param rate The interest rate, in ray * @param lastUpdateTimestamp The timestamp of the last update of the interest * @return The interest rate compounded during the timeDelta, in ray **/ function calculateCompoundedInterest( uint256 rate, uint40 lastUpdateTimestamp, uint256 currentTimestamp ) internal pure returns (uint256) { //solium-disable-next-line uint256 exp = currentTimestamp.sub(uint256(lastUpdateTimestamp)); if (exp == 0) { return WadRayMath.ray(); } uint256 expMinusOne = exp - 1; uint256 expMinusTwo = exp > 2 ? exp - 2 : 0; uint256 ratePerSecond = rate / SECONDS_PER_YEAR; uint256 basePowerTwo = ratePerSecond.rayMul(ratePerSecond); uint256 basePowerThree = basePowerTwo.rayMul(ratePerSecond); uint256 secondTerm = exp.mul(expMinusOne).mul(basePowerTwo) / 2; uint256 thirdTerm = exp.mul(expMinusOne).mul(expMinusTwo).mul(basePowerThree) / 6; return WadRayMath.ray().add(ratePerSecond.mul(exp)).add(secondTerm).add(thirdTerm); } /** * @dev Calculates the compounded interest between the timestamp of the last update and the current block timestamp * @param rate The interest rate (in ray) * @param lastUpdateTimestamp The timestamp from which the interest accumulation needs to be calculated **/ function calculateCompoundedInterest(uint256 rate, uint40 lastUpdateTimestamp) internal view returns (uint256) { return calculateCompoundedInterest(rate, lastUpdateTimestamp, block.timestamp); } }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; import {Errors} from '../helpers/Errors.sol'; /** * @title WadRayMath library * @author Aave * @dev Provides mul and div function for wads (decimal numbers with 18 digits precision) and rays (decimals with 27 digits) **/ library WadRayMath { uint256 internal constant WAD = 1e18; uint256 internal constant halfWAD = WAD / 2; uint256 internal constant RAY = 1e27; uint256 internal constant halfRAY = RAY / 2; uint256 internal constant WAD_RAY_RATIO = 1e9; /** * @return One ray, 1e27 **/ function ray() internal pure returns (uint256) { return RAY; } /** * @return One wad, 1e18 **/ function wad() internal pure returns (uint256) { return WAD; } /** * @return Half ray, 1e27/2 **/ function halfRay() internal pure returns (uint256) { return halfRAY; } /** * @return Half ray, 1e18/2 **/ function halfWad() internal pure returns (uint256) { return halfWAD; } /** * @dev Multiplies two wad, rounding half up to the nearest wad * @param a Wad * @param b Wad * @return The result of a*b, in wad **/ function wadMul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0 || b == 0) { return 0; } require(a <= (type(uint256).max - halfWAD) / b, Errors.MATH_MULTIPLICATION_OVERFLOW); return (a * b + halfWAD) / WAD; } /** * @dev Divides two wad, rounding half up to the nearest wad * @param a Wad * @param b Wad * @return The result of a/b, in wad **/ function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, Errors.MATH_DIVISION_BY_ZERO); uint256 halfB = b / 2; require(a <= (type(uint256).max - halfB) / WAD, Errors.MATH_MULTIPLICATION_OVERFLOW); return (a * WAD + halfB) / b; } /** * @dev Multiplies two ray, rounding half up to the nearest ray * @param a Ray * @param b Ray * @return The result of a*b, in ray **/ function rayMul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0 || b == 0) { return 0; } require(a <= (type(uint256).max - halfRAY) / b, Errors.MATH_MULTIPLICATION_OVERFLOW); return (a * b + halfRAY) / RAY; } /** * @dev Divides two ray, rounding half up to the nearest ray * @param a Ray * @param b Ray * @return The result of a/b, in ray **/ function rayDiv(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, Errors.MATH_DIVISION_BY_ZERO); uint256 halfB = b / 2; require(a <= (type(uint256).max - halfB) / RAY, Errors.MATH_MULTIPLICATION_OVERFLOW); return (a * RAY + halfB) / b; } /** * @dev Casts ray down to wad * @param a Ray * @return a casted to wad, rounded half up to the nearest wad **/ function rayToWad(uint256 a) internal pure returns (uint256) { uint256 halfRatio = WAD_RAY_RATIO / 2; uint256 result = halfRatio + a; require(result >= halfRatio, Errors.MATH_ADDITION_OVERFLOW); return result / WAD_RAY_RATIO; } /** * @dev Converts wad up to ray * @param a Wad * @return a converted in ray **/ function wadToRay(uint256 a) internal pure returns (uint256) { uint256 result = a * WAD_RAY_RATIO; require(result / WAD_RAY_RATIO == a, Errors.MATH_MULTIPLICATION_OVERFLOW); return result; } }
// 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 UserConfigurationMap { uint256 data; } enum InterestRateMode {NONE, STABLE, VARIABLE} }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; import {ILendingPool} from '../../../interfaces/ILendingPool.sol'; import {ICreditDelegationToken} from '../../../interfaces/ICreditDelegationToken.sol'; import { VersionedInitializable } from '../../libraries/aave-upgradeability/VersionedInitializable.sol'; import {IncentivizedERC20} from '../IncentivizedERC20.sol'; import {Errors} from '../../libraries/helpers/Errors.sol'; import {SafeMath} from '../../../dependencies/openzeppelin/contracts/SafeMath.sol'; /** * @title DebtTokenBase * @notice Base contract for different types of debt tokens, like StableDebtToken or VariableDebtToken * @author Aave */ abstract contract DebtTokenBase is IncentivizedERC20('DEBTTOKEN_IMPL', 'DEBTTOKEN_IMPL', 0), VersionedInitializable, ICreditDelegationToken { using SafeMath for uint256; mapping(address => mapping(address => uint256)) internal _borrowAllowances; /** * @dev Only lending pool can call functions marked by this modifier **/ modifier onlyLendingPool { require(_msgSender() == address(_getLendingPool()), Errors.CT_CALLER_MUST_BE_LENDING_POOL); _; } /** * @dev delegates borrowing power to a user on the specific debt token * @param delegatee the address receiving the delegated borrowing power * @param amount the maximum amount being delegated. Delegation will still * respect the liquidation constraints (even if delegated, a delegatee cannot * force a delegator HF to go below 1) **/ function approveDelegation(address delegatee, uint256 amount) external override { _borrowAllowances[_msgSender()][delegatee] = amount; emit BorrowAllowanceDelegated(_msgSender(), delegatee, _getUnderlyingAssetAddress(), amount); } /** * @dev returns the borrow allowance of the user * @param fromUser The user to giving allowance * @param toUser The user to give allowance to * @return the current allowance of toUser **/ function borrowAllowance(address fromUser, address toUser) external view override returns (uint256) { return _borrowAllowances[fromUser][toUser]; } /** * @dev Being non transferrable, the debt token does not implement any of the * standard ERC20 functions for transfer and allowance. **/ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { recipient; amount; revert('TRANSFER_NOT_SUPPORTED'); } function allowance(address owner, address spender) public view virtual override returns (uint256) { owner; spender; revert('ALLOWANCE_NOT_SUPPORTED'); } function approve(address spender, uint256 amount) public virtual override returns (bool) { spender; amount; revert('APPROVAL_NOT_SUPPORTED'); } function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { sender; recipient; amount; revert('TRANSFER_NOT_SUPPORTED'); } function increaseAllowance(address spender, uint256 addedValue) public virtual override returns (bool) { spender; addedValue; revert('ALLOWANCE_NOT_SUPPORTED'); } function decreaseAllowance(address spender, uint256 subtractedValue) public virtual override returns (bool) { spender; subtractedValue; revert('ALLOWANCE_NOT_SUPPORTED'); } function _decreaseBorrowAllowance( address delegator, address delegatee, uint256 amount ) internal { uint256 newAllowance = _borrowAllowances[delegator][delegatee].sub(amount, Errors.BORROW_ALLOWANCE_NOT_ENOUGH); _borrowAllowances[delegator][delegatee] = newAllowance; emit BorrowAllowanceDelegated(delegator, delegatee, _getUnderlyingAssetAddress(), newAllowance); } function _getUnderlyingAssetAddress() internal view virtual returns (address); function _getLendingPool() internal view virtual returns (ILendingPool); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; import {Context} from '../../dependencies/openzeppelin/contracts/Context.sol'; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol'; import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; import {IPriceOracle} from '../../interfaces/IPriceOracle.sol'; import {ILendingPool} from '../../interfaces/ILendingPool.sol'; /** * @title ERC20 * @notice Basic ERC20 implementation * @author Aave, inspired by the Openzeppelin ERC20 implementation **/ abstract contract IncentivizedERC20 is Context, IERC20, IERC20Detailed { using SafeMath for uint256; mapping(address => uint256) internal _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 internal _totalSupply; string private _name; string private _symbol; uint8 private _decimals; ILendingPool internal _pool; address internal _underlyingAsset; constructor( string memory name, string memory symbol, uint8 decimals ) { _name = name; _symbol = symbol; _decimals = decimals; } /** * @return The name of the token **/ function name() public view override returns (string memory) { return _name; } /** * @return The symbol of the token **/ function symbol() public view override returns (string memory) { return _symbol; } /** * @return The decimals of the token **/ function decimals() public view override returns (uint8) { return _decimals; } /** * @return The total supply of the token **/ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @return The balance of the token **/ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @return Abstract function implemented by the child aToken/debtToken. * Done this way in order to not break compatibility with previous versions of aTokens/debtTokens **/ function _getIncentivesController() internal view virtual returns(IAaveIncentivesController); /** * @dev Executes a transfer of tokens from _msgSender() to recipient * @param recipient The recipient of the tokens * @param amount The amount of tokens being transferred * @return `true` if the transfer succeeds, `false` otherwise **/ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); emit Transfer(_msgSender(), recipient, amount); return true; } /** * @dev Returns the allowance of spender on the tokens owned by owner * @param owner The owner of the tokens * @param spender The user allowed to spend the owner's tokens * @return The amount of owner's tokens spender is allowed to spend **/ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev Allows `spender` to spend the tokens owned by _msgSender() * @param spender The user allowed to spend _msgSender() tokens * @return `true` **/ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev Executes a transfer of token from sender to recipient, if _msgSender() is allowed to do so * @param sender The owner of the tokens * @param recipient The recipient of the tokens * @param amount The amount of tokens being transferred * @return `true` if the transfer succeeds, `false` otherwise **/ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve( sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, 'ERC20: transfer amount exceeds allowance') ); emit Transfer(sender, recipient, amount); return true; } /** * @dev Increases the allowance of spender to spend _msgSender() tokens * @param spender The user allowed to spend on behalf of _msgSender() * @param addedValue The amount being added to the allowance * @return `true` **/ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Decreases the allowance of spender to spend _msgSender() tokens * @param spender The user allowed to spend on behalf of _msgSender() * @param subtractedValue The amount being subtracted to the allowance * @return `true` **/ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve( _msgSender(), spender, _allowances[_msgSender()][spender].sub( subtractedValue, 'ERC20: decreased allowance below zero' ) ); return true; } function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), 'ERC20: transfer from the zero address'); require(recipient != address(0), 'ERC20: transfer to the zero address'); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender].sub(amount, 'ERC20: transfer amount exceeds balance'); _balances[sender] = senderBalance; uint256 recipientBalance = _balances[recipient].add(amount); _balances[recipient] = recipientBalance; if (address(_getIncentivesController()) != address(0)) { uint256 currentTotalSupply = _totalSupply; _getIncentivesController().handleAction(sender, senderBalance, currentTotalSupply); if (sender != recipient) { _getIncentivesController().handleAction(recipient, recipientBalance, currentTotalSupply); } } } function _mint(address account, uint256 amount) internal virtual { require(account != address(0), 'ERC20: mint to the zero address'); _beforeTokenTransfer(address(0), account, amount); uint256 currentTotalSupply = _totalSupply.add(amount); _totalSupply = currentTotalSupply; uint256 accountBalance = _balances[account].add(amount); _balances[account] = accountBalance; if (address(_getIncentivesController()) != address(0)) { _getIncentivesController().handleAction(account, accountBalance, currentTotalSupply); } } function _burn(address account, uint256 amount) internal virtual { require(account != address(0), 'ERC20: burn from the zero address'); _beforeTokenTransfer(account, address(0), amount); uint256 currentTotalSupply = _totalSupply.sub(amount); _totalSupply = currentTotalSupply; uint256 accountBalance = _balances[account].sub(amount, 'ERC20: burn amount exceeds balance'); _balances[account] = accountBalance; if (address(_getIncentivesController()) != address(0)) { _getIncentivesController().handleAction(account, accountBalance, currentTotalSupply); } } function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), 'ERC20: approve from the zero address'); require(spender != address(0), 'ERC20: approve to the zero address'); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } function _setName(string memory newName) internal { _name = newName; } function _setSymbol(string memory newSymbol) internal { _symbol = newSymbol; } function _setDecimals(uint8 newDecimals) internal { _decimals = newDecimals; } function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} function getAssetPrice() external view returns (uint256) { ILendingPoolAddressesProvider provider = _pool.getAddressesProvider(); address oracle = provider.getPriceOracle(); return IPriceOracle(oracle).getAssetPrice(_underlyingAsset); } }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; import {DebtTokenBase} from './base/DebtTokenBase.sol'; import {MathUtils} from '../libraries/math/MathUtils.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {IStableDebtToken} from '../../interfaces/IStableDebtToken.sol'; import {ILendingPool} from '../../interfaces/ILendingPool.sol'; import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; /** * @title StableDebtToken * @notice Implements a stable debt token to track the borrowing positions of users * at stable rate mode * @author Aave **/ contract StableDebtToken is IStableDebtToken, DebtTokenBase { using WadRayMath for uint256; using SafeMath for uint256; uint256 public constant DEBT_TOKEN_REVISION = 0x1; uint256 internal _avgStableRate; mapping(address => uint40) internal _timestamps; mapping(address => uint256) internal _usersStableRate; uint40 internal _totalSupplyTimestamp; IAaveIncentivesController internal _incentivesController; /** * @dev Initializes the debt token. * @param pool The address of the lending pool where this aToken will be used * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) * @param incentivesController The smart contract managing potential incentives distribution * @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's * @param debtTokenName The name of the token * @param debtTokenSymbol The symbol of the token */ function initialize( ILendingPool pool, address underlyingAsset, IAaveIncentivesController incentivesController, uint8 debtTokenDecimals, string memory debtTokenName, string memory debtTokenSymbol, bytes calldata params ) public override initializer { _setName(debtTokenName); _setSymbol(debtTokenSymbol); _setDecimals(debtTokenDecimals); _pool = pool; _underlyingAsset = underlyingAsset; _incentivesController = incentivesController; emit Initialized( underlyingAsset, address(pool), address(incentivesController), debtTokenDecimals, debtTokenName, debtTokenSymbol, params ); } /** * @dev Gets the revision of the stable debt token implementation * @return The debt token implementation revision **/ function getRevision() internal pure virtual override returns (uint256) { return DEBT_TOKEN_REVISION; } /** * @dev Returns the average stable rate across all the stable rate debt * @return the average stable rate **/ function getAverageStableRate() external view virtual override returns (uint256) { return _avgStableRate; } /** * @dev Returns the timestamp of the last user action * @return The last update timestamp **/ function getUserLastUpdated(address user) external view virtual override returns (uint40) { return _timestamps[user]; } /** * @dev Returns the stable rate of the user * @param user The address of the user * @return The stable rate of user **/ function getUserStableRate(address user) external view virtual override returns (uint256) { return _usersStableRate[user]; } /** * @dev Calculates the current user debt balance * @return The accumulated debt of the user **/ function balanceOf(address account) public view virtual override returns (uint256) { uint256 accountBalance = super.balanceOf(account); uint256 stableRate = _usersStableRate[account]; if (accountBalance == 0) { return 0; } uint256 cumulatedInterest = MathUtils.calculateCompoundedInterest(stableRate, _timestamps[account]); return accountBalance.rayMul(cumulatedInterest); } struct MintLocalVars { uint256 previousSupply; uint256 nextSupply; uint256 amountInRay; uint256 newStableRate; uint256 currentAvgStableRate; } /** * @dev Mints debt token to the `onBehalfOf` address. * - Only callable by the LendingPool * - The resulting rate is the weighted average between the rate of the new debt * and the rate of the previous debt * @param user The address receiving the borrowed underlying, being the delegatee in case * of credit delegate, or same as `onBehalfOf` otherwise * @param onBehalfOf The address receiving the debt tokens * @param amount The amount of debt tokens to mint * @param rate The rate of the debt being minted **/ function mint( address user, address onBehalfOf, uint256 amount, uint256 rate ) external override onlyLendingPool returns (bool) { MintLocalVars memory vars; if (user != onBehalfOf) { _decreaseBorrowAllowance(onBehalfOf, user, amount); } (, uint256 currentBalance, uint256 balanceIncrease) = _calculateBalanceIncrease(onBehalfOf); vars.previousSupply = totalSupply(); vars.currentAvgStableRate = _avgStableRate; vars.nextSupply = _totalSupply = vars.previousSupply.add(amount); vars.amountInRay = amount.wadToRay(); vars.newStableRate = _usersStableRate[onBehalfOf] .rayMul(currentBalance.wadToRay()) .add(vars.amountInRay.rayMul(rate)) .rayDiv(currentBalance.add(amount).wadToRay()); require(vars.newStableRate <= type(uint128).max, Errors.SDT_STABLE_DEBT_OVERFLOW); _usersStableRate[onBehalfOf] = vars.newStableRate; //solium-disable-next-line _totalSupplyTimestamp = _timestamps[onBehalfOf] = uint40(block.timestamp); // Calculates the updated average stable rate vars.currentAvgStableRate = _avgStableRate = vars .currentAvgStableRate .rayMul(vars.previousSupply.wadToRay()) .add(rate.rayMul(vars.amountInRay)) .rayDiv(vars.nextSupply.wadToRay()); _mint(onBehalfOf, amount.add(balanceIncrease), vars.previousSupply); emit Transfer(address(0), onBehalfOf, amount); emit Mint( user, onBehalfOf, amount, currentBalance, balanceIncrease, vars.newStableRate, vars.currentAvgStableRate, vars.nextSupply ); return currentBalance == 0; } /** * @dev Burns debt of `user` * @param user The address of the user getting his debt burned * @param amount The amount of debt tokens getting burned **/ function burn(address user, uint256 amount) external override onlyLendingPool { (, uint256 currentBalance, uint256 balanceIncrease) = _calculateBalanceIncrease(user); uint256 previousSupply = totalSupply(); uint256 newAvgStableRate = 0; uint256 nextSupply = 0; uint256 userStableRate = _usersStableRate[user]; // Since the total supply and each single user debt accrue separately, // there might be accumulation errors so that the last borrower repaying // mght actually try to repay more than the available debt supply. // In this case we simply set the total supply and the avg stable rate to 0 if (previousSupply <= amount) { _avgStableRate = 0; _totalSupply = 0; } else { nextSupply = _totalSupply = previousSupply.sub(amount); uint256 firstTerm = _avgStableRate.rayMul(previousSupply.wadToRay()); uint256 secondTerm = userStableRate.rayMul(amount.wadToRay()); // For the same reason described above, when the last user is repaying it might // happen that user rate * user balance > avg rate * total supply. In that case, // we simply set the avg rate to 0 if (secondTerm >= firstTerm) { newAvgStableRate = _avgStableRate = _totalSupply = 0; } else { newAvgStableRate = _avgStableRate = firstTerm.sub(secondTerm).rayDiv(nextSupply.wadToRay()); } } if (amount == currentBalance) { _usersStableRate[user] = 0; _timestamps[user] = 0; } else { //solium-disable-next-line _timestamps[user] = uint40(block.timestamp); } //solium-disable-next-line _totalSupplyTimestamp = uint40(block.timestamp); if (balanceIncrease > amount) { uint256 amountToMint = balanceIncrease.sub(amount); _mint(user, amountToMint, previousSupply); emit Mint( user, user, amountToMint, currentBalance, balanceIncrease, userStableRate, newAvgStableRate, nextSupply ); } else { uint256 amountToBurn = amount.sub(balanceIncrease); _burn(user, amountToBurn, previousSupply); emit Burn(user, amountToBurn, currentBalance, balanceIncrease, newAvgStableRate, nextSupply); } emit Transfer(user, address(0), amount); } /** * @dev Calculates the increase in balance since the last user interaction * @param user The address of the user for which the interest is being accumulated * @return The previous principal balance, the new principal balance and the balance increase **/ function _calculateBalanceIncrease(address user) internal view returns ( uint256, uint256, uint256 ) { uint256 previousPrincipalBalance = super.balanceOf(user); if (previousPrincipalBalance == 0) { return (0, 0, 0); } // Calculation of the accrued interest since the last accumulation uint256 balanceIncrease = balanceOf(user).sub(previousPrincipalBalance); return ( previousPrincipalBalance, previousPrincipalBalance.add(balanceIncrease), balanceIncrease ); } /** * @dev Returns the principal and total supply, the average borrow rate and the last supply update timestamp **/ function getSupplyData() public view override returns ( uint256, uint256, uint256, uint40 ) { uint256 avgRate = _avgStableRate; return (super.totalSupply(), _calcTotalSupply(avgRate), avgRate, _totalSupplyTimestamp); } /** * @dev Returns the the total supply and the average stable rate **/ function getTotalSupplyAndAvgRate() public view override returns (uint256, uint256) { uint256 avgRate = _avgStableRate; return (_calcTotalSupply(avgRate), avgRate); } /** * @dev Returns the total supply **/ function totalSupply() public view override returns (uint256) { return _calcTotalSupply(_avgStableRate); } /** * @dev Returns the timestamp at which the total supply was updated **/ function getTotalSupplyLastUpdated() public view override returns (uint40) { return _totalSupplyTimestamp; } /** * @dev Returns the principal debt balance of the user from * @param user The user's address * @return The debt balance of the user since the last burn/mint action **/ function principalBalanceOf(address user) external view virtual override returns (uint256) { return super.balanceOf(user); } /** * @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH) **/ function UNDERLYING_ASSET_ADDRESS() public view returns (address) { return _underlyingAsset; } /** * @dev Returns the address of the lending pool where this aToken is used **/ function POOL() public view returns (ILendingPool) { return _pool; } /** * @dev Returns the address of the incentives controller contract **/ function getIncentivesController() external view override returns (IAaveIncentivesController) { return _getIncentivesController(); } /** * @dev For internal usage in the logic of the parent contracts **/ function _getIncentivesController() internal view override returns (IAaveIncentivesController) { return _incentivesController; } /** * @dev For internal usage in the logic of the parent contracts **/ function _getUnderlyingAssetAddress() internal view override returns (address) { return _underlyingAsset; } /** * @dev For internal usage in the logic of the parent contracts **/ function _getLendingPool() internal view override returns (ILendingPool) { return _pool; } /** * @dev Calculates the total supply * @param avgRate The average rate at which the total supply increases * @return The debt balance of the user since the last burn/mint action **/ function _calcTotalSupply(uint256 avgRate) internal view virtual returns (uint256) { uint256 principalSupply = super.totalSupply(); if (principalSupply == 0) { return 0; } uint256 cumulatedInterest = MathUtils.calculateCompoundedInterest(avgRate, _totalSupplyTimestamp); return principalSupply.rayMul(cumulatedInterest); } /** * @dev Mints stable debt tokens to an user * @param account The account receiving the debt tokens * @param amount The amount being minted * @param oldTotalSupply the total supply before the minting event **/ function _mint( address account, uint256 amount, uint256 oldTotalSupply ) internal { uint256 oldAccountBalance = _balances[account]; _balances[account] = oldAccountBalance.add(amount); if (address(_incentivesController) != address(0)) { _incentivesController.handleAction(account, oldAccountBalance, oldTotalSupply); } } /** * @dev Burns stable debt tokens of an user * @param account The user getting his debt burned * @param amount The amount being burned * @param oldTotalSupply The total supply before the burning event **/ function _burn( address account, uint256 amount, uint256 oldTotalSupply ) internal { uint256 oldAccountBalance = _balances[account]; _balances[account] = oldAccountBalance.sub(amount, Errors.SDT_BURN_EXCEEDS_BALANCE); if (address(_incentivesController) != address(0)) { _incentivesController.handleAction(account, oldAccountBalance, oldTotalSupply); } } }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; import {IVariableDebtToken} from '../../interfaces/IVariableDebtToken.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; import {DebtTokenBase} from './base/DebtTokenBase.sol'; import {ILendingPool} from '../../interfaces/ILendingPool.sol'; import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol'; import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; /** * @title VariableDebtToken * @notice Implements a variable debt token to track the borrowing positions of users * at variable rate mode * @author Aave **/ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { using WadRayMath for uint256; using SafeMath for uint256; uint256 public constant DEBT_TOKEN_REVISION = 0x1; IAaveIncentivesController internal _incentivesController; /** * @dev Initializes the debt token. * @param pool The address of the lending pool where this aToken will be used * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) * @param incentivesController The smart contract managing potential incentives distribution * @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's * @param debtTokenName The name of the token * @param debtTokenSymbol The symbol of the token */ function initialize( ILendingPool pool, address underlyingAsset, IAaveIncentivesController incentivesController, uint8 debtTokenDecimals, string memory debtTokenName, string memory debtTokenSymbol, bytes calldata params ) public override initializer { _setName(debtTokenName); _setSymbol(debtTokenSymbol); _setDecimals(debtTokenDecimals); _pool = pool; _underlyingAsset = underlyingAsset; _incentivesController = incentivesController; emit Initialized( underlyingAsset, address(pool), address(incentivesController), debtTokenDecimals, debtTokenName, debtTokenSymbol, params ); } /** * @dev Gets the revision of the stable debt token implementation * @return The debt token implementation revision **/ function getRevision() internal pure virtual override returns (uint256) { return DEBT_TOKEN_REVISION; } /** * @dev Calculates the accumulated debt balance of the user * @return The debt balance of the user **/ function balanceOf(address user) public view virtual override returns (uint256) { uint256 scaledBalance = super.balanceOf(user); if (scaledBalance == 0) { return 0; } return scaledBalance.rayMul(_pool.getReserveNormalizedVariableDebt(_underlyingAsset)); } /** * @dev Mints debt token to the `onBehalfOf` address * - Only callable by the LendingPool * @param user The address receiving the borrowed underlying, being the delegatee in case * of credit delegate, or same as `onBehalfOf` otherwise * @param onBehalfOf The address receiving the debt tokens * @param amount The amount of debt being minted * @param index The variable debt index of the reserve * @return `true` if the the previous balance of the user is 0 **/ function mint( address user, address onBehalfOf, uint256 amount, uint256 index ) external override onlyLendingPool returns (bool) { if (user != onBehalfOf) { _decreaseBorrowAllowance(onBehalfOf, user, amount); } uint256 previousBalance = super.balanceOf(onBehalfOf); uint256 amountScaled = amount.rayDiv(index); require(amountScaled != 0, Errors.CT_INVALID_MINT_AMOUNT); _mint(onBehalfOf, amountScaled); emit Transfer(address(0), onBehalfOf, amount); emit Mint(user, onBehalfOf, amount, index); return previousBalance == 0; } /** * @dev Burns user variable debt * - Only callable by the LendingPool * @param user The user whose debt is getting burned * @param amount The amount getting burned * @param index The variable debt index of the reserve **/ function burn( address user, uint256 amount, uint256 index ) external override onlyLendingPool { uint256 amountScaled = amount.rayDiv(index); require(amountScaled != 0, Errors.CT_INVALID_BURN_AMOUNT); _burn(user, amountScaled); emit Transfer(user, address(0), amount); emit Burn(user, amount, index); } /** * @dev Returns the principal debt balance of the user from * @return The debt balance of the user since the last burn/mint action **/ function scaledBalanceOf(address user) public view virtual override returns (uint256) { return super.balanceOf(user); } /** * @dev Returns the total supply of the variable debt token. Represents the total debt accrued by the users * @return The total supply **/ function totalSupply() public view virtual override returns (uint256) { return super.totalSupply().rayMul(_pool.getReserveNormalizedVariableDebt(_underlyingAsset)); } /** * @dev Returns the scaled total supply of the variable debt token. Represents sum(debt/index) * @return the scaled total supply **/ function scaledTotalSupply() public view virtual override returns (uint256) { return super.totalSupply(); } /** * @dev Returns the principal balance of the user and principal total supply. * @param user The address of the user * @return The principal balance of the user * @return The principal total supply **/ function getScaledUserBalanceAndSupply(address user) external view override returns (uint256, uint256) { return (super.balanceOf(user), super.totalSupply()); } /** * @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH) **/ function UNDERLYING_ASSET_ADDRESS() public view returns (address) { return _underlyingAsset; } /** * @dev Returns the address of the incentives controller contract **/ function getIncentivesController() external view override returns (IAaveIncentivesController) { return _getIncentivesController(); } /** * @dev Returns the address of the lending pool where this aToken is used **/ function POOL() public view returns (ILendingPool) { return _pool; } function _getIncentivesController() internal view override returns (IAaveIncentivesController) { return _incentivesController; } function _getUnderlyingAssetAddress() internal view override returns (address) { return _underlyingAsset; } function _getLendingPool() internal view override returns (ILendingPool) { return _pool; } }
{ "optimizer": { "enabled": true, "runs": 2000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
[{"inputs":[{"internalType":"address payable","name":"_pool","type":"address"},{"internalType":"address","name":"_addressesProvider","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"stableToken","type":"address"},{"indexed":false,"internalType":"address","name":"variableToken","type":"address"}],"name":"deployedContracts","type":"event"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"string[]","name":"symbols","type":"string[]"}],"name":"initDeployment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"rates","type":"uint256[]"},{"internalType":"address","name":"oracle","type":"address"}],"name":"setOracleBorrowRates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"admin","type":"address"}],"name":"setOracleOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506040516149f13803806149f183398101604081905261002f916100b8565b60006100396100b4565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055610109565b3390565b600080604083850312156100ca578182fd5b82516100d5816100f1565b60208401519092506100e6816100f1565b809150509250929050565b6001600160a01b038116811461010657600080fd5b50565b6148d9806101186000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c80638da5cb5b116100505780638da5cb5b146100a7578063c2d30321146100c5578063f2fde38b146100d857610072565b806354fe1c9414610077578063563b1cb31461008c578063715018a61461009f575b600080fd5b61008a610085366004610801565b6100eb565b005b61008a61009a3660046107c9565b610248565b61008a6103f4565b6100af6104c0565b6040516100bc91906108eb565b60405180910390f35b61008a6100d336600461086a565b6104cf565b61008a6100e636600461078a565b610601565b6100f3610723565b6000546001600160a01b03908116911614610155576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b82811461017d5760405162461bcd60e51b8152600401610174906109d7565b60405180910390fd5b6001546001600160a01b03166101a55760405162461bcd60e51b815260040161017490610932565b60005b83811015610241577f1c1768aab1796270c7034dc781c2951065e6afb7a946269746521002443b8ea46040516101dd90610727565b604051809103906000f0801580156101f9573d6000803e3d6000fd5b5060405161020690610734565b604051809103906000f080158015610222573d6000803e3d6000fd5b506040516102319291906108ff565b60405180910390a16001016101a8565b5050505050565b610250610723565b6000546001600160a01b039081169116146102b2576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166102d85760405162461bcd60e51b8152600401610174906109a0565b306001600160a01b0316826001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561031b57600080fd5b505afa15801561032f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035391906107ad565b6001600160a01b0316146103795760405162461bcd60e51b815260040161017490610969565b6040517ff2fde38b0000000000000000000000000000000000000000000000000000000081526001600160a01b0383169063f2fde38b906103be9084906004016108eb565b600060405180830381600087803b1580156103d857600080fd5b505af11580156103ec573d6000803e3d6000fd5b505050505050565b6103fc610723565b6000546001600160a01b0390811691161461045e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6000546001600160a01b031690565b6104d7610723565b6000546001600160a01b03908116911614610539576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b8382146105585760405162461bcd60e51b8152600401610174906109d7565b60005b848110156103ec57816001600160a01b03166372eb293d87878481811061057e57fe5b9050602002016020810190610593919061078a565b86868581811061059f57fe5b905060200201356040518363ffffffff1660e01b81526004016105c3929190610919565b600060405180830381600087803b1580156105dd57600080fd5b505af11580156105f1573d6000803e3d6000fd5b50506001909201915061055b9050565b610609610723565b6000546001600160a01b0390811691161461066b576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166106b05760405162461bcd60e51b815260040180806020018281038252602681526020018061487e6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b3390565b61218980610a2783390190565b611cce80612bb083390190565b60008083601f840112610752578182fd5b50813567ffffffffffffffff811115610769578182fd5b602083019150836020808302850101111561078357600080fd5b9250929050565b60006020828403121561079b578081fd5b81356107a681610a0e565b9392505050565b6000602082840312156107be578081fd5b81516107a681610a0e565b600080604083850312156107db578081fd5b82356107e681610a0e565b915060208301356107f681610a0e565b809150509250929050565b60008060008060408587031215610816578182fd5b843567ffffffffffffffff8082111561082d578384fd5b61083988838901610741565b90965094506020870135915080821115610851578384fd5b5061085e87828801610741565b95989497509550505050565b600080600080600060608688031215610881578081fd5b853567ffffffffffffffff80821115610898578283fd5b6108a489838a01610741565b909750955060208801359150808211156108bc578283fd5b506108c988828901610741565b90945092505060408601356108dd81610a0e565b809150509295509295909350565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b6020808252601c908201527f506f6f6c2063616e206e6f74206265207a65726f206164647265737300000000604082015260600190565b60208082526013908201527f68656c706572206973206e6f74206f776e657200000000000000000000000000604082015260600190565b60208082526015908201527f6f776e65722063616e206e6f74206265207a65726f0000000000000000000000604082015260600190565b60208082526016908201527f417272617973206e6f742073616d65206c656e67746800000000000000000000604082015260600190565b6001600160a01b0381168114610a2357600080fd5b5056fe608060405260006007553480156200001657600080fd5b50604080518082018252600e8082526d111150951513d2d15397d253541360921b60208084018281528551808701909652928552840152815191929160009162000064916003919062000098565b5081516200007a90600490602085019062000098565b506005805460ff191660ff9290921691909117905550620001449050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620000d057600085556200011b565b82601f10620000eb57805160ff19168380011785556200011b565b828001600101855582156200011b579182015b828111156200011b578251825591602001919060010190620000fe565b50620001299291506200012d565b5090565b5b808211156200012957600081556001016200012e565b61203580620001546000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80639dc29fac116100f9578063c222ec8a11610097578063e54f088011610071578063e54f0880146106f4578063e7484890146106fc578063e78c9b3b14610704578063f731e9be1461072a576101c4565b8063c222ec8a146104f7578063c634dfaa146106a0578063dd62ed3e146106c6576101c4565b8063b16a19de116100d3578063b16a19de1461047f578063b3f1c93d14610487578063b9a7b622146104c3578063c04a8a10146104cb576101c4565b80639dc29fac14610425578063a457c2d7146102f4578063a9059cbb14610453576101c4565b806370a0823111610166578063797743381161014057806379774338146103a057806379ce6b8c146103d557806390f6fcf21461041557806395d89b411461041d576101c4565b806370a082311461034e5780637535d2461461037457806375d2641314610398576101c4565b806323b872dd116101a257806323b872dd146102a0578063313ce567146102d657806339509351146102f45780636bd76d2414610320576101c4565b806306fdde03146101c9578063095ea7b31461024657806318160ddd14610286575b600080fd5b6101d161074b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102726004803603604081101561025c57600080fd5b506001600160a01b0381351690602001356107e1565b604080519115158252519081900360200190f35b61028e610830565b60408051918252519081900360200190f35b610272600480360360608110156102b657600080fd5b506001600160a01b03813581169160208101359091169060400135610842565b6102de610891565b6040805160ff9092168252519081900360200190f35b6102726004803603604081101561030a57600080fd5b506001600160a01b03813516906020013561089a565b61028e6004803603604081101561033657600080fd5b506001600160a01b03813581169160200135166108e9565b61028e6004803603602081101561036457600080fd5b50356001600160a01b0316610916565b61037c610990565b604080516001600160a01b039092168252519081900360200190f35b61037c6109a4565b6103a86109ae565b6040805194855260208501939093528383019190915264ffffffffff166060830152519081900360800190f35b6103fb600480360360208110156103eb57600080fd5b50356001600160a01b03166109e4565b6040805164ffffffffff9092168252519081900360200190f35b61028e610a06565b6101d1610a0c565b6104516004803603604081101561043b57600080fd5b506001600160a01b038135169060200135610a6d565b005b6102726004803603604081101561046957600080fd5b506001600160a01b038135169060200135610842565b61037c610dee565b6102726004803603608081101561049d57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610dfd565b61028e61118b565b610451600480360360408110156104e157600080fd5b506001600160a01b038135169060200135611190565b610451600480360360e081101561050d57600080fd5b6001600160a01b038235811692602081013582169260408201359092169160ff606083013516919081019060a08101608082013564010000000081111561055357600080fd5b82018360208201111561056557600080fd5b8035906020019184600183028401116401000000008311171561058757600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156105da57600080fd5b8201836020820111156105ec57600080fd5b8035906020019184600183028401116401000000008311171561060e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561066157600080fd5b82018360208201111561067357600080fd5b8035906020019184600183028401116401000000008311171561069557600080fd5b50909250905061122c565b61028e600480360360208110156106b657600080fd5b50356001600160a01b03166114dd565b61028e600480360360408110156106dc57600080fd5b506001600160a01b038135811691602001351661089a565b61028e6114e8565b6103fb61168c565b61028e6004803603602081101561071a57600080fd5b50356001600160a01b0316611699565b6107326116b4565b6040805192835260208301919091528051918290030190f35b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107d75780601f106107ac576101008083540402835291602001916107d7565b820191906000526020600020905b8154815290600101906020018083116107ba57829003601f168201915b5050505050905090565b6040805162461bcd60e51b815260206004820152601660248201527f415050524f56414c5f4e4f545f535550504f52544544000000000000000000006044820152905160009181900360640190fd5b600061083d603c546116cd565b905090565b6040805162461bcd60e51b815260206004820152601660248201527f5452414e534645525f4e4f545f535550504f52544544000000000000000000006044820152905160009181900360640190fd5b60055460ff1690565b6040805162461bcd60e51b815260206004820152601760248201527f414c4c4f57414e43455f4e4f545f535550504f525445440000000000000000006044820152905160009181900360640190fd5b6001600160a01b038083166000908152603b60209081526040808320938516835292905220545b92915050565b60008061092283611715565b6001600160a01b0384166000908152603e60205260409020549091508161094e5760009250505061098b565b6001600160a01b0384166000908152603d602052604081205461097990839064ffffffffff16611730565b90506109858382611744565b93505050505b919050565b60055461010090046001600160a01b031690565b600061083d611815565b6000806000806000603c5490506109c361182d565b6109cc826116cd565b603f54919790965091945064ffffffffff1692509050565b6001600160a01b03166000908152603d602052604090205464ffffffffff1690565b603c5490565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107d75780601f106107ac576101008083540402835291602001916107d7565b610a75610990565b6001600160a01b0316610a86611833565b6001600160a01b0316146040518060400160405280600281526020017f323900000000000000000000000000000000000000000000000000000000000081525090610b4f5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b14578181015183820152602001610afc565b50505050905090810190601f168015610b415780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600080610b5c84611837565b92509250506000610b6b610830565b6001600160a01b0386166000908152603e6020526040812054919250908190868411610ba0576000603c819055600255610c22565b610baa8488611890565b600281905591506000610bc8610bbf866118d2565b603c5490611744565b90506000610bdf610bd88a6118d2565b8490611744565b9050818110610bfb5760006002819055603c8190559450610c1f565b610c17610c07856118d2565b610c118484611890565b90611950565b603c81905594505b50505b85871415610c60576001600160a01b0388166000908152603e60209081526040808320839055603d9091529020805464ffffffffff19169055610c8e565b6001600160a01b0388166000908152603d60205260409020805464ffffffffff19164264ffffffffff161790555b603f805464ffffffffff19164264ffffffffff1617905586851115610d2e576000610cb98689611890565b9050610cc6898287611a72565b6040805182815260208101899052808201889052606081018490526080810186905260a0810185905290516001600160a01b038b169182917fc16f4e4ca34d790de4c656c72fd015c667d688f20be64eea360618545c4c530f9181900360c00190a350610da3565b6000610d3a8887611890565b9050610d47898287611b62565b6040805182815260208101899052808201889052606081018690526080810185905290516001600160a01b038b16917f44bd20a79e993bdcc7cbedf54a3b4d19fb78490124b6b90d04fe3242eea579e8919081900360a00190a2505b6040805188815290516000916001600160a01b038b16917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050505050565b6006546001600160a01b031690565b6000610e07610990565b6001600160a01b0316610e18611833565b6001600160a01b0316146040518060400160405280600281526020017f323900000000000000000000000000000000000000000000000000000000000081525090610ea45760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b50610ead611ee0565b846001600160a01b0316866001600160a01b031614610ed157610ed1858786611bbf565b600080610edd87611837565b9250925050610eea610830565b808452603c546080850152610eff9087611ca2565b60028190556020840152610f12866118d2565b6040840152610f70610f2c610f278489611ca2565b6118d2565b6040850151610c1190610f3f9089611744565b610f6a610f4b876118d2565b6001600160a01b038d166000908152603e602052604090205490611744565b90611ca2565b6060840181905260408051808201909152600281527f37390000000000000000000000000000000000000000000000000000000000006020820152906fffffffffffffffffffffffffffffffff101561100a5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b5060608301516001600160a01b0388166000908152603e6020908152604080832093909355603d8152919020805464ffffffffff421664ffffffffff199182168117909255603f805490911690911790558301516110a09061106b906118d2565b610c1161108586604001518961174490919063ffffffff16565b610f6a61109588600001516118d2565b608089015190611744565b603c81905560808401526110bf876110b88884611ca2565b8551611a72565b6040805187815290516001600160a01b038916916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a3866001600160a01b0316886001600160a01b03167fc16f4e4ca34d790de4c656c72fd015c667d688f20be64eea360618545c4c530f888585886060015189608001518a6020015160405180878152602001868152602001858152602001848152602001838152602001828152602001965050505050505060405180910390a350159695505050505050565b600181565b80603b600061119d611833565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120919091556111d5611833565b6001600160a01b03167fda919360433220e13b51e8c211e490d148e61a3bd53de8c097194e458b97f3e1611207610dee565b604080516001600160a01b039092168252602082018690528051918290030190a35050565b6000611236611cfc565b60085490915060ff168061124d575061124d611d01565b80611259575060075481115b6112945760405162461bcd60e51b815260040180806020018281038252602e815260200180611fd2602e913960400191505060405180910390fd5b60085460ff161580156112b4576008805460ff1916600117905560078290555b6112bd86611d07565b6112c685611d1e565b6112cf87611d31565b89600560016101000a8154816001600160a01b0302191690836001600160a01b0316021790555088600660006101000a8154816001600160a01b0302191690836001600160a01b0316021790555087603f60056101000a8154816001600160a01b0302191690836001600160a01b03160217905550896001600160a01b0316896001600160a01b03167f40251fbfb6656cfa65a00d7879029fec1fad21d28fdcff2f4f68f52795b74f2c8a8a8a8a8a8a60405180876001600160a01b031681526020018660ff168152602001806020018060200180602001848103845288818151815260200191508051906020019080838360005b838110156113dc5781810151838201526020016113c4565b50505050905090810190601f1680156114095780820380516001836020036101000a031916815260200191505b50848103835287518152875160209182019189019080838360005b8381101561143c578181015183820152602001611424565b50505050905090810190601f1680156114695780820380516001836020036101000a031916815260200191505b508481038252858152602001868680828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018290039b50909950505050505050505050a380156114d1576008805460ff191690555b50505050505050505050565b600061091082611715565b600080600560019054906101000a90046001600160a01b03166001600160a01b031663fe65acfe6040518163ffffffff1660e01b815260040160206040518083038186803b15801561153957600080fd5b505afa15801561154d573d6000803e3d6000fd5b505050506040513d602081101561156357600080fd5b5051604080517ffca513a800000000000000000000000000000000000000000000000000000000815290519192506000916001600160a01b0384169163fca513a8916004808301926020929190829003018186803b1580156115c457600080fd5b505afa1580156115d8573d6000803e3d6000fd5b505050506040513d60208110156115ee57600080fd5b5051600654604080517fb3596f070000000000000000000000000000000000000000000000000000000081526001600160a01b03928316600482015290519293509083169163b3596f0791602480820192602092909190829003018186803b15801561165957600080fd5b505afa15801561166d573d6000803e3d6000fd5b505050506040513d602081101561168357600080fd5b50519250505090565b603f5464ffffffffff1690565b6001600160a01b03166000908152603e602052604090205490565b603c5460009081906116c5816116cd565b925090509091565b6000806116d861182d565b9050806116e957600091505061098b565b603f5460009061170190859064ffffffffff16611730565b905061170d8282611744565b949350505050565b6001600160a01b031660009081526020819052604090205490565b600061173d838342611d47565b9392505050565b6000821580611751575081155b1561175e57506000610910565b817ffffffffffffffffffffffffffffffffffffffffffe6268e1b017bfe18bffffff8161178757fe5b0483111560405180604001604052806002815260200161068760f31b815250906117f25760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b50506b033b2e3c9fd0803ce800000091026b019d971e4fe8401e74000000010490565b603f546501000000000090046001600160a01b031690565b60025490565b3390565b60008060008061184685611715565b90508061185e57600080600093509350935050611889565b60006118738261186d88610916565b90611890565b9050816118808183611ca2565b90955093509150505b9193909250565b600061173d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611e1d565b6000633b9aca0082810290839082041460405180604001604052806002815260200161068760f31b815250906119495760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b5092915050565b60408051808201909152600281527f35300000000000000000000000000000000000000000000000000000000000006020820152600090826119d35760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b5060408051808201909152600280825261068760f31b60208301528304906b033b2e3c9fd0803ce8000000821904851115611a4f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b5082816b033b2e3c9fd0803ce800000086020181611a6957fe5b04949350505050565b6001600160a01b038316600090815260208190526040902054611a958184611ca2565b6001600160a01b03808616600090815260208190526040902091909155603f546501000000000090041615611b5c57603f54604080517f31873e2e0000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301526024820185905260448201869052915165010000000000909304909116916331873e2e9160648082019260009290919082900301818387803b158015611b4357600080fd5b505af1158015611b57573d6000803e3d6000fd5b505050505b50505050565b6001600160a01b03831660009081526020818152604091829020548251808401909352600283527f38300000000000000000000000000000000000000000000000000000000000009183019190915290611a959082908590611e1d565b604080518082018252600281527f35390000000000000000000000000000000000000000000000000000000000006020808301919091526001600160a01b038087166000908152603b83528481209187168152915291822054611c23918490611e1d565b6001600160a01b038086166000818152603b60209081526040808320948916808452949091529020839055919250907fda919360433220e13b51e8c211e490d148e61a3bd53de8c097194e458b97f3e1611c7b610dee565b604080516001600160a01b039092168252602082018690528051918290030190a350505050565b60008282018381101561173d576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600190565b303b1590565b8051611d1a906003906020840190611f0f565b5050565b8051611d1a906004906020840190611f0f565b6005805460ff191660ff92909216919091179055565b600080611d5b8364ffffffffff8616611890565b905080611d7257611d6a611e77565b91505061173d565b6000198101600060028311611d88576000611d8d565b600283035b90506301e1338087046000611da28280611744565b90506000611db08284611744565b905060006002611dca84611dc48a8a611e87565b90611e87565b81611dd157fe5b04905060006006611de884611dc489818d8d611e87565b81611def57fe5b049050611e0d81610f6a8481611e058a8e611e87565b610f6a611e77565b9c9b505050505050505050505050565b60008184841115611e6f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b505050900390565b6b033b2e3c9fd0803ce800000090565b600082611e9657506000610910565b82820282848281611ea357fe5b041461173d5760405162461bcd60e51b8152600401808060200182810382526021815260200180611fb16021913960400191505060405180910390fd5b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611f455760008555611f8b565b82601f10611f5e57805160ff1916838001178555611f8b565b82800160010185558215611f8b579182015b82811115611f8b578251825591602001919060010190611f70565b50611f97929150611f9b565b5090565b5b80821115611f975760008155600101611f9c56fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a2646970667358221220107cec5b29ae043fe3200d287a765a874c6800fa4b9d66d0ef36e7f4f620f0bb64736f6c63430007060033608060405260006007553480156200001657600080fd5b50604080518082018252600e8082526d111150951513d2d15397d253541360921b60208084018281528551808701909652928552840152815191929160009162000064916003919062000098565b5081516200007a90600490602085019062000098565b506005805460ff191660ff9290921691909117905550620001449050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620000d057600085556200011b565b82601f10620000eb57805160ff19168380011785556200011b565b828001600101855582156200011b579182015b828111156200011b578251825591602001919060010190620000fe565b50620001299291506200012d565b5090565b5b808211156200012957600081556001016200012e565b611b7a80620001546000396000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806395d89b41116100e3578063b9a7b6221161008c578063dd62ed3e11610066578063dd62ed3e14610638578063e54f088014610666578063f5298aca1461066e57610198565b8063b9a7b62214610459578063c04a8a1014610461578063c222ec8a1461048f57610198565b8063b16a19de116100bd578063b16a19de1461040d578063b1bf962d14610415578063b3f1c93d1461041d57610198565b806395d89b41146103d9578063a457c2d71461032d578063a9059cbb146103e157610198565b8063313ce5671161014557806370a082311161011f57806370a08231146103875780637535d246146103ad57806375d26413146103d157610198565b8063313ce5671461030f578063395093511461032d5780636bd76d241461035957610198565b806318160ddd1161017657806318160ddd146102995780631da24f3e146102b357806323b872dd146102d957610198565b806306fdde031461019d578063095ea7b31461021a5780630afbcdc91461025a575b600080fd5b6101a56106a0565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101df5781810151838201526020016101c7565b50505050905090810190601f16801561020c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102466004803603604081101561023057600080fd5b506001600160a01b038135169060200135610736565b604080519115158252519081900360200190f35b6102806004803603602081101561027057600080fd5b50356001600160a01b0316610785565b6040805192835260208301919091528051918290030190f35b6102a16107a2565b60408051918252519081900360200190f35b6102a1600480360360208110156102c957600080fd5b50356001600160a01b0316610854565b610246600480360360608110156102ef57600080fd5b506001600160a01b03813581169160208101359091169060400135610867565b6103176108b6565b6040805160ff9092168252519081900360200190f35b6102466004803603604081101561034357600080fd5b506001600160a01b0381351690602001356108bf565b6102a16004803603604081101561036f57600080fd5b506001600160a01b038135811691602001351661090e565b6102a16004803603602081101561039d57600080fd5b50356001600160a01b031661093b565b6103b5610a04565b604080516001600160a01b039092168252519081900360200190f35b6103b5610a18565b6101a5610a22565b610246600480360360408110156103f757600080fd5b506001600160a01b038135169060200135610867565b6103b5610a83565b6102a1610a92565b6102466004803603608081101561043357600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610a9c565b6102a1610ceb565b61048d6004803603604081101561047757600080fd5b506001600160a01b038135169060200135610cf0565b005b61048d600480360360e08110156104a557600080fd5b6001600160a01b038235811692602081013582169260408201359092169160ff606083013516919081019060a0810160808201356401000000008111156104eb57600080fd5b8201836020820111156104fd57600080fd5b8035906020019184600183028401116401000000008311171561051f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561057257600080fd5b82018360208201111561058457600080fd5b803590602001918460018302840111640100000000831117156105a657600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156105f957600080fd5b82018360208201111561060b57600080fd5b8035906020019184600183028401116401000000008311171561062d57600080fd5b509092509050610d8c565b6102a16004803603604081101561064e57600080fd5b506001600160a01b03813581169160200135166108bf565b6102a161103d565b61048d6004803603606081101561068457600080fd5b506001600160a01b0381351690602081013590604001356111e1565b60038054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561072c5780601f106107015761010080835404028352916020019161072c565b820191906000526020600020905b81548152906001019060200180831161070f57829003601f168201915b5050505050905090565b6040805162461bcd60e51b815260206004820152601660248201527f415050524f56414c5f4e4f545f535550504f52544544000000000000000000006044820152905160009181900360640190fd5b600080610791836113ab565b6107996113c6565b91509150915091565b600554600654604080517f386497fd0000000000000000000000000000000000000000000000000000000081526001600160a01b039283166004820152905160009361084f93610100909104169163386497fd916024808301926020929190829003018186803b15801561081557600080fd5b505afa158015610829573d6000803e3d6000fd5b505050506040513d602081101561083f57600080fd5b50516108496113c6565b906113cc565b905090565b600061085f826113ab565b90505b919050565b6040805162461bcd60e51b815260206004820152601660248201527f5452414e534645525f4e4f545f535550504f52544544000000000000000000006044820152905160009181900360640190fd5b60055460ff1690565b6040805162461bcd60e51b815260206004820152601760248201527f414c4c4f57414e43455f4e4f545f535550504f525445440000000000000000006044820152905160009181900360640190fd5b6001600160a01b038083166000908152603b60209081526040808320938516835292905220545b92915050565b600080610947836113ab565b905080610958576000915050610862565b600554600654604080517f386497fd0000000000000000000000000000000000000000000000000000000081526001600160a01b03928316600482015290516109fd9361010090049092169163386497fd91602480820192602092909190829003018186803b1580156109ca57600080fd5b505afa1580156109de573d6000803e3d6000fd5b505050506040513d60208110156109f457600080fd5b505182906113cc565b9392505050565b60055461010090046001600160a01b031690565b600061084f6114b8565b60048054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561072c5780601f106107015761010080835404028352916020019161072c565b6006546001600160a01b031690565b600061084f6113c6565b6000610aa6610a04565b6001600160a01b0316610ab76114c7565b6001600160a01b0316146040518060400160405280600281526020017f323900000000000000000000000000000000000000000000000000000000000081525090610b805760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b45578181015183820152602001610b2d565b50505050905090810190601f168015610b725780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50836001600160a01b0316856001600160a01b031614610ba557610ba58486856114cb565b6000610bb0856113ab565b90506000610bbe85856115ae565b60408051808201909152600281527f3536000000000000000000000000000000000000000000000000000000000000602082015290915081610c415760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b50610c4c86826116eb565b6040805186815290516001600160a01b038816916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a3856001600160a01b0316876001600160a01b03167f2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee8787604051808381526020018281526020019250505060405180910390a3501595945050505050565b600181565b80603b6000610cfd6114c7565b6001600160a01b0390811682526020808301939093526040918201600090812091871680825291909352912091909155610d356114c7565b6001600160a01b03167fda919360433220e13b51e8c211e490d148e61a3bd53de8c097194e458b97f3e1610d67610a83565b604080516001600160a01b039092168252602082018690528051918290030190a35050565b6000610d96611847565b60085490915060ff1680610dad5750610dad61184c565b80610db9575060075481115b610df45760405162461bcd60e51b815260040180806020018281038252602e815260200180611af6602e913960400191505060405180910390fd5b60085460ff16158015610e14576008805460ff1916600117905560078290555b610e1d86611852565b610e2685611869565b610e2f8761187c565b89600560016101000a8154816001600160a01b0302191690836001600160a01b0316021790555088600660006101000a8154816001600160a01b0302191690836001600160a01b0316021790555087603c60006101000a8154816001600160a01b0302191690836001600160a01b03160217905550896001600160a01b0316896001600160a01b03167f40251fbfb6656cfa65a00d7879029fec1fad21d28fdcff2f4f68f52795b74f2c8a8a8a8a8a8a60405180876001600160a01b031681526020018660ff168152602001806020018060200180602001848103845288818151815260200191508051906020019080838360005b83811015610f3c578181015183820152602001610f24565b50505050905090810190601f168015610f695780820380516001836020036101000a031916815260200191505b50848103835287518152875160209182019189019080838360005b83811015610f9c578181015183820152602001610f84565b50505050905090810190601f168015610fc95780820380516001836020036101000a031916815260200191505b508481038252858152602001868680828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018290039b50909950505050505050505050a38015611031576008805460ff191690555b50505050505050505050565b600080600560019054906101000a90046001600160a01b03166001600160a01b031663fe65acfe6040518163ffffffff1660e01b815260040160206040518083038186803b15801561108e57600080fd5b505afa1580156110a2573d6000803e3d6000fd5b505050506040513d60208110156110b857600080fd5b5051604080517ffca513a800000000000000000000000000000000000000000000000000000000815290519192506000916001600160a01b0384169163fca513a8916004808301926020929190829003018186803b15801561111957600080fd5b505afa15801561112d573d6000803e3d6000fd5b505050506040513d602081101561114357600080fd5b5051600654604080517fb3596f070000000000000000000000000000000000000000000000000000000081526001600160a01b03928316600482015290519293509083169163b3596f0791602480820192602092909190829003018186803b1580156111ae57600080fd5b505afa1580156111c2573d6000803e3d6000fd5b505050506040513d60208110156111d857600080fd5b50519250505090565b6111e9610a04565b6001600160a01b03166111fa6114c7565b6001600160a01b0316146040518060400160405280600281526020017f3239000000000000000000000000000000000000000000000000000000000000815250906112865760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b50600061129383836115ae565b60408051808201909152600281527f35380000000000000000000000000000000000000000000000000000000000006020820152909150816113165760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b506113218482611892565b6040805184815290516000916001600160a01b038716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a3604080518481526020810184905281516001600160a01b038716927f49995e5dd6158cf69ad3e9777c46755a1a826a446c6416992167462dad033b2a928290030190a250505050565b6001600160a01b031660009081526020819052604090205490565b60025490565b60008215806113d9575081155b156113e657506000610935565b817ffffffffffffffffffffffffffffffffffffffffffe6268e1b017bfe18bffffff8161140f57fe5b048311156040518060400160405280600281526020017f3438000000000000000000000000000000000000000000000000000000000000815250906114955760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b50506b033b2e3c9fd0803ce800000091026b019d971e4fe8401e74000000010490565b603c546001600160a01b031690565b3390565b604080518082018252600281527f35390000000000000000000000000000000000000000000000000000000000006020808301919091526001600160a01b038087166000908152603b8352848120918716815291529182205461152f918490611937565b6001600160a01b038086166000818152603b60209081526040808320948916808452949091529020839055919250907fda919360433220e13b51e8c211e490d148e61a3bd53de8c097194e458b97f3e1611587610a83565b604080516001600160a01b039092168252602082018690528051918290030190a350505050565b60408051808201909152600281527f35300000000000000000000000000000000000000000000000000000000000006020820152600090826116315760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b506040805180820190915260028082527f343800000000000000000000000000000000000000000000000000000000000060208301528304906b033b2e3c9fd0803ce80000008219048511156116c85760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b5082816b033b2e3c9fd0803ce8000000860201816116e257fe5b04949350505050565b6001600160a01b038216611746576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b61175260008383611991565b6002546000906117629083611996565b60028190556001600160a01b0384166000908152602081905260408120549192509061178e9084611996565b6001600160a01b03851660009081526020819052604081208290559091506117b46114b8565b6001600160a01b031614611841576117ca6114b8565b6001600160a01b03166331873e2e8583856040518463ffffffff1660e01b815260040180846001600160a01b031681526020018381526020018281526020019350505050600060405180830381600087803b15801561182857600080fd5b505af115801561183c573d6000803e3d6000fd5b505050505b50505050565b600190565b303b1590565b8051611865906003906020840190611a32565b5050565b8051611865906004906020840190611a32565b6005805460ff191660ff92909216919091179055565b6001600160a01b0382166118d75760405162461bcd60e51b8152600401808060200182810382526021815260200180611b246021913960400191505060405180910390fd5b6118e382600083611991565b6002546000906118f390836119f0565b905080600281905550600061178e83604051806060016040528060228152602001611ad4602291396001600160a01b03871660009081526020819052604090205491905b600081848411156119895760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b505050900390565b505050565b6000828201838110156109fd576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006109fd83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611937565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611a685760008555611aae565b82601f10611a8157805160ff1916838001178555611aae565b82800160010185558215611aae579182015b82811115611aae578251825591602001919060010190611a93565b50611aba929150611abe565b5090565b5b80821115611aba5760008155600101611abf56fe45524332303a206275726e20616d6f756e7420657863656564732062616c616e6365436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a656445524332303a206275726e2066726f6d20746865207a65726f2061646472657373a26469706673582212206d2c8a05224c77c053ea4fb944710858ded2f4c6da09abae7252c150dae7ad3d64736f6c634300070600334f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a2646970667358221220ed5c48e4e9eb368049b2c2fa7b0931aef9023290fbcdb2dd5091465e87e19d8464736f6c6343000706003300000000000000000000000037d913276586da1764ac1458e4d77d8570d82bb70000000000000000000000006a4905c7ea38b0f24023dfbbd6efd53c1b2f5d6d
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100725760003560e01c80638da5cb5b116100505780638da5cb5b146100a7578063c2d30321146100c5578063f2fde38b146100d857610072565b806354fe1c9414610077578063563b1cb31461008c578063715018a61461009f575b600080fd5b61008a610085366004610801565b6100eb565b005b61008a61009a3660046107c9565b610248565b61008a6103f4565b6100af6104c0565b6040516100bc91906108eb565b60405180910390f35b61008a6100d336600461086a565b6104cf565b61008a6100e636600461078a565b610601565b6100f3610723565b6000546001600160a01b03908116911614610155576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b82811461017d5760405162461bcd60e51b8152600401610174906109d7565b60405180910390fd5b6001546001600160a01b03166101a55760405162461bcd60e51b815260040161017490610932565b60005b83811015610241577f1c1768aab1796270c7034dc781c2951065e6afb7a946269746521002443b8ea46040516101dd90610727565b604051809103906000f0801580156101f9573d6000803e3d6000fd5b5060405161020690610734565b604051809103906000f080158015610222573d6000803e3d6000fd5b506040516102319291906108ff565b60405180910390a16001016101a8565b5050505050565b610250610723565b6000546001600160a01b039081169116146102b2576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166102d85760405162461bcd60e51b8152600401610174906109a0565b306001600160a01b0316826001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561031b57600080fd5b505afa15801561032f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035391906107ad565b6001600160a01b0316146103795760405162461bcd60e51b815260040161017490610969565b6040517ff2fde38b0000000000000000000000000000000000000000000000000000000081526001600160a01b0383169063f2fde38b906103be9084906004016108eb565b600060405180830381600087803b1580156103d857600080fd5b505af11580156103ec573d6000803e3d6000fd5b505050505050565b6103fc610723565b6000546001600160a01b0390811691161461045e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6000546001600160a01b031690565b6104d7610723565b6000546001600160a01b03908116911614610539576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b8382146105585760405162461bcd60e51b8152600401610174906109d7565b60005b848110156103ec57816001600160a01b03166372eb293d87878481811061057e57fe5b9050602002016020810190610593919061078a565b86868581811061059f57fe5b905060200201356040518363ffffffff1660e01b81526004016105c3929190610919565b600060405180830381600087803b1580156105dd57600080fd5b505af11580156105f1573d6000803e3d6000fd5b50506001909201915061055b9050565b610609610723565b6000546001600160a01b0390811691161461066b576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166106b05760405162461bcd60e51b815260040180806020018281038252602681526020018061487e6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b3390565b61218980610a2783390190565b611cce80612bb083390190565b60008083601f840112610752578182fd5b50813567ffffffffffffffff811115610769578182fd5b602083019150836020808302850101111561078357600080fd5b9250929050565b60006020828403121561079b578081fd5b81356107a681610a0e565b9392505050565b6000602082840312156107be578081fd5b81516107a681610a0e565b600080604083850312156107db578081fd5b82356107e681610a0e565b915060208301356107f681610a0e565b809150509250929050565b60008060008060408587031215610816578182fd5b843567ffffffffffffffff8082111561082d578384fd5b61083988838901610741565b90965094506020870135915080821115610851578384fd5b5061085e87828801610741565b95989497509550505050565b600080600080600060608688031215610881578081fd5b853567ffffffffffffffff80821115610898578283fd5b6108a489838a01610741565b909750955060208801359150808211156108bc578283fd5b506108c988828901610741565b90945092505060408601356108dd81610a0e565b809150509295509295909350565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b6020808252601c908201527f506f6f6c2063616e206e6f74206265207a65726f206164647265737300000000604082015260600190565b60208082526013908201527f68656c706572206973206e6f74206f776e657200000000000000000000000000604082015260600190565b60208082526015908201527f6f776e65722063616e206e6f74206265207a65726f0000000000000000000000604082015260600190565b60208082526016908201527f417272617973206e6f742073616d65206c656e67746800000000000000000000604082015260600190565b6001600160a01b0381168114610a2357600080fd5b5056fe608060405260006007553480156200001657600080fd5b50604080518082018252600e8082526d111150951513d2d15397d253541360921b60208084018281528551808701909652928552840152815191929160009162000064916003919062000098565b5081516200007a90600490602085019062000098565b506005805460ff191660ff9290921691909117905550620001449050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620000d057600085556200011b565b82601f10620000eb57805160ff19168380011785556200011b565b828001600101855582156200011b579182015b828111156200011b578251825591602001919060010190620000fe565b50620001299291506200012d565b5090565b5b808211156200012957600081556001016200012e565b61203580620001546000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80639dc29fac116100f9578063c222ec8a11610097578063e54f088011610071578063e54f0880146106f4578063e7484890146106fc578063e78c9b3b14610704578063f731e9be1461072a576101c4565b8063c222ec8a146104f7578063c634dfaa146106a0578063dd62ed3e146106c6576101c4565b8063b16a19de116100d3578063b16a19de1461047f578063b3f1c93d14610487578063b9a7b622146104c3578063c04a8a10146104cb576101c4565b80639dc29fac14610425578063a457c2d7146102f4578063a9059cbb14610453576101c4565b806370a0823111610166578063797743381161014057806379774338146103a057806379ce6b8c146103d557806390f6fcf21461041557806395d89b411461041d576101c4565b806370a082311461034e5780637535d2461461037457806375d2641314610398576101c4565b806323b872dd116101a257806323b872dd146102a0578063313ce567146102d657806339509351146102f45780636bd76d2414610320576101c4565b806306fdde03146101c9578063095ea7b31461024657806318160ddd14610286575b600080fd5b6101d161074b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102726004803603604081101561025c57600080fd5b506001600160a01b0381351690602001356107e1565b604080519115158252519081900360200190f35b61028e610830565b60408051918252519081900360200190f35b610272600480360360608110156102b657600080fd5b506001600160a01b03813581169160208101359091169060400135610842565b6102de610891565b6040805160ff9092168252519081900360200190f35b6102726004803603604081101561030a57600080fd5b506001600160a01b03813516906020013561089a565b61028e6004803603604081101561033657600080fd5b506001600160a01b03813581169160200135166108e9565b61028e6004803603602081101561036457600080fd5b50356001600160a01b0316610916565b61037c610990565b604080516001600160a01b039092168252519081900360200190f35b61037c6109a4565b6103a86109ae565b6040805194855260208501939093528383019190915264ffffffffff166060830152519081900360800190f35b6103fb600480360360208110156103eb57600080fd5b50356001600160a01b03166109e4565b6040805164ffffffffff9092168252519081900360200190f35b61028e610a06565b6101d1610a0c565b6104516004803603604081101561043b57600080fd5b506001600160a01b038135169060200135610a6d565b005b6102726004803603604081101561046957600080fd5b506001600160a01b038135169060200135610842565b61037c610dee565b6102726004803603608081101561049d57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610dfd565b61028e61118b565b610451600480360360408110156104e157600080fd5b506001600160a01b038135169060200135611190565b610451600480360360e081101561050d57600080fd5b6001600160a01b038235811692602081013582169260408201359092169160ff606083013516919081019060a08101608082013564010000000081111561055357600080fd5b82018360208201111561056557600080fd5b8035906020019184600183028401116401000000008311171561058757600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156105da57600080fd5b8201836020820111156105ec57600080fd5b8035906020019184600183028401116401000000008311171561060e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561066157600080fd5b82018360208201111561067357600080fd5b8035906020019184600183028401116401000000008311171561069557600080fd5b50909250905061122c565b61028e600480360360208110156106b657600080fd5b50356001600160a01b03166114dd565b61028e600480360360408110156106dc57600080fd5b506001600160a01b038135811691602001351661089a565b61028e6114e8565b6103fb61168c565b61028e6004803603602081101561071a57600080fd5b50356001600160a01b0316611699565b6107326116b4565b6040805192835260208301919091528051918290030190f35b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107d75780601f106107ac576101008083540402835291602001916107d7565b820191906000526020600020905b8154815290600101906020018083116107ba57829003601f168201915b5050505050905090565b6040805162461bcd60e51b815260206004820152601660248201527f415050524f56414c5f4e4f545f535550504f52544544000000000000000000006044820152905160009181900360640190fd5b600061083d603c546116cd565b905090565b6040805162461bcd60e51b815260206004820152601660248201527f5452414e534645525f4e4f545f535550504f52544544000000000000000000006044820152905160009181900360640190fd5b60055460ff1690565b6040805162461bcd60e51b815260206004820152601760248201527f414c4c4f57414e43455f4e4f545f535550504f525445440000000000000000006044820152905160009181900360640190fd5b6001600160a01b038083166000908152603b60209081526040808320938516835292905220545b92915050565b60008061092283611715565b6001600160a01b0384166000908152603e60205260409020549091508161094e5760009250505061098b565b6001600160a01b0384166000908152603d602052604081205461097990839064ffffffffff16611730565b90506109858382611744565b93505050505b919050565b60055461010090046001600160a01b031690565b600061083d611815565b6000806000806000603c5490506109c361182d565b6109cc826116cd565b603f54919790965091945064ffffffffff1692509050565b6001600160a01b03166000908152603d602052604090205464ffffffffff1690565b603c5490565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107d75780601f106107ac576101008083540402835291602001916107d7565b610a75610990565b6001600160a01b0316610a86611833565b6001600160a01b0316146040518060400160405280600281526020017f323900000000000000000000000000000000000000000000000000000000000081525090610b4f5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b14578181015183820152602001610afc565b50505050905090810190601f168015610b415780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600080610b5c84611837565b92509250506000610b6b610830565b6001600160a01b0386166000908152603e6020526040812054919250908190868411610ba0576000603c819055600255610c22565b610baa8488611890565b600281905591506000610bc8610bbf866118d2565b603c5490611744565b90506000610bdf610bd88a6118d2565b8490611744565b9050818110610bfb5760006002819055603c8190559450610c1f565b610c17610c07856118d2565b610c118484611890565b90611950565b603c81905594505b50505b85871415610c60576001600160a01b0388166000908152603e60209081526040808320839055603d9091529020805464ffffffffff19169055610c8e565b6001600160a01b0388166000908152603d60205260409020805464ffffffffff19164264ffffffffff161790555b603f805464ffffffffff19164264ffffffffff1617905586851115610d2e576000610cb98689611890565b9050610cc6898287611a72565b6040805182815260208101899052808201889052606081018490526080810186905260a0810185905290516001600160a01b038b169182917fc16f4e4ca34d790de4c656c72fd015c667d688f20be64eea360618545c4c530f9181900360c00190a350610da3565b6000610d3a8887611890565b9050610d47898287611b62565b6040805182815260208101899052808201889052606081018690526080810185905290516001600160a01b038b16917f44bd20a79e993bdcc7cbedf54a3b4d19fb78490124b6b90d04fe3242eea579e8919081900360a00190a2505b6040805188815290516000916001600160a01b038b16917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050505050565b6006546001600160a01b031690565b6000610e07610990565b6001600160a01b0316610e18611833565b6001600160a01b0316146040518060400160405280600281526020017f323900000000000000000000000000000000000000000000000000000000000081525090610ea45760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b50610ead611ee0565b846001600160a01b0316866001600160a01b031614610ed157610ed1858786611bbf565b600080610edd87611837565b9250925050610eea610830565b808452603c546080850152610eff9087611ca2565b60028190556020840152610f12866118d2565b6040840152610f70610f2c610f278489611ca2565b6118d2565b6040850151610c1190610f3f9089611744565b610f6a610f4b876118d2565b6001600160a01b038d166000908152603e602052604090205490611744565b90611ca2565b6060840181905260408051808201909152600281527f37390000000000000000000000000000000000000000000000000000000000006020820152906fffffffffffffffffffffffffffffffff101561100a5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b5060608301516001600160a01b0388166000908152603e6020908152604080832093909355603d8152919020805464ffffffffff421664ffffffffff199182168117909255603f805490911690911790558301516110a09061106b906118d2565b610c1161108586604001518961174490919063ffffffff16565b610f6a61109588600001516118d2565b608089015190611744565b603c81905560808401526110bf876110b88884611ca2565b8551611a72565b6040805187815290516001600160a01b038916916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a3866001600160a01b0316886001600160a01b03167fc16f4e4ca34d790de4c656c72fd015c667d688f20be64eea360618545c4c530f888585886060015189608001518a6020015160405180878152602001868152602001858152602001848152602001838152602001828152602001965050505050505060405180910390a350159695505050505050565b600181565b80603b600061119d611833565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120919091556111d5611833565b6001600160a01b03167fda919360433220e13b51e8c211e490d148e61a3bd53de8c097194e458b97f3e1611207610dee565b604080516001600160a01b039092168252602082018690528051918290030190a35050565b6000611236611cfc565b60085490915060ff168061124d575061124d611d01565b80611259575060075481115b6112945760405162461bcd60e51b815260040180806020018281038252602e815260200180611fd2602e913960400191505060405180910390fd5b60085460ff161580156112b4576008805460ff1916600117905560078290555b6112bd86611d07565b6112c685611d1e565b6112cf87611d31565b89600560016101000a8154816001600160a01b0302191690836001600160a01b0316021790555088600660006101000a8154816001600160a01b0302191690836001600160a01b0316021790555087603f60056101000a8154816001600160a01b0302191690836001600160a01b03160217905550896001600160a01b0316896001600160a01b03167f40251fbfb6656cfa65a00d7879029fec1fad21d28fdcff2f4f68f52795b74f2c8a8a8a8a8a8a60405180876001600160a01b031681526020018660ff168152602001806020018060200180602001848103845288818151815260200191508051906020019080838360005b838110156113dc5781810151838201526020016113c4565b50505050905090810190601f1680156114095780820380516001836020036101000a031916815260200191505b50848103835287518152875160209182019189019080838360005b8381101561143c578181015183820152602001611424565b50505050905090810190601f1680156114695780820380516001836020036101000a031916815260200191505b508481038252858152602001868680828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018290039b50909950505050505050505050a380156114d1576008805460ff191690555b50505050505050505050565b600061091082611715565b600080600560019054906101000a90046001600160a01b03166001600160a01b031663fe65acfe6040518163ffffffff1660e01b815260040160206040518083038186803b15801561153957600080fd5b505afa15801561154d573d6000803e3d6000fd5b505050506040513d602081101561156357600080fd5b5051604080517ffca513a800000000000000000000000000000000000000000000000000000000815290519192506000916001600160a01b0384169163fca513a8916004808301926020929190829003018186803b1580156115c457600080fd5b505afa1580156115d8573d6000803e3d6000fd5b505050506040513d60208110156115ee57600080fd5b5051600654604080517fb3596f070000000000000000000000000000000000000000000000000000000081526001600160a01b03928316600482015290519293509083169163b3596f0791602480820192602092909190829003018186803b15801561165957600080fd5b505afa15801561166d573d6000803e3d6000fd5b505050506040513d602081101561168357600080fd5b50519250505090565b603f5464ffffffffff1690565b6001600160a01b03166000908152603e602052604090205490565b603c5460009081906116c5816116cd565b925090509091565b6000806116d861182d565b9050806116e957600091505061098b565b603f5460009061170190859064ffffffffff16611730565b905061170d8282611744565b949350505050565b6001600160a01b031660009081526020819052604090205490565b600061173d838342611d47565b9392505050565b6000821580611751575081155b1561175e57506000610910565b817ffffffffffffffffffffffffffffffffffffffffffe6268e1b017bfe18bffffff8161178757fe5b0483111560405180604001604052806002815260200161068760f31b815250906117f25760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b50506b033b2e3c9fd0803ce800000091026b019d971e4fe8401e74000000010490565b603f546501000000000090046001600160a01b031690565b60025490565b3390565b60008060008061184685611715565b90508061185e57600080600093509350935050611889565b60006118738261186d88610916565b90611890565b9050816118808183611ca2565b90955093509150505b9193909250565b600061173d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611e1d565b6000633b9aca0082810290839082041460405180604001604052806002815260200161068760f31b815250906119495760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b5092915050565b60408051808201909152600281527f35300000000000000000000000000000000000000000000000000000000000006020820152600090826119d35760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b5060408051808201909152600280825261068760f31b60208301528304906b033b2e3c9fd0803ce8000000821904851115611a4f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b5082816b033b2e3c9fd0803ce800000086020181611a6957fe5b04949350505050565b6001600160a01b038316600090815260208190526040902054611a958184611ca2565b6001600160a01b03808616600090815260208190526040902091909155603f546501000000000090041615611b5c57603f54604080517f31873e2e0000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301526024820185905260448201869052915165010000000000909304909116916331873e2e9160648082019260009290919082900301818387803b158015611b4357600080fd5b505af1158015611b57573d6000803e3d6000fd5b505050505b50505050565b6001600160a01b03831660009081526020818152604091829020548251808401909352600283527f38300000000000000000000000000000000000000000000000000000000000009183019190915290611a959082908590611e1d565b604080518082018252600281527f35390000000000000000000000000000000000000000000000000000000000006020808301919091526001600160a01b038087166000908152603b83528481209187168152915291822054611c23918490611e1d565b6001600160a01b038086166000818152603b60209081526040808320948916808452949091529020839055919250907fda919360433220e13b51e8c211e490d148e61a3bd53de8c097194e458b97f3e1611c7b610dee565b604080516001600160a01b039092168252602082018690528051918290030190a350505050565b60008282018381101561173d576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600190565b303b1590565b8051611d1a906003906020840190611f0f565b5050565b8051611d1a906004906020840190611f0f565b6005805460ff191660ff92909216919091179055565b600080611d5b8364ffffffffff8616611890565b905080611d7257611d6a611e77565b91505061173d565b6000198101600060028311611d88576000611d8d565b600283035b90506301e1338087046000611da28280611744565b90506000611db08284611744565b905060006002611dca84611dc48a8a611e87565b90611e87565b81611dd157fe5b04905060006006611de884611dc489818d8d611e87565b81611def57fe5b049050611e0d81610f6a8481611e058a8e611e87565b610f6a611e77565b9c9b505050505050505050505050565b60008184841115611e6f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b14578181015183820152602001610afc565b505050900390565b6b033b2e3c9fd0803ce800000090565b600082611e9657506000610910565b82820282848281611ea357fe5b041461173d5760405162461bcd60e51b8152600401808060200182810382526021815260200180611fb16021913960400191505060405180910390fd5b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611f455760008555611f8b565b82601f10611f5e57805160ff1916838001178555611f8b565b82800160010185558215611f8b579182015b82811115611f8b578251825591602001919060010190611f70565b50611f97929150611f9b565b5090565b5b80821115611f975760008155600101611f9c56fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a2646970667358221220107cec5b29ae043fe3200d287a765a874c6800fa4b9d66d0ef36e7f4f620f0bb64736f6c63430007060033608060405260006007553480156200001657600080fd5b50604080518082018252600e8082526d111150951513d2d15397d253541360921b60208084018281528551808701909652928552840152815191929160009162000064916003919062000098565b5081516200007a90600490602085019062000098565b506005805460ff191660ff9290921691909117905550620001449050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620000d057600085556200011b565b82601f10620000eb57805160ff19168380011785556200011b565b828001600101855582156200011b579182015b828111156200011b578251825591602001919060010190620000fe565b50620001299291506200012d565b5090565b5b808211156200012957600081556001016200012e565b611b7a80620001546000396000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806395d89b41116100e3578063b9a7b6221161008c578063dd62ed3e11610066578063dd62ed3e14610638578063e54f088014610666578063f5298aca1461066e57610198565b8063b9a7b62214610459578063c04a8a1014610461578063c222ec8a1461048f57610198565b8063b16a19de116100bd578063b16a19de1461040d578063b1bf962d14610415578063b3f1c93d1461041d57610198565b806395d89b41146103d9578063a457c2d71461032d578063a9059cbb146103e157610198565b8063313ce5671161014557806370a082311161011f57806370a08231146103875780637535d246146103ad57806375d26413146103d157610198565b8063313ce5671461030f578063395093511461032d5780636bd76d241461035957610198565b806318160ddd1161017657806318160ddd146102995780631da24f3e146102b357806323b872dd146102d957610198565b806306fdde031461019d578063095ea7b31461021a5780630afbcdc91461025a575b600080fd5b6101a56106a0565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101df5781810151838201526020016101c7565b50505050905090810190601f16801561020c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102466004803603604081101561023057600080fd5b506001600160a01b038135169060200135610736565b604080519115158252519081900360200190f35b6102806004803603602081101561027057600080fd5b50356001600160a01b0316610785565b6040805192835260208301919091528051918290030190f35b6102a16107a2565b60408051918252519081900360200190f35b6102a1600480360360208110156102c957600080fd5b50356001600160a01b0316610854565b610246600480360360608110156102ef57600080fd5b506001600160a01b03813581169160208101359091169060400135610867565b6103176108b6565b6040805160ff9092168252519081900360200190f35b6102466004803603604081101561034357600080fd5b506001600160a01b0381351690602001356108bf565b6102a16004803603604081101561036f57600080fd5b506001600160a01b038135811691602001351661090e565b6102a16004803603602081101561039d57600080fd5b50356001600160a01b031661093b565b6103b5610a04565b604080516001600160a01b039092168252519081900360200190f35b6103b5610a18565b6101a5610a22565b610246600480360360408110156103f757600080fd5b506001600160a01b038135169060200135610867565b6103b5610a83565b6102a1610a92565b6102466004803603608081101561043357600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610a9c565b6102a1610ceb565b61048d6004803603604081101561047757600080fd5b506001600160a01b038135169060200135610cf0565b005b61048d600480360360e08110156104a557600080fd5b6001600160a01b038235811692602081013582169260408201359092169160ff606083013516919081019060a0810160808201356401000000008111156104eb57600080fd5b8201836020820111156104fd57600080fd5b8035906020019184600183028401116401000000008311171561051f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561057257600080fd5b82018360208201111561058457600080fd5b803590602001918460018302840111640100000000831117156105a657600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156105f957600080fd5b82018360208201111561060b57600080fd5b8035906020019184600183028401116401000000008311171561062d57600080fd5b509092509050610d8c565b6102a16004803603604081101561064e57600080fd5b506001600160a01b03813581169160200135166108bf565b6102a161103d565b61048d6004803603606081101561068457600080fd5b506001600160a01b0381351690602081013590604001356111e1565b60038054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561072c5780601f106107015761010080835404028352916020019161072c565b820191906000526020600020905b81548152906001019060200180831161070f57829003601f168201915b5050505050905090565b6040805162461bcd60e51b815260206004820152601660248201527f415050524f56414c5f4e4f545f535550504f52544544000000000000000000006044820152905160009181900360640190fd5b600080610791836113ab565b6107996113c6565b91509150915091565b600554600654604080517f386497fd0000000000000000000000000000000000000000000000000000000081526001600160a01b039283166004820152905160009361084f93610100909104169163386497fd916024808301926020929190829003018186803b15801561081557600080fd5b505afa158015610829573d6000803e3d6000fd5b505050506040513d602081101561083f57600080fd5b50516108496113c6565b906113cc565b905090565b600061085f826113ab565b90505b919050565b6040805162461bcd60e51b815260206004820152601660248201527f5452414e534645525f4e4f545f535550504f52544544000000000000000000006044820152905160009181900360640190fd5b60055460ff1690565b6040805162461bcd60e51b815260206004820152601760248201527f414c4c4f57414e43455f4e4f545f535550504f525445440000000000000000006044820152905160009181900360640190fd5b6001600160a01b038083166000908152603b60209081526040808320938516835292905220545b92915050565b600080610947836113ab565b905080610958576000915050610862565b600554600654604080517f386497fd0000000000000000000000000000000000000000000000000000000081526001600160a01b03928316600482015290516109fd9361010090049092169163386497fd91602480820192602092909190829003018186803b1580156109ca57600080fd5b505afa1580156109de573d6000803e3d6000fd5b505050506040513d60208110156109f457600080fd5b505182906113cc565b9392505050565b60055461010090046001600160a01b031690565b600061084f6114b8565b60048054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561072c5780601f106107015761010080835404028352916020019161072c565b6006546001600160a01b031690565b600061084f6113c6565b6000610aa6610a04565b6001600160a01b0316610ab76114c7565b6001600160a01b0316146040518060400160405280600281526020017f323900000000000000000000000000000000000000000000000000000000000081525090610b805760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b45578181015183820152602001610b2d565b50505050905090810190601f168015610b725780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50836001600160a01b0316856001600160a01b031614610ba557610ba58486856114cb565b6000610bb0856113ab565b90506000610bbe85856115ae565b60408051808201909152600281527f3536000000000000000000000000000000000000000000000000000000000000602082015290915081610c415760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b50610c4c86826116eb565b6040805186815290516001600160a01b038816916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a3856001600160a01b0316876001600160a01b03167f2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee8787604051808381526020018281526020019250505060405180910390a3501595945050505050565b600181565b80603b6000610cfd6114c7565b6001600160a01b0390811682526020808301939093526040918201600090812091871680825291909352912091909155610d356114c7565b6001600160a01b03167fda919360433220e13b51e8c211e490d148e61a3bd53de8c097194e458b97f3e1610d67610a83565b604080516001600160a01b039092168252602082018690528051918290030190a35050565b6000610d96611847565b60085490915060ff1680610dad5750610dad61184c565b80610db9575060075481115b610df45760405162461bcd60e51b815260040180806020018281038252602e815260200180611af6602e913960400191505060405180910390fd5b60085460ff16158015610e14576008805460ff1916600117905560078290555b610e1d86611852565b610e2685611869565b610e2f8761187c565b89600560016101000a8154816001600160a01b0302191690836001600160a01b0316021790555088600660006101000a8154816001600160a01b0302191690836001600160a01b0316021790555087603c60006101000a8154816001600160a01b0302191690836001600160a01b03160217905550896001600160a01b0316896001600160a01b03167f40251fbfb6656cfa65a00d7879029fec1fad21d28fdcff2f4f68f52795b74f2c8a8a8a8a8a8a60405180876001600160a01b031681526020018660ff168152602001806020018060200180602001848103845288818151815260200191508051906020019080838360005b83811015610f3c578181015183820152602001610f24565b50505050905090810190601f168015610f695780820380516001836020036101000a031916815260200191505b50848103835287518152875160209182019189019080838360005b83811015610f9c578181015183820152602001610f84565b50505050905090810190601f168015610fc95780820380516001836020036101000a031916815260200191505b508481038252858152602001868680828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018290039b50909950505050505050505050a38015611031576008805460ff191690555b50505050505050505050565b600080600560019054906101000a90046001600160a01b03166001600160a01b031663fe65acfe6040518163ffffffff1660e01b815260040160206040518083038186803b15801561108e57600080fd5b505afa1580156110a2573d6000803e3d6000fd5b505050506040513d60208110156110b857600080fd5b5051604080517ffca513a800000000000000000000000000000000000000000000000000000000815290519192506000916001600160a01b0384169163fca513a8916004808301926020929190829003018186803b15801561111957600080fd5b505afa15801561112d573d6000803e3d6000fd5b505050506040513d602081101561114357600080fd5b5051600654604080517fb3596f070000000000000000000000000000000000000000000000000000000081526001600160a01b03928316600482015290519293509083169163b3596f0791602480820192602092909190829003018186803b1580156111ae57600080fd5b505afa1580156111c2573d6000803e3d6000fd5b505050506040513d60208110156111d857600080fd5b50519250505090565b6111e9610a04565b6001600160a01b03166111fa6114c7565b6001600160a01b0316146040518060400160405280600281526020017f3239000000000000000000000000000000000000000000000000000000000000815250906112865760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b50600061129383836115ae565b60408051808201909152600281527f35380000000000000000000000000000000000000000000000000000000000006020820152909150816113165760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b506113218482611892565b6040805184815290516000916001600160a01b038716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a3604080518481526020810184905281516001600160a01b038716927f49995e5dd6158cf69ad3e9777c46755a1a826a446c6416992167462dad033b2a928290030190a250505050565b6001600160a01b031660009081526020819052604090205490565b60025490565b60008215806113d9575081155b156113e657506000610935565b817ffffffffffffffffffffffffffffffffffffffffffe6268e1b017bfe18bffffff8161140f57fe5b048311156040518060400160405280600281526020017f3438000000000000000000000000000000000000000000000000000000000000815250906114955760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b50506b033b2e3c9fd0803ce800000091026b019d971e4fe8401e74000000010490565b603c546001600160a01b031690565b3390565b604080518082018252600281527f35390000000000000000000000000000000000000000000000000000000000006020808301919091526001600160a01b038087166000908152603b8352848120918716815291529182205461152f918490611937565b6001600160a01b038086166000818152603b60209081526040808320948916808452949091529020839055919250907fda919360433220e13b51e8c211e490d148e61a3bd53de8c097194e458b97f3e1611587610a83565b604080516001600160a01b039092168252602082018690528051918290030190a350505050565b60408051808201909152600281527f35300000000000000000000000000000000000000000000000000000000000006020820152600090826116315760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b506040805180820190915260028082527f343800000000000000000000000000000000000000000000000000000000000060208301528304906b033b2e3c9fd0803ce80000008219048511156116c85760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b5082816b033b2e3c9fd0803ce8000000860201816116e257fe5b04949350505050565b6001600160a01b038216611746576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b61175260008383611991565b6002546000906117629083611996565b60028190556001600160a01b0384166000908152602081905260408120549192509061178e9084611996565b6001600160a01b03851660009081526020819052604081208290559091506117b46114b8565b6001600160a01b031614611841576117ca6114b8565b6001600160a01b03166331873e2e8583856040518463ffffffff1660e01b815260040180846001600160a01b031681526020018381526020018281526020019350505050600060405180830381600087803b15801561182857600080fd5b505af115801561183c573d6000803e3d6000fd5b505050505b50505050565b600190565b303b1590565b8051611865906003906020840190611a32565b5050565b8051611865906004906020840190611a32565b6005805460ff191660ff92909216919091179055565b6001600160a01b0382166118d75760405162461bcd60e51b8152600401808060200182810382526021815260200180611b246021913960400191505060405180910390fd5b6118e382600083611991565b6002546000906118f390836119f0565b905080600281905550600061178e83604051806060016040528060228152602001611ad4602291396001600160a01b03871660009081526020819052604090205491905b600081848411156119895760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b45578181015183820152602001610b2d565b505050900390565b505050565b6000828201838110156109fd576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006109fd83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611937565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611a685760008555611aae565b82601f10611a8157805160ff1916838001178555611aae565b82800160010185558215611aae579182015b82811115611aae578251825591602001919060010190611a93565b50611aba929150611abe565b5090565b5b80821115611aba5760008155600101611abf56fe45524332303a206275726e20616d6f756e7420657863656564732062616c616e6365436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a656445524332303a206275726e2066726f6d20746865207a65726f2061646472657373a26469706673582212206d2c8a05224c77c053ea4fb944710858ded2f4c6da09abae7252c150dae7ad3d64736f6c634300070600334f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a2646970667358221220ed5c48e4e9eb368049b2c2fa7b0931aef9023290fbcdb2dd5091465e87e19d8464736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000037d913276586da1764ac1458e4d77d8570d82bb70000000000000000000000006a4905c7ea38b0f24023dfbbd6efd53c1b2f5d6d
-----Decoded View---------------
Arg [0] : _pool (address): 0x37d913276586dA1764Ac1458e4d77D8570d82Bb7
Arg [1] : _addressesProvider (address): 0x6A4905C7Ea38b0f24023dFbBd6eFd53C1b2f5D6d
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000037d913276586da1764ac1458e4d77d8570d82bb7
Arg [1] : 0000000000000000000000006a4905c7ea38b0f24023dfbbd6efd53c1b2f5d6d
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.