Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Initialize | 13803286 | 1459 days ago | IN | 0 ETH | 0.01024042 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PAaveIntegration
Compiler Version
v0.8.6+commit.11564f7e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;
import { IAaveATokenV2, IAaveLendingPoolV2, ILendingPoolAddressesProviderV2 } from "../peripheral/Aave/IAave.sol";
import { AaveV2Integration } from "../masset/peripheral/AaveV2Integration.sol";
import { IAaveIncentivesController } from "../peripheral/Aave/IAaveIncentivesController.sol";
/**
* @title PAaveIntegration
* @author mStable
* @notice A simple connection to deposit and withdraw bAssets from Aave on Polygon
* @dev VERSION: 1.0
* DATE: 2020-16-11
*/
contract PAaveIntegration is AaveV2Integration {
event RewardsClaimed(address[] assets, uint256 amount);
IAaveIncentivesController public immutable rewardController;
/**
* @param _nexus Address of the Nexus
* @param _lp Address of LP
* @param _platformAddress Generic platform address
* @param _rewardToken Reward token, if any
* @param _rewardController AaveIncentivesController
*/
constructor(
address _nexus,
address _lp,
address _platformAddress,
address _rewardToken,
address _rewardController
) AaveV2Integration(_nexus, _lp, _platformAddress, _rewardToken) {
require(_rewardController != address(0), "Invalid controller address");
rewardController = IAaveIncentivesController(_rewardController);
}
/**
* @dev Claims outstanding rewards from market
*/
function claimRewards() external {
uint256 len = bAssetsMapped.length;
address[] memory pTokens = new address[](len);
for (uint256 i = 0; i < len; i++) {
pTokens[i] = bAssetToPToken[bAssetsMapped[i]];
}
uint256 rewards = rewardController.claimRewards(pTokens, type(uint256).max, address(this));
emit RewardsClaimed(pTokens, rewards);
}
}// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;
/**
* @dev Interface for Aaves Lending Pool
* Documentation: https://developers.aave.com/#lendingpooladdressesprovider
*/
interface ILendingPoolAddressesProviderV2 {
/**
* @notice Get the current address for Aave LendingPool
* @dev Lending pool is the core contract on which to call deposit
*/
function getLendingPool() external view returns (address);
}
/**
* @dev Interface for Aaves A Token
* Documentation: https://developers.aave.com/#atokens
*/
interface IAaveATokenV2 {
/**
* @notice returns the current total aToken balance of _user all interest collected included.
* To obtain the user asset principal balance with interests excluded , ERC20 non-standard
* method principalBalanceOf() can be used.
*/
function balanceOf(address _user) external view returns (uint256);
}
interface IAaveLendingPoolV2 {
/**
* @dev deposits The underlying asset into the reserve. A corresponding amount of the overlying asset (aTokens)
* is minted.
* @param reserve the address of the reserve
* @param amount the amount to be deposited
* @param referralCode integrators are assigned a referral code and can potentially receive rewards.
**/
function deposit(
address reserve,
uint256 amount,
address onBehalfOf,
uint16 referralCode
) external;
/**
* @dev withdraws the assets of user.
* @param reserve the address of the reserve
* @param amount the underlying amount to be redeemed
* @param to address that will receive the underlying
**/
function withdraw(
address reserve,
uint256 amount,
address to
) external;
}
/** Interface for Staking AAVE Token
* Documentation: https://docs.aave.com/developers/protocol-governance/staking-aave
*/
interface IStakedAave {
function COOLDOWN_SECONDS() external returns (uint256);
function UNSTAKE_WINDOW() external returns (uint256);
function stake(address to, uint256 amount) external;
function redeem(address to, uint256 amount) external;
function cooldown() external;
function claimRewards(address to, uint256 amount) external;
function stakersCooldowns(address staker) external returns (uint256);
}// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;
// External
import { IAaveATokenV2, IAaveLendingPoolV2, ILendingPoolAddressesProviderV2 } from "../../peripheral/Aave/IAave.sol";
// Libs
import { MassetHelpers } from "../../shared/MassetHelpers.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { AbstractIntegration } from "./AbstractIntegration.sol";
/**
* @title AaveV2Integration
* @author mStable
* @notice A simple connection to deposit and withdraw bAssets from Aave
* @dev VERSION: 1.0
* DATE: 2020-16-11
*/
contract AaveV2Integration is AbstractIntegration {
using SafeERC20 for IERC20;
// Core address for the given platform */
address public immutable platformAddress;
address public immutable rewardToken;
event RewardTokenApproved(address rewardToken, address account);
/**
* @param _nexus Address of the Nexus
* @param _lp Address of LP
* @param _platformAddress Generic platform address
* @param _rewardToken Reward token, if any
*/
constructor(
address _nexus,
address _lp,
address _platformAddress,
address _rewardToken
) AbstractIntegration(_nexus, _lp) {
require(_platformAddress != address(0), "Invalid platform address");
platformAddress = _platformAddress;
rewardToken = _rewardToken;
}
/***************************************
ADMIN
****************************************/
/**
* @dev Approves Liquidator to spend reward tokens
*/
function approveRewardToken() external onlyGovernor {
address liquidator = nexus.getModule(keccak256("Liquidator"));
require(liquidator != address(0), "Liquidator address cannot be zero");
MassetHelpers.safeInfiniteApprove(rewardToken, liquidator);
emit RewardTokenApproved(rewardToken, liquidator);
}
/***************************************
CORE
****************************************/
/**
* @dev Deposit a quantity of bAsset into the platform. Credited aTokens
* remain here in the vault. Can only be called by whitelisted addresses
* (mAsset and corresponding BasketManager)
* @param _bAsset Address for the bAsset
* @param _amount Units of bAsset to deposit
* @param _hasTxFee Is the bAsset known to have a tx fee?
* @return quantityDeposited Quantity of bAsset that entered the platform
*/
function deposit(
address _bAsset,
uint256 _amount,
bool _hasTxFee
) external override onlyLP nonReentrant returns (uint256 quantityDeposited) {
require(_amount > 0, "Must deposit something");
IAaveATokenV2 aToken = _getATokenFor(_bAsset);
quantityDeposited = _amount;
if (_hasTxFee) {
// If we charge a fee, account for it
uint256 prevBal = _checkBalance(aToken);
_getLendingPool().deposit(_bAsset, _amount, address(this), 36);
uint256 newBal = _checkBalance(aToken);
quantityDeposited = _min(quantityDeposited, newBal - prevBal);
} else {
_getLendingPool().deposit(_bAsset, _amount, address(this), 36);
}
emit Deposit(_bAsset, address(aToken), quantityDeposited);
}
/**
* @dev Withdraw a quantity of bAsset from the platform
* @param _receiver Address to which the bAsset should be sent
* @param _bAsset Address of the bAsset
* @param _amount Units of bAsset to withdraw
* @param _hasTxFee Is the bAsset known to have a tx fee?
*/
function withdraw(
address _receiver,
address _bAsset,
uint256 _amount,
bool _hasTxFee
) external override onlyLP nonReentrant {
_withdraw(_receiver, _bAsset, _amount, _amount, _hasTxFee);
}
/**
* @dev Withdraw a quantity of bAsset from the platform
* @param _receiver Address to which the bAsset should be sent
* @param _bAsset Address of the bAsset
* @param _amount Units of bAsset to send to recipient
* @param _totalAmount Total units to pull from lending platform
* @param _hasTxFee Is the bAsset known to have a tx fee?
*/
function withdraw(
address _receiver,
address _bAsset,
uint256 _amount,
uint256 _totalAmount,
bool _hasTxFee
) external override onlyLP nonReentrant {
_withdraw(_receiver, _bAsset, _amount, _totalAmount, _hasTxFee);
}
/** @dev Withdraws _totalAmount from the lending pool, sending _amount to user */
function _withdraw(
address _receiver,
address _bAsset,
uint256 _amount,
uint256 _totalAmount,
bool _hasTxFee
) internal {
require(_totalAmount > 0, "Must withdraw something");
IAaveATokenV2 aToken = _getATokenFor(_bAsset);
if (_hasTxFee) {
require(_amount == _totalAmount, "Cache inactive for assets with fee");
_getLendingPool().withdraw(_bAsset, _amount, _receiver);
} else {
_getLendingPool().withdraw(_bAsset, _totalAmount, address(this));
// Send redeemed bAsset to the receiver
IERC20(_bAsset).safeTransfer(_receiver, _amount);
}
emit PlatformWithdrawal(_bAsset, address(aToken), _totalAmount, _amount);
}
/**
* @dev Withdraw a quantity of bAsset from the cache.
* @param _receiver Address to which the bAsset should be sent
* @param _bAsset Address of the bAsset
* @param _amount Units of bAsset to withdraw
*/
function withdrawRaw(
address _receiver,
address _bAsset,
uint256 _amount
) external override onlyLP nonReentrant {
require(_amount > 0, "Must withdraw something");
require(_receiver != address(0), "Must specify recipient");
IERC20(_bAsset).safeTransfer(_receiver, _amount);
emit Withdrawal(_bAsset, address(0), _amount);
}
/**
* @dev Get the total bAsset value held in the platform
* This includes any interest that was generated since depositing
* Aave gradually increases the balances of all aToken holders, as the interest grows
* @param _bAsset Address of the bAsset
* @return balance Total value of the bAsset in the platform
*/
function checkBalance(address _bAsset) external view override returns (uint256 balance) {
// balance is always with token aToken decimals
IAaveATokenV2 aToken = _getATokenFor(_bAsset);
return _checkBalance(aToken);
}
/***************************************
APPROVALS
****************************************/
/**
* @dev Internal method to respond to the addition of new bAsset / pTokens
* We need to approve the Aave lending pool core conrtact and give it permission
* to spend the bAsset
* @param _bAsset Address of the bAsset to approve
*/
function _abstractSetPToken(
address _bAsset,
address /*_pToken*/
) internal override {
address lendingPool = address(_getLendingPool());
// approve the pool to spend the bAsset
MassetHelpers.safeInfiniteApprove(_bAsset, lendingPool);
}
/***************************************
HELPERS
****************************************/
/**
* @dev Get the current address of the Aave lending pool, which is the gateway to
* depositing.
* @return Current lending pool implementation
*/
function _getLendingPool() internal view returns (IAaveLendingPoolV2) {
address lendingPool = ILendingPoolAddressesProviderV2(platformAddress).getLendingPool();
require(lendingPool != address(0), "Lending pool does not exist");
return IAaveLendingPoolV2(lendingPool);
}
/**
* @dev Get the pToken wrapped in the IAaveAToken interface for this bAsset, to use
* for withdrawing or balance checking. Fails if the pToken doesn't exist in our mappings.
* @param _bAsset Address of the bAsset
* @return aToken Corresponding to this bAsset
*/
function _getATokenFor(address _bAsset) internal view returns (IAaveATokenV2) {
address aToken = bAssetToPToken[_bAsset];
require(aToken != address(0), "aToken does not exist");
return IAaveATokenV2(aToken);
}
/**
* @dev Get the total bAsset value held in the platform
* @param _aToken aToken for which to check balance
* @return balance Total value of the bAsset in the platform
*/
function _checkBalance(IAaveATokenV2 _aToken) internal view returns (uint256 balance) {
return _aToken.balanceOf(address(this));
}
}// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.8.6;
pragma experimental ABIEncoderV2;
interface IAaveIncentivesController {
/**
* @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 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 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);
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.6;
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/**
* @title MassetHelpers
* @author mStable
* @notice Helper functions to facilitate minting and redemption from off chain
* @dev VERSION: 1.0
* DATE: 2020-03-28
*/
library MassetHelpers {
using SafeERC20 for IERC20;
function transferReturnBalance(
address _sender,
address _recipient,
address _bAsset,
uint256 _qty
) internal returns (uint256 receivedQty, uint256 recipientBalance) {
uint256 balBefore = IERC20(_bAsset).balanceOf(_recipient);
IERC20(_bAsset).safeTransferFrom(_sender, _recipient, _qty);
recipientBalance = IERC20(_bAsset).balanceOf(_recipient);
receivedQty = recipientBalance - balBefore;
}
function safeInfiniteApprove(address _asset, address _spender) internal {
IERC20(_asset).safeApprove(_spender, 0);
IERC20(_asset).safeApprove(_spender, 2**256 - 1);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;
import { IPlatformIntegration } from "../../interfaces/IPlatformIntegration.sol";
import { ImmutableModule } from "../../shared/ImmutableModule.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
/**
* @title AbstractIntegration
* @author mStable
* @notice A generalised platform integration contract from which to inherit
* @dev Contains functionality for managing access to a specific lending
* platform. pTokens are the generic name given to platform tokens e.g. cDai
* Governance are responsible for setting platform and pToken addresses.
*/
abstract contract AbstractIntegration is
IPlatformIntegration,
Initializable,
ImmutableModule,
ReentrancyGuard
{
event PTokenAdded(address indexed _bAsset, address _pToken);
event Deposit(address indexed _bAsset, address _pToken, uint256 _amount);
event Withdrawal(address indexed _bAsset, address _pToken, uint256 _amount);
event PlatformWithdrawal(
address indexed bAsset,
address pToken,
uint256 totalAmount,
uint256 userAmount
);
/// @notice mAsset or Feeder Pool using the integration. eg fPmUSD/alUSD
/// @dev LP has write access
address public immutable lpAddress;
// bAsset => pToken (Platform Specific Token Address)
mapping(address => address) public bAssetToPToken;
// Full list of all bAssets supported here
address[] internal bAssetsMapped;
/**
* @param _nexus Address of the Nexus
* @param _lp Address of LP
*/
constructor(address _nexus, address _lp) ReentrancyGuard() ImmutableModule(_nexus) {
require(_lp != address(0), "Invalid LP address");
lpAddress = _lp;
}
/**
* @dev Simple initializer to set first bAsset/pTokens
*/
function initialize(address[] calldata _bAssets, address[] calldata _pTokens)
public
initializer
{
uint256 len = _bAssets.length;
require(len == _pTokens.length, "Invalid inputs");
for (uint256 i = 0; i < len; i++) {
_setPTokenAddress(_bAssets[i], _pTokens[i]);
}
}
/**
* @dev Modifier to allow function calls only from the Governor.
*/
modifier onlyLP() {
require(msg.sender == lpAddress, "Only the LP can execute");
_;
}
/***************************************
CONFIG
****************************************/
/**
* @dev Provide support for bAsset by passing its pToken address.
* This method can only be called by the system Governor
* @param _bAsset Address for the bAsset
* @param _pToken Address for the corresponding platform token
*/
function setPTokenAddress(address _bAsset, address _pToken) external onlyGovernor {
_setPTokenAddress(_bAsset, _pToken);
}
/**
* @dev Provide support for bAsset by passing its pToken address.
* Add to internal mappings and execute the platform specific,
* abstract method `_abstractSetPToken`
* @param _bAsset Address for the bAsset
* @param _pToken Address for the corresponding platform token
*/
function _setPTokenAddress(address _bAsset, address _pToken) internal {
require(bAssetToPToken[_bAsset] == address(0), "pToken already set");
require(_bAsset != address(0) && _pToken != address(0), "Invalid addresses");
bAssetToPToken[_bAsset] = _pToken;
bAssetsMapped.push(_bAsset);
emit PTokenAdded(_bAsset, _pToken);
_abstractSetPToken(_bAsset, _pToken);
}
function _abstractSetPToken(address _bAsset, address _pToken) internal virtual;
/**
* @dev Simple helper func to get the min of two values
*/
function _min(uint256 x, uint256 y) internal pure returns (uint256) {
return x > y ? y : x;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.6;
/**
* @title Platform interface to integrate with lending platform like Compound, AAVE etc.
*/
interface IPlatformIntegration {
/**
* @dev Deposit the given bAsset to Lending platform
* @param _bAsset bAsset address
* @param _amount Amount to deposit
*/
function deposit(
address _bAsset,
uint256 _amount,
bool isTokenFeeCharged
) external returns (uint256 quantityDeposited);
/**
* @dev Withdraw given bAsset from Lending platform
*/
function withdraw(
address _receiver,
address _bAsset,
uint256 _amount,
bool _hasTxFee
) external;
/**
* @dev Withdraw given bAsset from Lending platform
*/
function withdraw(
address _receiver,
address _bAsset,
uint256 _amount,
uint256 _totalAmount,
bool _hasTxFee
) external;
/**
* @dev Withdraw given bAsset from the cache
*/
function withdrawRaw(
address _receiver,
address _bAsset,
uint256 _amount
) external;
/**
* @dev Returns the current balance of the given bAsset
*/
function checkBalance(address _bAsset) external returns (uint256 balance);
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.6;
import { ModuleKeys } from "./ModuleKeys.sol";
import { INexus } from "../interfaces/INexus.sol";
/**
* @title ImmutableModule
* @author mStable
* @dev Subscribes to module updates from a given publisher and reads from its registry.
* Contract is used for upgradable proxy contracts.
*/
abstract contract ImmutableModule is ModuleKeys {
INexus public immutable nexus;
/**
* @dev Initialization function for upgradable proxy contracts
* @param _nexus Nexus contract address
*/
constructor(address _nexus) {
require(_nexus != address(0), "Nexus address is zero");
nexus = INexus(_nexus);
}
/**
* @dev Modifier to allow function calls only from the Governor.
*/
modifier onlyGovernor() {
_onlyGovernor();
_;
}
function _onlyGovernor() internal view {
require(msg.sender == _governor(), "Only governor can execute");
}
/**
* @dev Modifier to allow function calls only from the Governor or the Keeper EOA.
*/
modifier onlyKeeperOrGovernor() {
_keeperOrGovernor();
_;
}
function _keeperOrGovernor() internal view {
require(msg.sender == _keeper() || msg.sender == _governor(), "Only keeper or governor");
}
/**
* @dev Modifier to allow function calls only from the Governance.
* Governance is either Governor address or Governance address.
*/
modifier onlyGovernance() {
require(
msg.sender == _governor() || msg.sender == _governance(),
"Only governance can execute"
);
_;
}
/**
* @dev Returns Governor address from the Nexus
* @return Address of Governor Contract
*/
function _governor() internal view returns (address) {
return nexus.governor();
}
/**
* @dev Returns Governance Module address from the Nexus
* @return Address of the Governance (Phase 2)
*/
function _governance() internal view returns (address) {
return nexus.getModule(KEY_GOVERNANCE);
}
/**
* @dev Return Keeper address from the Nexus.
* This account is used for operational transactions that
* don't need multiple signatures.
* @return Address of the Keeper externally owned account.
*/
function _keeper() internal view returns (address) {
return nexus.getModule(KEY_KEEPER);
}
/**
* @dev Return SavingsManager Module address from the Nexus
* @return Address of the SavingsManager Module contract
*/
function _savingsManager() internal view returns (address) {
return nexus.getModule(KEY_SAVINGS_MANAGER);
}
/**
* @dev Return Recollateraliser Module address from the Nexus
* @return Address of the Recollateraliser Module contract (Phase 2)
*/
function _recollateraliser() internal view returns (address) {
return nexus.getModule(KEY_RECOLLATERALISER);
}
/**
* @dev Return Liquidator Module address from the Nexus
* @return Address of the Liquidator Module contract
*/
function _liquidator() internal view returns (address) {
return nexus.getModule(KEY_LIQUIDATOR);
}
/**
* @dev Return ProxyAdmin Module address from the Nexus
* @return Address of the ProxyAdmin Module contract
*/
function _proxyAdmin() internal view returns (address) {
return nexus.getModule(KEY_PROXY_ADMIN);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
require(_initializing || !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.6;
/**
* @title ModuleKeys
* @author mStable
* @notice Provides system wide access to the byte32 represntations of system modules
* This allows each system module to be able to reference and update one another in a
* friendly way
* @dev keccak256() values are hardcoded to avoid re-evaluation of the constants at runtime.
*/
contract ModuleKeys {
// Governance
// ===========
// keccak256("Governance");
bytes32 internal constant KEY_GOVERNANCE =
0x9409903de1e6fd852dfc61c9dacb48196c48535b60e25abf92acc92dd689078d;
//keccak256("Staking");
bytes32 internal constant KEY_STAKING =
0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034;
//keccak256("ProxyAdmin");
bytes32 internal constant KEY_PROXY_ADMIN =
0x96ed0203eb7e975a4cbcaa23951943fa35c5d8288117d50c12b3d48b0fab48d1;
// mStable
// =======
// keccak256("OracleHub");
bytes32 internal constant KEY_ORACLE_HUB =
0x8ae3a082c61a7379e2280f3356a5131507d9829d222d853bfa7c9fe1200dd040;
// keccak256("Manager");
bytes32 internal constant KEY_MANAGER =
0x6d439300980e333f0256d64be2c9f67e86f4493ce25f82498d6db7f4be3d9e6f;
//keccak256("Recollateraliser");
bytes32 internal constant KEY_RECOLLATERALISER =
0x39e3ed1fc335ce346a8cbe3e64dd525cf22b37f1e2104a755e761c3c1eb4734f;
//keccak256("MetaToken");
bytes32 internal constant KEY_META_TOKEN =
0xea7469b14936af748ee93c53b2fe510b9928edbdccac3963321efca7eb1a57a2;
// keccak256("SavingsManager");
bytes32 internal constant KEY_SAVINGS_MANAGER =
0x12fe936c77a1e196473c4314f3bed8eeac1d757b319abb85bdda70df35511bf1;
// keccak256("Liquidator");
bytes32 internal constant KEY_LIQUIDATOR =
0x1e9cb14d7560734a61fa5ff9273953e971ff3cd9283c03d8346e3264617933d4;
// keccak256("InterestValidator");
bytes32 internal constant KEY_INTEREST_VALIDATOR =
0xc10a28f028c7f7282a03c90608e38a4a646e136e614e4b07d119280c5f7f839f;
// keccak256("Keeper");
bytes32 internal constant KEY_KEEPER =
0x4f78afe9dfc9a0cb0441c27b9405070cd2a48b490636a7bdd09f355e33a5d7de;
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.6;
/**
* @title INexus
* @dev Basic interface for interacting with the Nexus i.e. SystemKernel
*/
interface INexus {
function governor() external view returns (address);
function getModule(bytes32 key) external view returns (address);
function proposeModule(bytes32 _key, address _addr) external;
function cancelProposedModule(bytes32 _key) external;
function acceptProposedModule(bytes32 _key) external;
function acceptProposedModules(bytes32[] calldata _keys) external;
function requestLockModule(bytes32 _key) external;
function cancelLockModule(bytes32 _key) external;
function lockModule(bytes32 _key) external;
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_nexus","type":"address"},{"internalType":"address","name":"_lp","type":"address"},{"internalType":"address","name":"_platformAddress","type":"address"},{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_rewardController","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_bAsset","type":"address"},{"indexed":false,"internalType":"address","name":"_pToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_bAsset","type":"address"},{"indexed":false,"internalType":"address","name":"_pToken","type":"address"}],"name":"PTokenAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bAsset","type":"address"},{"indexed":false,"internalType":"address","name":"pToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userAmount","type":"uint256"}],"name":"PlatformWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rewardToken","type":"address"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"RewardTokenApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"assets","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_bAsset","type":"address"},{"indexed":false,"internalType":"address","name":"_pToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Withdrawal","type":"event"},{"inputs":[],"name":"approveRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bAssetToPToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_bAsset","type":"address"}],"name":"checkBalance","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bAsset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_hasTxFee","type":"bool"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"quantityDeposited","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_bAssets","type":"address[]"},{"internalType":"address[]","name":"_pTokens","type":"address[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lpAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nexus","outputs":[{"internalType":"contract INexus","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardController","outputs":[{"internalType":"contract IAaveIncentivesController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_bAsset","type":"address"},{"internalType":"address","name":"_pToken","type":"address"}],"name":"setPTokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"address","name":"_bAsset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_hasTxFee","type":"bool"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"address","name":"_bAsset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_totalAmount","type":"uint256"},{"internalType":"bool","name":"_hasTxFee","type":"bool"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"address","name":"_bAsset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawRaw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6101206040523480156200001257600080fd5b5060405162001efb38038062001efb83398101604081905262000035916200020e565b848484848383816001600160a01b038116620000985760405162461bcd60e51b815260206004820152601560248201527f4e657875732061646472657373206973207a65726f000000000000000000000060448201526064015b60405180910390fd5b60601b6001600160601b031916608052600180556001600160a01b038116620000f95760405162461bcd60e51b8152602060048201526012602482015271496e76616c6964204c50206164647265737360701b60448201526064016200008f565b60601b6001600160601b03191660a052506001600160a01b038216620001625760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420706c6174666f726d2061646472657373000000000000000060448201526064016200008f565b6001600160601b0319606092831b811660c052911b1660e05250506001600160a01b038116620001d55760405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420636f6e74726f6c6c6572206164647265737300000000000060448201526064016200008f565b60601b6001600160601b03191661010052506200027e92505050565b80516001600160a01b03811681146200020957600080fd5b919050565b600080600080600060a086880312156200022757600080fd5b6200023286620001f1565b94506200024260208701620001f1565b93506200025260408701620001f1565b92506200026260608701620001f1565b91506200027260808701620001f1565b90509295509295909350565b60805160601c60a05160601c60c05160601c60e05160601c6101005160601c611be362000318600039600081816101a901526103b001526000818161028601528181610bf80152610c2b0152600081816102570152610f390152600081816101e30152818161048a01528181610863015281816108ea0152610a5201526000818161020a01528181610b0f01526112df0152611be36000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063934785b711610097578063c89fc72f11610066578063c89fc72f1461023f578063dbe55e5614610252578063e729645414610279578063f7c618c11461028157600080fd5b8063934785b7146101cb5780639b4dc8cc146101de578063a3f5c1d214610205578063a4e285951461022c57600080fd5b80635f515226116100d35780635f5152261461013d57806371c465851461015057806373cf25f8146101915780638cc5ce99146101a457600080fd5b80630ed57b3a146100fa578063372500ab1461010f5780633edd112814610117575b600080fd5b61010d61010836600461177d565b6102a8565b005b61010d6102be565b61012a6101253660046118a9565b61047d565b6040519081526020015b60405180910390f35b61012a61014b366004611743565b6106cd565b61017961015e366004611743565b6002602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610134565b61010d61019f3660046118eb565b6106eb565b6101797f000000000000000000000000000000000000000000000000000000000000000081565b61010d6101d93660046117f7565b610858565b6101797f000000000000000000000000000000000000000000000000000000000000000081565b6101797f000000000000000000000000000000000000000000000000000000000000000081565b61010d61023a3660046117b6565b6108df565b61010d61024d36600461184a565b610a47565b6101797f000000000000000000000000000000000000000000000000000000000000000081565b61010d610acf565b6101797f000000000000000000000000000000000000000000000000000000000000000081565b6102b0610c83565b6102ba8282610ced565b5050565b60035460008167ffffffffffffffff8111156102dc576102dc611b71565b604051908082528060200260200182016040528015610305578160200160208202803683370190505b50905060005b8281101561039557600260006003838154811061032a5761032a611b5b565b60009182526020808320909101546001600160a01b039081168452908301939093526040909101902054835191169083908390811061036b5761036b611b5b565b6001600160a01b03909216602092830291909101909101528061038d81611b2a565b91505061030b565b50604051633111e7b360e01b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633111e7b3906103eb908590600019903090600401611a0f565b602060405180830381600087803b15801561040557600080fd5b505af1158015610419573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043d9190611974565b90507fdfcc08fd436cd72ca789d668ae3ee67528136f98c501b1b51796de133fe3bf7a82826040516104709291906119ed565b60405180910390a1505050565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104d05760405162461bcd60e51b81526004016104c790611a75565b60405180910390fd5b600260015414156104f35760405162461bcd60e51b81526004016104c790611aac565b60026001558261053e5760405162461bcd60e51b81526020600482015260166024820152754d757374206465706f73697420736f6d657468696e6760501b60448201526064016104c7565b600061054985610e52565b9050839150821561060257600061055f82610eba565b9050610569610f34565b60405163e8eda9df60e01b81526001600160a01b03888116600483015260248281018990523060448401526064830152919091169063e8eda9df90608401600060405180830381600087803b1580156105c157600080fd5b505af11580156105d5573d6000803e3d6000fd5b5050505060006105e483610eba565b90506105f9846105f48484611ae3565b611025565b9350505061067b565b61060a610f34565b60405163e8eda9df60e01b81526001600160a01b03878116600483015260248281018890523060448401526064830152919091169063e8eda9df90608401600060405180830381600087803b15801561066257600080fd5b505af1158015610676573d6000803e3d6000fd5b505050505b604080516001600160a01b038381168252602082018590528716917f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62910160405180910390a250600180559392505050565b6000806106d983610e52565b90506106e481610eba565b9392505050565b600054610100900460ff1680610704575060005460ff16155b6107675760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016104c7565b600054610100900460ff16158015610789576000805461ffff19166101011790555b838281146107ca5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420696e7075747360901b60448201526064016104c7565b60005b8181101561083d5761082b8787838181106107ea576107ea611b5b565b90506020020160208101906107ff9190611743565b86868481811061081157610811611b5b565b90506020020160208101906108269190611743565b610ced565b8061083581611b2a565b9150506107cd565b50508015610851576000805461ff00191690555b5050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108a05760405162461bcd60e51b81526004016104c790611a75565b600260015414156108c35760405162461bcd60e51b81526004016104c790611aac565b60026001556108d5848484808561103a565b5050600180555050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109275760405162461bcd60e51b81526004016104c790611a75565b6002600154141561094a5760405162461bcd60e51b81526004016104c790611aac565b6002600155806109965760405162461bcd60e51b81526020600482015260176024820152764d75737420776974686472617720736f6d657468696e6760481b60448201526064016104c7565b6001600160a01b0383166109e55760405162461bcd60e51b8152602060048201526016602482015275135d5cdd081cdc1958da599e481c9958da5c1a595b9d60521b60448201526064016104c7565b6109f96001600160a01b0383168483611248565b6040805160008152602081018390526001600160a01b038416917f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b6398910160405180910390a250506001805550565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a8f5760405162461bcd60e51b81526004016104c790611a75565b60026001541415610ab25760405162461bcd60e51b81526004016104c790611aac565b6002600155610ac4858585858561103a565b505060018055505050565b610ad7610c83565b6040516385acd64160e01b81527f1e9cb14d7560734a61fa5ff9273953e971ff3cd9283c03d8346e3264617933d460048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906385acd6419060240160206040518083038186803b158015610b5957600080fd5b505afa158015610b6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b919190611760565b90506001600160a01b038116610bf35760405162461bcd60e51b815260206004820152602160248201527f4c697175696461746f7220616464726573732063616e6e6f74206265207a65726044820152606f60f81b60648201526084016104c7565b610c1d7f0000000000000000000000000000000000000000000000000000000000000000826112b0565b604080516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081168252831660208201527f71b4effce66e58c9e4ad29e468e7100f7e8b5d106381fd905a25eee3ea1b6a93910160405180910390a150565b610c8b6112db565b6001600160a01b0316336001600160a01b031614610ceb5760405162461bcd60e51b815260206004820152601960248201527f4f6e6c7920676f7665726e6f722063616e20657865637574650000000000000060448201526064016104c7565b565b6001600160a01b038281166000908152600260205260409020541615610d4a5760405162461bcd60e51b81526020600482015260126024820152711c151bdad95b88185b1c9958591e481cd95d60721b60448201526064016104c7565b6001600160a01b03821615801590610d6a57506001600160a01b03811615155b610daa5760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642061646472657373657360781b60448201526064016104c7565b6001600160a01b03828116600081815260026020908152604080832080549587166001600160a01b031996871681179091556003805460018101825594527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b90930180549095168417909455925190815290917fef6485b84315f9b1483beffa32aae9a0596890395e3d7521f1c5fbb51790e765910160405180910390a26102ba8282611373565b6001600160a01b0380821660009081526002602052604081205490911680610eb45760405162461bcd60e51b815260206004820152601560248201527418551bdad95b88191bd95cc81b9bdd08195e1a5cdd605a1b60448201526064016104c7565b92915050565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b158015610efc57600080fd5b505afa158015610f10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb49190611974565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f9057600080fd5b505afa158015610fa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc89190611760565b90506001600160a01b0381166110205760405162461bcd60e51b815260206004820152601b60248201527f4c656e64696e6720706f6f6c20646f6573206e6f74206578697374000000000060448201526064016104c7565b919050565b600081831161103457826106e4565b50919050565b600082116110845760405162461bcd60e51b81526020600482015260176024820152764d75737420776974686472617720736f6d657468696e6760481b60448201526064016104c7565b600061108f85610e52565b9050811561116a578284146110f15760405162461bcd60e51b815260206004820152602260248201527f436163686520696e61637469766520666f722061737365747320776974682066604482015261656560f01b60648201526084016104c7565b6110f9610f34565b604051631a4ca37b60e21b81526001600160a01b03878116600483015260248201879052888116604483015291909116906369328dec90606401600060405180830381600087803b15801561114d57600080fd5b505af1158015611161573d6000803e3d6000fd5b505050506111f1565b611172610f34565b604051631a4ca37b60e21b81526001600160a01b0387811660048301526024820186905230604483015291909116906369328dec90606401600060405180830381600087803b1580156111c457600080fd5b505af11580156111d8573d6000803e3d6000fd5b506111f1925050506001600160a01b0386168786611248565b604080516001600160a01b03838116825260208201869052918101869052908616907fb925ac01b9c34cc156a17a1e3da718f364df34eec9d0c9dc4e59c2bb1e7ba54b9060600160405180910390a2505050505050565b6040516001600160a01b0383166024820152604481018290526112ab90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611389565b505050565b6112c56001600160a01b03831682600061145b565b6102ba6001600160a01b0383168260001961145b565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561133657600080fd5b505afa15801561134a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136e9190611760565b905090565b600061137d610f34565b90506112ab83826112b0565b60006113de826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661157f9092919063ffffffff16565b8051909150156112ab57808060200190518101906113fc9190611957565b6112ab5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016104c7565b8015806114e45750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156114aa57600080fd5b505afa1580156114be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e29190611974565b155b61154f5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016104c7565b6040516001600160a01b0383166024820152604481018290526112ab90849063095ea7b360e01b90606401611274565b606061158e8484600085611596565b949350505050565b6060824710156115f75760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016104c7565b843b6116455760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104c7565b600080866001600160a01b0316858760405161166191906119d1565b60006040518083038185875af1925050503d806000811461169e576040519150601f19603f3d011682016040523d82523d6000602084013e6116a3565b606091505b50915091506116b38282866116be565b979650505050505050565b606083156116cd5750816106e4565b8251156116dd5782518084602001fd5b8160405162461bcd60e51b81526004016104c79190611a42565b60008083601f84011261170957600080fd5b50813567ffffffffffffffff81111561172157600080fd5b6020830191508360208260051b850101111561173c57600080fd5b9250929050565b60006020828403121561175557600080fd5b81356106e481611b87565b60006020828403121561177257600080fd5b81516106e481611b87565b6000806040838503121561179057600080fd5b823561179b81611b87565b915060208301356117ab81611b87565b809150509250929050565b6000806000606084860312156117cb57600080fd5b83356117d681611b87565b925060208401356117e681611b87565b929592945050506040919091013590565b6000806000806080858703121561180d57600080fd5b843561181881611b87565b9350602085013561182881611b87565b925060408501359150606085013561183f81611b9f565b939692955090935050565b600080600080600060a0868803121561186257600080fd5b853561186d81611b87565b9450602086013561187d81611b87565b93506040860135925060608601359150608086013561189b81611b9f565b809150509295509295909350565b6000806000606084860312156118be57600080fd5b83356118c981611b87565b92506020840135915060408401356118e081611b9f565b809150509250925092565b6000806000806040858703121561190157600080fd5b843567ffffffffffffffff8082111561191957600080fd5b611925888389016116f7565b9096509450602087013591508082111561193e57600080fd5b5061194b878288016116f7565b95989497509550505050565b60006020828403121561196957600080fd5b81516106e481611b9f565b60006020828403121561198657600080fd5b5051919050565b600081518084526020808501945080840160005b838110156119c65781516001600160a01b0316875295820195908201906001016119a1565b509495945050505050565b600082516119e3818460208701611afa565b9190910192915050565b604081526000611a00604083018561198d565b90508260208301529392505050565b606081526000611a22606083018661198d565b6020830194909452506001600160a01b0391909116604090910152919050565b6020815260008251806020840152611a61816040850160208701611afa565b601f01601f19169190910160400192915050565b60208082526017908201527f4f6e6c7920746865204c502063616e2065786563757465000000000000000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600082821015611af557611af5611b45565b500390565b60005b83811015611b15578181015183820152602001611afd565b83811115611b24576000848401525b50505050565b6000600019821415611b3e57611b3e611b45565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611b9c57600080fd5b50565b8015158114611b9c57600080fdfea2646970667358221220852d819d90e9c4eaf423206e72867265b8ba41bd8bf8eb99f408b844fad8c64e64736f6c63430008060033000000000000000000000000afce80b19a8ce13dec0739a1aab7a028d6845eb30000000000000000000000002f1423d27f9b20058d9d1843e342726fdf985eb4000000000000000000000000b53c1a33016b2dc2ff3653530bff1848a515c8c50000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5000000000000000000000000d784927ff2f95ba542bfc824c8a8a98f3495f6b5
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100f55760003560e01c8063934785b711610097578063c89fc72f11610066578063c89fc72f1461023f578063dbe55e5614610252578063e729645414610279578063f7c618c11461028157600080fd5b8063934785b7146101cb5780639b4dc8cc146101de578063a3f5c1d214610205578063a4e285951461022c57600080fd5b80635f515226116100d35780635f5152261461013d57806371c465851461015057806373cf25f8146101915780638cc5ce99146101a457600080fd5b80630ed57b3a146100fa578063372500ab1461010f5780633edd112814610117575b600080fd5b61010d61010836600461177d565b6102a8565b005b61010d6102be565b61012a6101253660046118a9565b61047d565b6040519081526020015b60405180910390f35b61012a61014b366004611743565b6106cd565b61017961015e366004611743565b6002602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610134565b61010d61019f3660046118eb565b6106eb565b6101797f000000000000000000000000d784927ff2f95ba542bfc824c8a8a98f3495f6b581565b61010d6101d93660046117f7565b610858565b6101797f0000000000000000000000002f1423d27f9b20058d9d1843e342726fdf985eb481565b6101797f000000000000000000000000afce80b19a8ce13dec0739a1aab7a028d6845eb381565b61010d61023a3660046117b6565b6108df565b61010d61024d36600461184a565b610a47565b6101797f000000000000000000000000b53c1a33016b2dc2ff3653530bff1848a515c8c581565b61010d610acf565b6101797f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f581565b6102b0610c83565b6102ba8282610ced565b5050565b60035460008167ffffffffffffffff8111156102dc576102dc611b71565b604051908082528060200260200182016040528015610305578160200160208202803683370190505b50905060005b8281101561039557600260006003838154811061032a5761032a611b5b565b60009182526020808320909101546001600160a01b039081168452908301939093526040909101902054835191169083908390811061036b5761036b611b5b565b6001600160a01b03909216602092830291909101909101528061038d81611b2a565b91505061030b565b50604051633111e7b360e01b81526000906001600160a01b037f000000000000000000000000d784927ff2f95ba542bfc824c8a8a98f3495f6b51690633111e7b3906103eb908590600019903090600401611a0f565b602060405180830381600087803b15801561040557600080fd5b505af1158015610419573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043d9190611974565b90507fdfcc08fd436cd72ca789d668ae3ee67528136f98c501b1b51796de133fe3bf7a82826040516104709291906119ed565b60405180910390a1505050565b6000336001600160a01b037f0000000000000000000000002f1423d27f9b20058d9d1843e342726fdf985eb416146104d05760405162461bcd60e51b81526004016104c790611a75565b60405180910390fd5b600260015414156104f35760405162461bcd60e51b81526004016104c790611aac565b60026001558261053e5760405162461bcd60e51b81526020600482015260166024820152754d757374206465706f73697420736f6d657468696e6760501b60448201526064016104c7565b600061054985610e52565b9050839150821561060257600061055f82610eba565b9050610569610f34565b60405163e8eda9df60e01b81526001600160a01b03888116600483015260248281018990523060448401526064830152919091169063e8eda9df90608401600060405180830381600087803b1580156105c157600080fd5b505af11580156105d5573d6000803e3d6000fd5b5050505060006105e483610eba565b90506105f9846105f48484611ae3565b611025565b9350505061067b565b61060a610f34565b60405163e8eda9df60e01b81526001600160a01b03878116600483015260248281018890523060448401526064830152919091169063e8eda9df90608401600060405180830381600087803b15801561066257600080fd5b505af1158015610676573d6000803e3d6000fd5b505050505b604080516001600160a01b038381168252602082018590528716917f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62910160405180910390a250600180559392505050565b6000806106d983610e52565b90506106e481610eba565b9392505050565b600054610100900460ff1680610704575060005460ff16155b6107675760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016104c7565b600054610100900460ff16158015610789576000805461ffff19166101011790555b838281146107ca5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420696e7075747360901b60448201526064016104c7565b60005b8181101561083d5761082b8787838181106107ea576107ea611b5b565b90506020020160208101906107ff9190611743565b86868481811061081157610811611b5b565b90506020020160208101906108269190611743565b610ced565b8061083581611b2a565b9150506107cd565b50508015610851576000805461ff00191690555b5050505050565b336001600160a01b037f0000000000000000000000002f1423d27f9b20058d9d1843e342726fdf985eb416146108a05760405162461bcd60e51b81526004016104c790611a75565b600260015414156108c35760405162461bcd60e51b81526004016104c790611aac565b60026001556108d5848484808561103a565b5050600180555050565b336001600160a01b037f0000000000000000000000002f1423d27f9b20058d9d1843e342726fdf985eb416146109275760405162461bcd60e51b81526004016104c790611a75565b6002600154141561094a5760405162461bcd60e51b81526004016104c790611aac565b6002600155806109965760405162461bcd60e51b81526020600482015260176024820152764d75737420776974686472617720736f6d657468696e6760481b60448201526064016104c7565b6001600160a01b0383166109e55760405162461bcd60e51b8152602060048201526016602482015275135d5cdd081cdc1958da599e481c9958da5c1a595b9d60521b60448201526064016104c7565b6109f96001600160a01b0383168483611248565b6040805160008152602081018390526001600160a01b038416917f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b6398910160405180910390a250506001805550565b336001600160a01b037f0000000000000000000000002f1423d27f9b20058d9d1843e342726fdf985eb41614610a8f5760405162461bcd60e51b81526004016104c790611a75565b60026001541415610ab25760405162461bcd60e51b81526004016104c790611aac565b6002600155610ac4858585858561103a565b505060018055505050565b610ad7610c83565b6040516385acd64160e01b81527f1e9cb14d7560734a61fa5ff9273953e971ff3cd9283c03d8346e3264617933d460048201526000907f000000000000000000000000afce80b19a8ce13dec0739a1aab7a028d6845eb36001600160a01b0316906385acd6419060240160206040518083038186803b158015610b5957600080fd5b505afa158015610b6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b919190611760565b90506001600160a01b038116610bf35760405162461bcd60e51b815260206004820152602160248201527f4c697175696461746f7220616464726573732063616e6e6f74206265207a65726044820152606f60f81b60648201526084016104c7565b610c1d7f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5826112b0565b604080516001600160a01b037f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f581168252831660208201527f71b4effce66e58c9e4ad29e468e7100f7e8b5d106381fd905a25eee3ea1b6a93910160405180910390a150565b610c8b6112db565b6001600160a01b0316336001600160a01b031614610ceb5760405162461bcd60e51b815260206004820152601960248201527f4f6e6c7920676f7665726e6f722063616e20657865637574650000000000000060448201526064016104c7565b565b6001600160a01b038281166000908152600260205260409020541615610d4a5760405162461bcd60e51b81526020600482015260126024820152711c151bdad95b88185b1c9958591e481cd95d60721b60448201526064016104c7565b6001600160a01b03821615801590610d6a57506001600160a01b03811615155b610daa5760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642061646472657373657360781b60448201526064016104c7565b6001600160a01b03828116600081815260026020908152604080832080549587166001600160a01b031996871681179091556003805460018101825594527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b90930180549095168417909455925190815290917fef6485b84315f9b1483beffa32aae9a0596890395e3d7521f1c5fbb51790e765910160405180910390a26102ba8282611373565b6001600160a01b0380821660009081526002602052604081205490911680610eb45760405162461bcd60e51b815260206004820152601560248201527418551bdad95b88191bd95cc81b9bdd08195e1a5cdd605a1b60448201526064016104c7565b92915050565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b158015610efc57600080fd5b505afa158015610f10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb49190611974565b6000807f000000000000000000000000b53c1a33016b2dc2ff3653530bff1848a515c8c56001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f9057600080fd5b505afa158015610fa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc89190611760565b90506001600160a01b0381166110205760405162461bcd60e51b815260206004820152601b60248201527f4c656e64696e6720706f6f6c20646f6573206e6f74206578697374000000000060448201526064016104c7565b919050565b600081831161103457826106e4565b50919050565b600082116110845760405162461bcd60e51b81526020600482015260176024820152764d75737420776974686472617720736f6d657468696e6760481b60448201526064016104c7565b600061108f85610e52565b9050811561116a578284146110f15760405162461bcd60e51b815260206004820152602260248201527f436163686520696e61637469766520666f722061737365747320776974682066604482015261656560f01b60648201526084016104c7565b6110f9610f34565b604051631a4ca37b60e21b81526001600160a01b03878116600483015260248201879052888116604483015291909116906369328dec90606401600060405180830381600087803b15801561114d57600080fd5b505af1158015611161573d6000803e3d6000fd5b505050506111f1565b611172610f34565b604051631a4ca37b60e21b81526001600160a01b0387811660048301526024820186905230604483015291909116906369328dec90606401600060405180830381600087803b1580156111c457600080fd5b505af11580156111d8573d6000803e3d6000fd5b506111f1925050506001600160a01b0386168786611248565b604080516001600160a01b03838116825260208201869052918101869052908616907fb925ac01b9c34cc156a17a1e3da718f364df34eec9d0c9dc4e59c2bb1e7ba54b9060600160405180910390a2505050505050565b6040516001600160a01b0383166024820152604481018290526112ab90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611389565b505050565b6112c56001600160a01b03831682600061145b565b6102ba6001600160a01b0383168260001961145b565b60007f000000000000000000000000afce80b19a8ce13dec0739a1aab7a028d6845eb36001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561133657600080fd5b505afa15801561134a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136e9190611760565b905090565b600061137d610f34565b90506112ab83826112b0565b60006113de826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661157f9092919063ffffffff16565b8051909150156112ab57808060200190518101906113fc9190611957565b6112ab5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016104c7565b8015806114e45750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156114aa57600080fd5b505afa1580156114be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e29190611974565b155b61154f5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016104c7565b6040516001600160a01b0383166024820152604481018290526112ab90849063095ea7b360e01b90606401611274565b606061158e8484600085611596565b949350505050565b6060824710156115f75760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016104c7565b843b6116455760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104c7565b600080866001600160a01b0316858760405161166191906119d1565b60006040518083038185875af1925050503d806000811461169e576040519150601f19603f3d011682016040523d82523d6000602084013e6116a3565b606091505b50915091506116b38282866116be565b979650505050505050565b606083156116cd5750816106e4565b8251156116dd5782518084602001fd5b8160405162461bcd60e51b81526004016104c79190611a42565b60008083601f84011261170957600080fd5b50813567ffffffffffffffff81111561172157600080fd5b6020830191508360208260051b850101111561173c57600080fd5b9250929050565b60006020828403121561175557600080fd5b81356106e481611b87565b60006020828403121561177257600080fd5b81516106e481611b87565b6000806040838503121561179057600080fd5b823561179b81611b87565b915060208301356117ab81611b87565b809150509250929050565b6000806000606084860312156117cb57600080fd5b83356117d681611b87565b925060208401356117e681611b87565b929592945050506040919091013590565b6000806000806080858703121561180d57600080fd5b843561181881611b87565b9350602085013561182881611b87565b925060408501359150606085013561183f81611b9f565b939692955090935050565b600080600080600060a0868803121561186257600080fd5b853561186d81611b87565b9450602086013561187d81611b87565b93506040860135925060608601359150608086013561189b81611b9f565b809150509295509295909350565b6000806000606084860312156118be57600080fd5b83356118c981611b87565b92506020840135915060408401356118e081611b9f565b809150509250925092565b6000806000806040858703121561190157600080fd5b843567ffffffffffffffff8082111561191957600080fd5b611925888389016116f7565b9096509450602087013591508082111561193e57600080fd5b5061194b878288016116f7565b95989497509550505050565b60006020828403121561196957600080fd5b81516106e481611b9f565b60006020828403121561198657600080fd5b5051919050565b600081518084526020808501945080840160005b838110156119c65781516001600160a01b0316875295820195908201906001016119a1565b509495945050505050565b600082516119e3818460208701611afa565b9190910192915050565b604081526000611a00604083018561198d565b90508260208301529392505050565b606081526000611a22606083018661198d565b6020830194909452506001600160a01b0391909116604090910152919050565b6020815260008251806020840152611a61816040850160208701611afa565b601f01601f19169190910160400192915050565b60208082526017908201527f4f6e6c7920746865204c502063616e2065786563757465000000000000000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600082821015611af557611af5611b45565b500390565b60005b83811015611b15578181015183820152602001611afd565b83811115611b24576000848401525b50505050565b6000600019821415611b3e57611b3e611b45565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611b9c57600080fd5b50565b8015158114611b9c57600080fdfea2646970667358221220852d819d90e9c4eaf423206e72867265b8ba41bd8bf8eb99f408b844fad8c64e64736f6c63430008060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000afce80b19a8ce13dec0739a1aab7a028d6845eb30000000000000000000000002f1423d27f9b20058d9d1843e342726fdf985eb4000000000000000000000000b53c1a33016b2dc2ff3653530bff1848a515c8c50000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5000000000000000000000000d784927ff2f95ba542bfc824c8a8a98f3495f6b5
-----Decoded View---------------
Arg [0] : _nexus (address): 0xAFcE80b19A8cE13DEc0739a1aaB7A028d6845Eb3
Arg [1] : _lp (address): 0x2F1423D27f9B20058d9D1843E342726fDF985Eb4
Arg [2] : _platformAddress (address): 0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5
Arg [3] : _rewardToken (address): 0x4da27a545c0c5B758a6BA100e3a049001de870f5
Arg [4] : _rewardController (address): 0xd784927Ff2f95ba542BfC824c8a8a98F3495f6b5
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000afce80b19a8ce13dec0739a1aab7a028d6845eb3
Arg [1] : 0000000000000000000000002f1423d27f9b20058d9d1843e342726fdf985eb4
Arg [2] : 000000000000000000000000b53c1a33016b2dc2ff3653530bff1848a515c8c5
Arg [3] : 0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5
Arg [4] : 000000000000000000000000d784927ff2f95ba542bfc824c8a8a98f3495f6b5
Loading...
Loading
Loading...
Loading
OVERVIEW
Connects FEI from the Feeder Pool to Aave V2.Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.