Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Initialize | 10147860 | 2117 days ago | IN | 0 ETH | 0.01134486 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
AaveIntegration
Compiler Version
v0.5.16+commit.9c3226ce
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion, GNU GPLv3 license, Audited
Contract Source Code (Solidity)Audit Report
/**
*Submitted for verification at Etherscan.io on 2020-05-28
*/
pragma solidity 0.5.16;
interface IAaveAToken {
/**
* @notice Non-standard ERC20 function to redeem an _amount of aTokens for the underlying
* asset, burning the aTokens during the process.
* @param _amount Amount of aTokens
*/
function redeem(uint256 _amount) external;
/**
* @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 IAaveLendingPool {
/**
* @notice Deposits a certain _amount of an asset specified by the _reserve parameter.
* @dev The caller receives a certain amount of corresponding aTokens in exchange.
* The amount of aTokens received depends on the corresponding aToken exchange rate.
* LendingPoolCore must be approved to spend this reserve
*/
function deposit(address _reserve, uint256 _amount, uint16 _referralCode) external;
}
interface ILendingPoolAddressesProvider {
/**
* @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);
/**
* @notice Get the address for lendingPoolCore
* @dev IMPORTANT - this is where _reserve must be approved before deposit
*/
function getLendingPoolCore() external view returns (address payable);
}
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 _isTokenFeeCharged) external;
/**
* @dev Returns the current balance of the given bAsset
*/
function checkBalance(address _bAsset) external returns (uint256 balance);
}
contract InitializableModuleKeys {
// Governance
bytes32 internal KEY_GOVERNANCE;
bytes32 internal KEY_STAKING;
bytes32 internal KEY_PROXY_ADMIN;
// mStable
bytes32 internal KEY_ORACLE_HUB;
bytes32 internal KEY_MANAGER;
bytes32 internal KEY_RECOLLATERALISER;
bytes32 internal KEY_META_TOKEN;
bytes32 internal KEY_SAVINGS_MANAGER;
/**
* @dev Initialize function for upgradable proxy contracts. This function should be called
* via Proxy to initialize constants in the Proxy contract.
*/
function _initialize() internal {
// keccak256() values are evaluated only once at the time of this function call.
// Hence, no need to assign hard-coded values to these variables.
KEY_GOVERNANCE = keccak256("Governance");
KEY_STAKING = keccak256("Staking");
KEY_PROXY_ADMIN = keccak256("ProxyAdmin");
KEY_ORACLE_HUB = keccak256("OracleHub");
KEY_MANAGER = keccak256("Manager");
KEY_RECOLLATERALISER = keccak256("Recollateraliser");
KEY_META_TOKEN = keccak256("MetaToken");
KEY_SAVINGS_MANAGER = keccak256("SavingsManager");
}
}
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;
}
contract InitializableModule is InitializableModuleKeys {
INexus public nexus;
/**
* @dev Modifier to allow function calls only from the Governor.
*/
modifier onlyGovernor() {
require(msg.sender == _governor(), "Only governor can execute");
_;
}
/**
* @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 Modifier to allow function calls only from the ProxyAdmin.
*/
modifier onlyProxyAdmin() {
require(
msg.sender == _proxyAdmin(), "Only ProxyAdmin can execute"
);
_;
}
/**
* @dev Modifier to allow function calls only from the Manager.
*/
modifier onlyManager() {
require(msg.sender == _manager(), "Only manager can execute");
_;
}
/**
* @dev Initialization function for upgradable proxy contracts
* @param _nexus Nexus contract address
*/
function _initialize(address _nexus) internal {
require(_nexus != address(0), "Nexus address is zero");
nexus = INexus(_nexus);
InitializableModuleKeys._initialize();
}
/**
* @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 Staking Module address from the Nexus
* @return Address of the Staking Module contract
*/
function _staking() internal view returns (address) {
return nexus.getModule(KEY_STAKING);
}
/**
* @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);
}
/**
* @dev Return MetaToken Module address from the Nexus
* @return Address of the MetaToken Module contract
*/
function _metaToken() internal view returns (address) {
return nexus.getModule(KEY_META_TOKEN);
}
/**
* @dev Return OracleHub Module address from the Nexus
* @return Address of the OracleHub Module contract
*/
function _oracleHub() internal view returns (address) {
return nexus.getModule(KEY_ORACLE_HUB);
}
/**
* @dev Return Manager Module address from the Nexus
* @return Address of the Manager Module contract
*/
function _manager() internal view returns (address) {
return nexus.getModule(KEY_MANAGER);
}
/**
* @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);
}
}
contract InitializableGovernableWhitelist is InitializableModule {
event Whitelisted(address indexed _address);
mapping(address => bool) public whitelist;
/**
* @dev Modifier to allow function calls only from the whitelisted address.
*/
modifier onlyWhitelisted() {
require(whitelist[msg.sender], "Not a whitelisted address");
_;
}
/**
* @dev Initialization function for upgradable proxy contracts
* @param _nexus Nexus contract address
* @param _whitelisted Array of whitelisted addresses.
*/
function _initialize(
address _nexus,
address[] memory _whitelisted
)
internal
{
InitializableModule._initialize(_nexus);
require(_whitelisted.length > 0, "Empty whitelist array");
for(uint256 i = 0; i < _whitelisted.length; i++) {
_addWhitelist(_whitelisted[i]);
}
}
/**
* @dev Adds a new whitelist address
* @param _address Address to add in whitelist
*/
function _addWhitelist(address _address) internal {
require(_address != address(0), "Address is zero");
require(! whitelist[_address], "Already whitelisted");
whitelist[_address] = true;
emit Whitelisted(_address);
}
}
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 use in the initializer function of a contract.
*/
modifier initializer() {
require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");
bool isTopLevelCall = !initializing;
if (isTopLevelCall) {
initializing = true;
initialized = true;
}
_;
if (isTopLevelCall) {
initializing = false;
}
}
/// @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.
address self = address(this);
uint256 cs;
assembly { cs := extcodesize(self) }
return cs == 0;
}
// Reserved storage space to allow for layout changes in the future.
uint256[50] private ______gap;
}
/**
* @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.
*
* _Available since v2.4.0._
*/
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.
*
* _Available since v2.4.0._
*/
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.
*
* _Available since v2.4.0._
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
/**
* @title StableMath
* @author Stability Labs Pty. Ltd.
* @notice A library providing safe mathematical operations to multiply and
* divide with standardised precision.
* @dev Derives from OpenZeppelin's SafeMath lib and uses generic system
* wide variables for managing precision.
*/
library StableMath {
using SafeMath for uint256;
/**
* @dev Scaling unit for use in specific calculations,
* where 1 * 10**18, or 1e18 represents a unit '1'
*/
uint256 private constant FULL_SCALE = 1e18;
/**
* @notice Token Ratios are used when converting between units of bAsset, mAsset and MTA
* Reasoning: Takes into account token decimals, and difference in base unit (i.e. grams to Troy oz for gold)
* @dev bAsset ratio unit for use in exact calculations,
* where (1 bAsset unit * bAsset.ratio) / ratioScale == x mAsset unit
*/
uint256 private constant RATIO_SCALE = 1e8;
/**
* @dev Provides an interface to the scaling unit
* @return Scaling unit (1e18 or 1 * 10**18)
*/
function getFullScale() internal pure returns (uint256) {
return FULL_SCALE;
}
/**
* @dev Provides an interface to the ratio unit
* @return Ratio scale unit (1e8 or 1 * 10**8)
*/
function getRatioScale() internal pure returns (uint256) {
return RATIO_SCALE;
}
/**
* @dev Scales a given integer to the power of the full scale.
* @param x Simple uint256 to scale
* @return Scaled value a to an exact number
*/
function scaleInteger(uint256 x)
internal
pure
returns (uint256)
{
return x.mul(FULL_SCALE);
}
/***************************************
PRECISE ARITHMETIC
****************************************/
/**
* @dev Multiplies two precise units, and then truncates by the full scale
* @param x Left hand input to multiplication
* @param y Right hand input to multiplication
* @return Result after multiplying the two inputs and then dividing by the shared
* scale unit
*/
function mulTruncate(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
return mulTruncateScale(x, y, FULL_SCALE);
}
/**
* @dev Multiplies two precise units, and then truncates by the given scale. For example,
* when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18
* @param x Left hand input to multiplication
* @param y Right hand input to multiplication
* @param scale Scale unit
* @return Result after multiplying the two inputs and then dividing by the shared
* scale unit
*/
function mulTruncateScale(uint256 x, uint256 y, uint256 scale)
internal
pure
returns (uint256)
{
uint256 z = x.mul(y);
return z.div(scale);
}
/**
* @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result
* @param x Left hand input to multiplication
* @param y Right hand input to multiplication
* @return Result after multiplying the two inputs and then dividing by the shared
* scale unit, rounded up to the closest base unit.
*/
function mulTruncateCeil(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
uint256 scaled = x.mul(y);
uint256 ceil = scaled.add(FULL_SCALE.sub(1));
return ceil.div(FULL_SCALE);
}
/**
* @dev Precisely divides two units, by first scaling the left hand operand. Useful
* for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17)
* @param x Left hand input to division
* @param y Right hand input to division
* @return Result after multiplying the left operand by the scale, and
* executing the division on the right hand input.
*/
function divPrecisely(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
uint256 z = x.mul(FULL_SCALE);
return z.div(y);
}
/***************************************
RATIO FUNCS
****************************************/
/**
* @dev Multiplies and truncates a token ratio, essentially flooring the result
* i.e. How much mAsset is this bAsset worth?
* @param x Left hand operand to multiplication (i.e Exact quantity)
* @param ratio bAsset ratio
* @return Result after multiplying the two inputs and then dividing by the ratio scale
*/
function mulRatioTruncate(uint256 x, uint256 ratio)
internal
pure
returns (uint256 c)
{
return mulTruncateScale(x, ratio, RATIO_SCALE);
}
/**
* @dev Multiplies and truncates a token ratio, rounding up the result
* i.e. How much mAsset is this bAsset worth?
* @param x Left hand input to multiplication (i.e Exact quantity)
* @param ratio bAsset ratio
* @return Result after multiplying the two inputs and then dividing by the shared
* ratio scale, rounded up to the closest base unit.
*/
function mulRatioTruncateCeil(uint256 x, uint256 ratio)
internal
pure
returns (uint256)
{
uint256 scaled = x.mul(ratio);
uint256 ceil = scaled.add(RATIO_SCALE.sub(1));
return ceil.div(RATIO_SCALE);
}
/**
* @dev Precisely divides two ratioed units, by first scaling the left hand operand
* i.e. How much bAsset is this mAsset worth?
* @param x Left hand operand in division
* @param ratio bAsset ratio
* @return Result after multiplying the left operand by the scale, and
* executing the division on the right hand input.
*/
function divRatioPrecisely(uint256 x, uint256 ratio)
internal
pure
returns (uint256 c)
{
uint256 y = x.mul(RATIO_SCALE);
return y.div(ratio);
}
/***************************************
HELPERS
****************************************/
/**
* @dev Calculates minimum of two numbers
* @param x Left hand input
* @param y Right hand input
* @return Minimum of the two inputs
*/
function min(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
return x > y ? y : x;
}
/**
* @dev Calculated maximum of two numbers
* @param x Left hand input
* @param y Right hand input
* @return Maximum of the two inputs
*/
function max(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
return x > y ? x : y;
}
/**
* @dev Clamps a value to an upper bound
* @param x Left hand input
* @param upperBound Maximum possible value to return
* @return Input x clamped to a maximum value, upperBound
*/
function clamp(uint256 x, uint256 upperBound)
internal
pure
returns (uint256)
{
return x > upperBound ? upperBound : x;
}
}
/**
* @dev Interface of the ERC20 standard as defined in the EIP. Does not include
* the optional functions; to access them see {ERC20Detailed}.
*/
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);
}
/**
* @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) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);
}
/**
* @dev Converts an `address` into `address payable`. Note that this is
* simply a type cast: the actual underlying value is not changed.
*
* _Available since v2.4.0._
*/
function toPayable(address account) internal pure returns (address payable) {
return address(uint160(account));
}
/**
* @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].
*
* _Available since v2.4.0._
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-call-value
(bool success, ) = recipient.call.value(amount)("");
require(success, "Address: unable to send value, recipient may have reverted");
}
}
library SafeERC20 {
using SafeMath for uint256;
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));
}
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'
// solhint-disable-next-line max-line-length
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).add(value);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
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.
// A Solidity high level call has three parts:
// 1. The target address is checked to verify it contains contract code
// 2. The call itself is made, and success asserted
// 3. The return value is decoded, which in turn checks the size of the returned data.
// solhint-disable-next-line max-line-length
require(address(token).isContract(), "SafeERC20: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = address(token).call(data);
require(success, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
library MassetHelpers {
using StableMath for uint256;
using SafeMath for uint256;
using SafeERC20 for IERC20;
function transferTokens(
address _sender,
address _recipient,
address _basset,
bool _erc20TransferFeeCharged,
uint256 _qty
)
internal
returns (uint256 receivedQty)
{
receivedQty = _qty;
if(_erc20TransferFeeCharged) {
uint256 balBefore = IERC20(_basset).balanceOf(_recipient);
IERC20(_basset).safeTransferFrom(_sender, _recipient, _qty);
uint256 balAfter = IERC20(_basset).balanceOf(_recipient);
receivedQty = StableMath.min(_qty, balAfter.sub(balBefore));
} else {
IERC20(_basset).safeTransferFrom(_sender, _recipient, _qty);
}
}
function safeInfiniteApprove(address _asset, address _spender)
internal
{
IERC20(_asset).safeApprove(_spender, 0);
IERC20(_asset).safeApprove(_spender, uint256(-1));
}
}
contract InitializableReentrancyGuard {
bool private _notEntered;
function _initialize() internal {
// Storing an initial 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 percetange 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.
_notEntered = true;
}
/**
* @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(_notEntered, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_notEntered = false;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_notEntered = true;
}
}
/**
* @title AbstractIntegration
* @author Stability Labs Pty. Ltd.
* @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.
*/
contract InitializableAbstractIntegration is
Initializable,
IPlatformIntegration,
InitializableGovernableWhitelist,
InitializableReentrancyGuard
{
using SafeERC20 for IERC20;
using SafeMath for uint256;
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);
// Core address for the given platform */
address public platformAddress;
// bAsset => pToken (Platform Specific Token Address)
mapping(address => address) public bAssetToPToken;
// Full list of all bAssets supported here
address[] internal bAssetsMapped;
/**
* @dev Initialization function for upgradable proxy contract.
* This function should be called via Proxy just after contract deployment.
* @param _nexus Address of the Nexus
* @param _whitelisted Whitelisted addresses for vault access
* @param _platformAddress Generic platform address
* @param _bAssets Addresses of initial supported bAssets
* @param _pTokens Platform Token corresponding addresses
*/
function initialize(
address _nexus,
address[] calldata _whitelisted,
address _platformAddress,
address[] calldata _bAssets,
address[] calldata _pTokens
)
external
initializer
{
InitializableReentrancyGuard._initialize();
InitializableGovernableWhitelist._initialize(_nexus, _whitelisted);
InitializableAbstractIntegration._initialize(_platformAddress, _bAssets, _pTokens);
}
/**
* @dev Internal initialize function, to set up initial internal state
* @param _platformAddress Generic platform address
* @param _bAssets Addresses of initial supported bAssets
* @param _pTokens Platform Token corresponding addresses
*/
function _initialize(
address _platformAddress,
address[] memory _bAssets,
address[] memory _pTokens
)
internal
{
platformAddress = _platformAddress;
uint256 bAssetCount = _bAssets.length;
require(bAssetCount == _pTokens.length, "Invalid input arrays");
for(uint256 i = 0; i < bAssetCount; i++){
_setPTokenAddress(_bAssets[i], _pTokens[i]);
}
}
/***************************************
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;
function reApproveAllTokens() external;
/***************************************
ABSTRACT
****************************************/
/**
* @dev Deposit a quantity of bAsset into the platform
* @param _bAsset Address for the bAsset
* @param _amount Units of bAsset to deposit
* @param _isTokenFeeCharged Flag that signals if an xfer fee is charged on bAsset
* @return quantityDeposited Quantity of bAsset that entered the platform
*/
function deposit(address _bAsset, uint256 _amount, bool _isTokenFeeCharged)
external returns (uint256 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 _isTokenFeeCharged Flag that signals if an xfer fee is charged on bAsset
*/
function withdraw(address _receiver, address _bAsset, uint256 _amount, bool _isTokenFeeCharged) external;
/**
* @dev Get the total bAsset value held in the platform
* This includes any interest that was generated since depositing
* @param _bAsset Address of the bAsset
* @return balance Total value of the bAsset in the platform
*/
function checkBalance(address _bAsset) external returns (uint256 balance);
/***************************************
HELPERS
****************************************/
/**
* @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;
}
}
/**
* @title AaveIntegration
* @author Stability Labs Pty. Ltd.
* @notice A simple connection to deposit and withdraw bAssets from Aave
* @dev VERSION: 1.0
* DATE: 2020-03-26
*/
contract AaveIntegration is InitializableAbstractIntegration {
/***************************************
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 _isTokenFeeCharged Flag that signals if an xfer fee is charged on bAsset
* @return quantityDeposited Quantity of bAsset that entered the platform
*/
function deposit(
address _bAsset,
uint256 _amount,
bool _isTokenFeeCharged
)
external
onlyWhitelisted
nonReentrant
returns (uint256 quantityDeposited)
{
require(_amount > 0, "Must deposit something");
// Get the Target token
IAaveAToken aToken = _getATokenFor(_bAsset);
// We should have been sent this amount, if not, the deposit will fail
quantityDeposited = _amount;
uint16 referralCode = 36; // temp code
if(_isTokenFeeCharged) {
// If we charge a fee, account for it
uint256 prevBal = _checkBalance(aToken);
_getLendingPool().deposit(_bAsset, _amount, referralCode);
uint256 newBal = _checkBalance(aToken);
quantityDeposited = _min(quantityDeposited, newBal.sub(prevBal));
} else {
// aTokens are 1:1 for each asset
_getLendingPool().deposit(_bAsset, _amount, referralCode);
}
emit Deposit(_bAsset, address(aToken), quantityDeposited);
}
/**
* @dev Withdraw a quantity of bAsset from the platform. Redemption
* should fail if we have insufficient balance on 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
*/
function withdraw(
address _receiver,
address _bAsset,
uint256 _amount,
bool _isTokenFeeCharged
)
external
onlyWhitelisted
nonReentrant
{
require(_amount > 0, "Must withdraw something");
// Get the Target token
IAaveAToken aToken = _getATokenFor(_bAsset);
uint256 quantityWithdrawn = _amount;
// Don't need to Approve aToken, as it gets burned in redeem()
if(_isTokenFeeCharged) {
IERC20 b = IERC20(_bAsset);
uint256 prevBal = b.balanceOf(address(this));
aToken.redeem(_amount);
uint256 newBal = b.balanceOf(address(this));
quantityWithdrawn = _min(quantityWithdrawn, newBal.sub(prevBal));
} else {
aToken.redeem(_amount);
}
// Send redeemed bAsset to the receiver
IERC20(_bAsset).safeTransfer(_receiver, quantityWithdrawn);
emit Withdrawal(_bAsset, address(aToken), quantityWithdrawn);
}
/**
* @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
returns (uint256 balance)
{
// balance is always with token aToken decimals
IAaveAToken aToken = _getATokenFor(_bAsset);
return _checkBalance(aToken);
}
/***************************************
APPROVALS
****************************************/
/**
* @dev Re-approve the spending of all bAssets by the Aave lending pool core,
* if for some reason is it necessary for example if the address of core changes.
* Only callable through Governance.
*/
function reApproveAllTokens()
external
onlyGovernor
{
uint256 bAssetCount = bAssetsMapped.length;
address lendingPoolVault = _getLendingPoolCore();
// approve the pool to spend the bAsset
for(uint i = 0; i < bAssetCount; i++){
MassetHelpers.safeInfiniteApprove(bAssetsMapped[i], lendingPoolVault);
}
}
/**
* @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
{
address lendingPoolVault = _getLendingPoolCore();
// approve the pool to spend the bAsset
MassetHelpers.safeInfiniteApprove(_bAsset, lendingPoolVault);
}
/***************************************
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 (IAaveLendingPool)
{
address lendingPool = ILendingPoolAddressesProvider(platformAddress).getLendingPool();
require(lendingPool != address(0), "Lending pool does not exist");
return IAaveLendingPool(lendingPool);
}
/**
* @dev Get the current address of the Aave lending pool core, which stores all the
* reserve tokens in its vault.
* @return Current lending pool core address
*/
function _getLendingPoolCore()
internal
view
returns (address payable)
{
address payable lendingPoolCore = ILendingPoolAddressesProvider(platformAddress).getLendingPoolCore();
require(lendingPoolCore != address(uint160(address(0))), "Lending pool core does not exist");
return lendingPoolCore;
}
/**
* @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 (IAaveAToken)
{
address aToken = bAssetToPToken[_bAsset];
require(aToken != address(0), "aToken does not exist");
return IAaveAToken(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(IAaveAToken _aToken)
internal
view
returns (uint256 balance)
{
return _aToken.balanceOf(address(this));
}
}Contract Security Audit
- Consensys Diligence - August 10th, 2020 - Security Audit Report
Contract ABI
API[{"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":"_address","type":"address"}],"name":"Whitelisted","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"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bAssetToPToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_bAsset","type":"address"}],"name":"checkBalance","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_bAsset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_isTokenFeeCharged","type":"bool"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"quantityDeposited","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_nexus","type":"address"},{"internalType":"address[]","name":"_whitelisted","type":"address[]"},{"internalType":"address","name":"_platformAddress","type":"address"},{"internalType":"address[]","name":"_bAssets","type":"address[]"},{"internalType":"address[]","name":"_pTokens","type":"address[]"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"nexus","outputs":[{"internalType":"contract INexus","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"platformAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"reApproveAllTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_bAsset","type":"address"},{"internalType":"address","name":"_pToken","type":"address"}],"name":"setPTokenAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"address","name":"_bAsset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_isTokenFeeCharged","type":"bool"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50611a0f806100206000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c8063934785b711610066578063934785b7146102b25780639b19251a146102f0578063a3f5c1d21461032a578063a755349a14610332578063dbe55e561461033a5761009e565b80630ed57b3a146100a357806311505f72146100d35780633edd1128146102045780635f5152261461024a57806371c4658514610270575b600080fd5b6100d1600480360360408110156100b957600080fd5b506001600160a01b0381358116916020013516610342565b005b6100d1600480360360a08110156100e957600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561011457600080fd5b82018360208201111561012657600080fd5b8035906020019184602083028401116401000000008311171561014857600080fd5b919390926001600160a01b038335169260408101906020013564010000000081111561017357600080fd5b82018360208201111561018557600080fd5b803590602001918460208302840111640100000000831117156101a757600080fd5b9193909290916020810190356401000000008111156101c557600080fd5b8201836020820111156101d757600080fd5b803590602001918460208302840111640100000000831117156101f957600080fd5b5090925090506103b9565b6102386004803603606081101561021a57600080fd5b506001600160a01b0381351690602081013590604001351515610516565b60408051918252519081900360200190f35b6102386004803603602081101561026057600080fd5b50356001600160a01b03166107cd565b6102966004803603602081101561028657600080fd5b50356001600160a01b03166107eb565b604080516001600160a01b039092168252519081900360200190f35b6100d1600480360360808110156102c857600080fd5b506001600160a01b038135811691602081013590911690604081013590606001351515610806565b6103166004803603602081101561030657600080fd5b50356001600160a01b0316610b72565b604080519115158252519081900360200190f35b610296610b87565b6100d1610b96565b610296610c51565b61034a610c65565b6001600160a01b0316336001600160a01b0316146103ab576040805162461bcd60e51b81526020600482015260196024820152784f6e6c7920676f7665726e6f722063616e206578656375746560381b604482015290519081900360640190fd5b6103b58282610cdb565b5050565b600054610100900460ff16806103d257506103d2610e4a565b806103e0575060005460ff16155b61041b5760405162461bcd60e51b815260040180806020018281038252602e81526020018061194d602e913960400191505060405180910390fd5b600054610100900460ff16158015610446576000805460ff1961ff0019909116610100171660011790555b61044e610e50565b61048b89898980806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610e5f92505050565b6104f98686868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808a02828101820190935289825290935089925088918291850190849080828437600092019190915250610ee692505050565b801561050b576000805461ff00191690555b505050505050505050565b336000908152603c602052604081205460ff16610576576040805162461bcd60e51b81526020600482015260196024820152784e6f7420612077686974656c6973746564206164647265737360381b604482015290519081900360640190fd5b603d5460ff166105cd576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b603d805460ff1916905582610622576040805162461bcd60e51b81526020600482015260166024820152754d757374206465706f73697420736f6d657468696e6760501b604482015290519081900360640190fd5b600061062d85610f9e565b8492509050602483156106f35760006106458361100b565b905061064f611087565b60408051636968703360e11b81526001600160a01b038a81166004830152602482018a905261ffff861660448301529151929091169163d2d0e0669160648082019260009290919082900301818387803b1580156106ac57600080fd5b505af11580156106c0573d6000803e3d6000fd5b5050505060006106cf8461100b565b90506106ea856106e5838563ffffffff61116616565b6111a8565b94505050610771565b6106fb611087565b60408051636968703360e11b81526001600160a01b0389811660048301526024820189905261ffff851660448301529151929091169163d2d0e0669160648082019260009290919082900301818387803b15801561075857600080fd5b505af115801561076c573d6000803e3d6000fd5b505050505b604080516001600160a01b038481168252602082018690528251908916927f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62928290030190a25050603d805460ff191660011790559392505050565b6000806107d983610f9e565b90506107e48161100b565b9392505050565b603e602052600090815260409020546001600160a01b031681565b336000908152603c602052604090205460ff16610866576040805162461bcd60e51b81526020600482015260196024820152784e6f7420612077686974656c6973746564206164647265737360381b604482015290519081900360640190fd5b603d5460ff166108bd576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b603d805460ff1916905581610919576040805162461bcd60e51b815260206004820152601760248201527f4d75737420776974686472617720736f6d657468696e67000000000000000000604482015290519081900360640190fd5b600061092484610f9e565b9050828215610a9e57604080516370a0823160e01b8152306004820152905186916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561097857600080fd5b505afa15801561098c573d6000803e3d6000fd5b505050506040513d60208110156109a257600080fd5b50516040805163db006a7560e01b81526004810189905290519192506001600160a01b0386169163db006a759160248082019260009290919082900301818387803b1580156109f057600080fd5b505af1158015610a04573d6000803e3d6000fd5b5050604080516370a0823160e01b81523060048201529051600093506001600160a01b03861692506370a0823191602480820192602092909190829003018186803b158015610a5257600080fd5b505afa158015610a66573d6000803e3d6000fd5b505050506040513d6020811015610a7c57600080fd5b50519050610a94846106e5838563ffffffff61116616565b9350505050610afd565b816001600160a01b031663db006a75856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610ae457600080fd5b505af1158015610af8573d6000803e3d6000fd5b505050505b610b176001600160a01b038616878363ffffffff6111bd16565b604080516001600160a01b038481168252602082018490528251908816927f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b6398928290030190a25050603d805460ff1916600117905550505050565b603c6020526000908152604090205460ff1681565b603b546001600160a01b031681565b610b9e610c65565b6001600160a01b0316336001600160a01b031614610bff576040805162461bcd60e51b81526020600482015260196024820152784f6e6c7920676f7665726e6f722063616e206578656375746560381b604482015290519081900360640190fd5b603f546000610c0c61120f565b905060005b82811015610c4c57610c44603f8281548110610c2957fe5b6000918252602090912001546001600160a01b0316836112e9565b600101610c11565b505050565b603d5461010090046001600160a01b031681565b603b546040805163030d028960e21b815290516000926001600160a01b031691630c340a24916004808301926020929190829003018186803b158015610caa57600080fd5b505afa158015610cbe573d6000803e3d6000fd5b505050506040513d6020811015610cd457600080fd5b5051905090565b6001600160a01b038281166000908152603e60205260409020541615610d3d576040805162461bcd60e51b81526020600482015260126024820152711c151bdad95b88185b1c9958591e481cd95d60721b604482015290519081900360640190fd5b6001600160a01b03821615801590610d5d57506001600160a01b03811615155b610da2576040805162461bcd60e51b8152602060048201526011602482015270496e76616c69642061646472657373657360781b604482015290519081900360640190fd5b6001600160a01b038083166000818152603e6020908152604080832080549587166001600160a01b03199687168117909155603f805460018101825594527fc03004e3ce0784bf68186394306849f9b7b1200073105cd9aeb554a1802b58fd909301805490951684179094558351918252925191927fef6485b84315f9b1483beffa32aae9a0596890395e3d7521f1c5fbb51790e76592918290030190a26103b58282611320565b303b1590565b603d805460ff19166001179055565b610e6882611336565b6000815111610eb6576040805162461bcd60e51b8152602060048201526015602482015274456d7074792077686974656c69737420617272617960581b604482015290519081900360640190fd5b60005b8151811015610c4c57610ede828281518110610ed157fe5b60200260200101516113af565b600101610eb9565b603d8054610100600160a81b0319166101006001600160a01b03861602179055815181518114610f54576040805162461bcd60e51b8152602060048201526014602482015273496e76616c696420696e7075742061727261797360601b604482015290519081900360640190fd5b60005b81811015610f9757610f8f848281518110610f6e57fe5b6020026020010151848381518110610f8257fe5b6020026020010151610cdb565b600101610f57565b5050505050565b6001600160a01b038082166000908152603e602052604081205490911680611005576040805162461bcd60e51b815260206004820152601560248201527418551bdad95b88191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b92915050565b604080516370a0823160e01b815230600482015290516000916001600160a01b038416916370a0823191602480820192602092909190829003018186803b15801561105557600080fd5b505afa158015611069573d6000803e3d6000fd5b505050506040513d602081101561107f57600080fd5b505192915050565b600080603d60019054906101000a90046001600160a01b03166001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110d857600080fd5b505afa1580156110ec573d6000803e3d6000fd5b505050506040513d602081101561110257600080fd5b505190506001600160a01b038116611161576040805162461bcd60e51b815260206004820152601b60248201527f4c656e64696e6720706f6f6c20646f6573206e6f742065786973740000000000604482015290519081900360640190fd5b905090565b60006107e483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114ac565b60008183116111b757826107e4565b50919050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610c4c908490611543565b600080603d60019054906101000a90046001600160a01b03166001600160a01b031663ed6ff7606040518163ffffffff1660e01b815260040160206040518083038186803b15801561126057600080fd5b505afa158015611274573d6000803e3d6000fd5b505050506040513d602081101561128a57600080fd5b505190506001600160a01b038116611161576040805162461bcd60e51b815260206004820181905260248201527f4c656e64696e6720706f6f6c20636f726520646f6573206e6f74206578697374604482015290519081900360640190fd5b6113046001600160a01b03831682600063ffffffff61170116565b6103b56001600160a01b0383168260001963ffffffff61170116565b600061132a61120f565b9050610c4c83826112e9565b6001600160a01b038116611389576040805162461bcd60e51b81526020600482015260156024820152744e657875732061646472657373206973207a65726f60581b604482015290519081900360640190fd5b603b80546001600160a01b0319166001600160a01b0383161790556113ac611814565b50565b6001600160a01b0381166113fc576040805162461bcd60e51b815260206004820152600f60248201526e41646472657373206973207a65726f60881b604482015290519081900360640190fd5b6001600160a01b0381166000908152603c602052604090205460ff1615611460576040805162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481dda1a5d195b1a5cdd1959606a1b604482015290519081900360640190fd5b6001600160a01b0381166000818152603c6020526040808220805460ff19166001179055517faab7954e9d246b167ef88aeddad35209ca2489d95a8aeb59e288d9b19fae5a549190a250565b6000818484111561153b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156115005781810151838201526020016114e8565b50505050905090810190601f16801561152d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b611555826001600160a01b0316611910565b6115a6576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106115e45780518252601f1990920191602091820191016115c5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611646576040519150601f19603f3d011682016040523d82523d6000602084013e61164b565b606091505b5091509150816116a2576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b8051156116fb578080602001905160208110156116be57600080fd5b50516116fb5760405162461bcd60e51b815260040180806020018281038252602a81526020018061197b602a913960400191505060405180910390fd5b50505050565b801580611787575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b15801561175957600080fd5b505afa15801561176d573d6000803e3d6000fd5b505050506040513d602081101561178357600080fd5b5051155b6117c25760405162461bcd60e51b81526004018080602001828103825260368152602001806119a56036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052610c4c908490611543565b6040805169476f7665726e616e636560b01b8152815190819003600a9081018220603355665374616b696e6760c81b82528251918290036007908101832060345569283937bc3ca0b236b4b760b11b835283519283900390910182206035556827b930b1b632a43ab160b91b8252825191829003600990810183206036556626b0b730b3b2b960c91b835283519283900390910182206037556f2932b1b7b63630ba32b930b634b9b2b960811b825282519182900360100182206038556826b2ba30aa37b5b2b760b91b82528251918290030181206039556d29b0bb34b733b9a6b0b730b3b2b960911b8152905190819003600e019020603a55565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061194457508115155b94935050505056fe436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a265627a7a723158201b95b45862e45392ea5068e238d754d160ac6127f53ab2bdd9bb6ce7f7b0144264736f6c63430005100032
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061009e5760003560e01c8063934785b711610066578063934785b7146102b25780639b19251a146102f0578063a3f5c1d21461032a578063a755349a14610332578063dbe55e561461033a5761009e565b80630ed57b3a146100a357806311505f72146100d35780633edd1128146102045780635f5152261461024a57806371c4658514610270575b600080fd5b6100d1600480360360408110156100b957600080fd5b506001600160a01b0381358116916020013516610342565b005b6100d1600480360360a08110156100e957600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561011457600080fd5b82018360208201111561012657600080fd5b8035906020019184602083028401116401000000008311171561014857600080fd5b919390926001600160a01b038335169260408101906020013564010000000081111561017357600080fd5b82018360208201111561018557600080fd5b803590602001918460208302840111640100000000831117156101a757600080fd5b9193909290916020810190356401000000008111156101c557600080fd5b8201836020820111156101d757600080fd5b803590602001918460208302840111640100000000831117156101f957600080fd5b5090925090506103b9565b6102386004803603606081101561021a57600080fd5b506001600160a01b0381351690602081013590604001351515610516565b60408051918252519081900360200190f35b6102386004803603602081101561026057600080fd5b50356001600160a01b03166107cd565b6102966004803603602081101561028657600080fd5b50356001600160a01b03166107eb565b604080516001600160a01b039092168252519081900360200190f35b6100d1600480360360808110156102c857600080fd5b506001600160a01b038135811691602081013590911690604081013590606001351515610806565b6103166004803603602081101561030657600080fd5b50356001600160a01b0316610b72565b604080519115158252519081900360200190f35b610296610b87565b6100d1610b96565b610296610c51565b61034a610c65565b6001600160a01b0316336001600160a01b0316146103ab576040805162461bcd60e51b81526020600482015260196024820152784f6e6c7920676f7665726e6f722063616e206578656375746560381b604482015290519081900360640190fd5b6103b58282610cdb565b5050565b600054610100900460ff16806103d257506103d2610e4a565b806103e0575060005460ff16155b61041b5760405162461bcd60e51b815260040180806020018281038252602e81526020018061194d602e913960400191505060405180910390fd5b600054610100900460ff16158015610446576000805460ff1961ff0019909116610100171660011790555b61044e610e50565b61048b89898980806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610e5f92505050565b6104f98686868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808a02828101820190935289825290935089925088918291850190849080828437600092019190915250610ee692505050565b801561050b576000805461ff00191690555b505050505050505050565b336000908152603c602052604081205460ff16610576576040805162461bcd60e51b81526020600482015260196024820152784e6f7420612077686974656c6973746564206164647265737360381b604482015290519081900360640190fd5b603d5460ff166105cd576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b603d805460ff1916905582610622576040805162461bcd60e51b81526020600482015260166024820152754d757374206465706f73697420736f6d657468696e6760501b604482015290519081900360640190fd5b600061062d85610f9e565b8492509050602483156106f35760006106458361100b565b905061064f611087565b60408051636968703360e11b81526001600160a01b038a81166004830152602482018a905261ffff861660448301529151929091169163d2d0e0669160648082019260009290919082900301818387803b1580156106ac57600080fd5b505af11580156106c0573d6000803e3d6000fd5b5050505060006106cf8461100b565b90506106ea856106e5838563ffffffff61116616565b6111a8565b94505050610771565b6106fb611087565b60408051636968703360e11b81526001600160a01b0389811660048301526024820189905261ffff851660448301529151929091169163d2d0e0669160648082019260009290919082900301818387803b15801561075857600080fd5b505af115801561076c573d6000803e3d6000fd5b505050505b604080516001600160a01b038481168252602082018690528251908916927f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62928290030190a25050603d805460ff191660011790559392505050565b6000806107d983610f9e565b90506107e48161100b565b9392505050565b603e602052600090815260409020546001600160a01b031681565b336000908152603c602052604090205460ff16610866576040805162461bcd60e51b81526020600482015260196024820152784e6f7420612077686974656c6973746564206164647265737360381b604482015290519081900360640190fd5b603d5460ff166108bd576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b603d805460ff1916905581610919576040805162461bcd60e51b815260206004820152601760248201527f4d75737420776974686472617720736f6d657468696e67000000000000000000604482015290519081900360640190fd5b600061092484610f9e565b9050828215610a9e57604080516370a0823160e01b8152306004820152905186916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561097857600080fd5b505afa15801561098c573d6000803e3d6000fd5b505050506040513d60208110156109a257600080fd5b50516040805163db006a7560e01b81526004810189905290519192506001600160a01b0386169163db006a759160248082019260009290919082900301818387803b1580156109f057600080fd5b505af1158015610a04573d6000803e3d6000fd5b5050604080516370a0823160e01b81523060048201529051600093506001600160a01b03861692506370a0823191602480820192602092909190829003018186803b158015610a5257600080fd5b505afa158015610a66573d6000803e3d6000fd5b505050506040513d6020811015610a7c57600080fd5b50519050610a94846106e5838563ffffffff61116616565b9350505050610afd565b816001600160a01b031663db006a75856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610ae457600080fd5b505af1158015610af8573d6000803e3d6000fd5b505050505b610b176001600160a01b038616878363ffffffff6111bd16565b604080516001600160a01b038481168252602082018490528251908816927f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b6398928290030190a25050603d805460ff1916600117905550505050565b603c6020526000908152604090205460ff1681565b603b546001600160a01b031681565b610b9e610c65565b6001600160a01b0316336001600160a01b031614610bff576040805162461bcd60e51b81526020600482015260196024820152784f6e6c7920676f7665726e6f722063616e206578656375746560381b604482015290519081900360640190fd5b603f546000610c0c61120f565b905060005b82811015610c4c57610c44603f8281548110610c2957fe5b6000918252602090912001546001600160a01b0316836112e9565b600101610c11565b505050565b603d5461010090046001600160a01b031681565b603b546040805163030d028960e21b815290516000926001600160a01b031691630c340a24916004808301926020929190829003018186803b158015610caa57600080fd5b505afa158015610cbe573d6000803e3d6000fd5b505050506040513d6020811015610cd457600080fd5b5051905090565b6001600160a01b038281166000908152603e60205260409020541615610d3d576040805162461bcd60e51b81526020600482015260126024820152711c151bdad95b88185b1c9958591e481cd95d60721b604482015290519081900360640190fd5b6001600160a01b03821615801590610d5d57506001600160a01b03811615155b610da2576040805162461bcd60e51b8152602060048201526011602482015270496e76616c69642061646472657373657360781b604482015290519081900360640190fd5b6001600160a01b038083166000818152603e6020908152604080832080549587166001600160a01b03199687168117909155603f805460018101825594527fc03004e3ce0784bf68186394306849f9b7b1200073105cd9aeb554a1802b58fd909301805490951684179094558351918252925191927fef6485b84315f9b1483beffa32aae9a0596890395e3d7521f1c5fbb51790e76592918290030190a26103b58282611320565b303b1590565b603d805460ff19166001179055565b610e6882611336565b6000815111610eb6576040805162461bcd60e51b8152602060048201526015602482015274456d7074792077686974656c69737420617272617960581b604482015290519081900360640190fd5b60005b8151811015610c4c57610ede828281518110610ed157fe5b60200260200101516113af565b600101610eb9565b603d8054610100600160a81b0319166101006001600160a01b03861602179055815181518114610f54576040805162461bcd60e51b8152602060048201526014602482015273496e76616c696420696e7075742061727261797360601b604482015290519081900360640190fd5b60005b81811015610f9757610f8f848281518110610f6e57fe5b6020026020010151848381518110610f8257fe5b6020026020010151610cdb565b600101610f57565b5050505050565b6001600160a01b038082166000908152603e602052604081205490911680611005576040805162461bcd60e51b815260206004820152601560248201527418551bdad95b88191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b92915050565b604080516370a0823160e01b815230600482015290516000916001600160a01b038416916370a0823191602480820192602092909190829003018186803b15801561105557600080fd5b505afa158015611069573d6000803e3d6000fd5b505050506040513d602081101561107f57600080fd5b505192915050565b600080603d60019054906101000a90046001600160a01b03166001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110d857600080fd5b505afa1580156110ec573d6000803e3d6000fd5b505050506040513d602081101561110257600080fd5b505190506001600160a01b038116611161576040805162461bcd60e51b815260206004820152601b60248201527f4c656e64696e6720706f6f6c20646f6573206e6f742065786973740000000000604482015290519081900360640190fd5b905090565b60006107e483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114ac565b60008183116111b757826107e4565b50919050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610c4c908490611543565b600080603d60019054906101000a90046001600160a01b03166001600160a01b031663ed6ff7606040518163ffffffff1660e01b815260040160206040518083038186803b15801561126057600080fd5b505afa158015611274573d6000803e3d6000fd5b505050506040513d602081101561128a57600080fd5b505190506001600160a01b038116611161576040805162461bcd60e51b815260206004820181905260248201527f4c656e64696e6720706f6f6c20636f726520646f6573206e6f74206578697374604482015290519081900360640190fd5b6113046001600160a01b03831682600063ffffffff61170116565b6103b56001600160a01b0383168260001963ffffffff61170116565b600061132a61120f565b9050610c4c83826112e9565b6001600160a01b038116611389576040805162461bcd60e51b81526020600482015260156024820152744e657875732061646472657373206973207a65726f60581b604482015290519081900360640190fd5b603b80546001600160a01b0319166001600160a01b0383161790556113ac611814565b50565b6001600160a01b0381166113fc576040805162461bcd60e51b815260206004820152600f60248201526e41646472657373206973207a65726f60881b604482015290519081900360640190fd5b6001600160a01b0381166000908152603c602052604090205460ff1615611460576040805162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481dda1a5d195b1a5cdd1959606a1b604482015290519081900360640190fd5b6001600160a01b0381166000818152603c6020526040808220805460ff19166001179055517faab7954e9d246b167ef88aeddad35209ca2489d95a8aeb59e288d9b19fae5a549190a250565b6000818484111561153b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156115005781810151838201526020016114e8565b50505050905090810190601f16801561152d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b611555826001600160a01b0316611910565b6115a6576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106115e45780518252601f1990920191602091820191016115c5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611646576040519150601f19603f3d011682016040523d82523d6000602084013e61164b565b606091505b5091509150816116a2576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b8051156116fb578080602001905160208110156116be57600080fd5b50516116fb5760405162461bcd60e51b815260040180806020018281038252602a81526020018061197b602a913960400191505060405180910390fd5b50505050565b801580611787575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b15801561175957600080fd5b505afa15801561176d573d6000803e3d6000fd5b505050506040513d602081101561178357600080fd5b5051155b6117c25760405162461bcd60e51b81526004018080602001828103825260368152602001806119a56036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052610c4c908490611543565b6040805169476f7665726e616e636560b01b8152815190819003600a9081018220603355665374616b696e6760c81b82528251918290036007908101832060345569283937bc3ca0b236b4b760b11b835283519283900390910182206035556827b930b1b632a43ab160b91b8252825191829003600990810183206036556626b0b730b3b2b960c91b835283519283900390910182206037556f2932b1b7b63630ba32b930b634b9b2b960811b825282519182900360100182206038556826b2ba30aa37b5b2b760b91b82528251918290030181206039556d29b0bb34b733b9a6b0b730b3b2b960911b8152905190819003600e019020603a55565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061194457508115155b94935050505056fe436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a265627a7a723158201b95b45862e45392ea5068e238d754d160ac6127f53ab2bdd9bb6ce7f7b0144264736f6c63430005100032
Deployed Bytecode Sourcemap
41468:7371:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41468:7371:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38390:159;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;38390:159:0;;;;;;;;;;:::i;:::-;;36751:480;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;36751:480:0;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;36751:480:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;36751:480:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;36751:480:0;;;;-1:-1:-1;;;;;36751:480:0;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;36751:480:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;36751:480:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;36751:480:0;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;36751:480:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;36751:480:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;36751:480:0;;-1:-1:-1;36751:480:0;-1:-1:-1;36751:480:0;:::i;42185:1110::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;42185:1110:0;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;45076:255;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45076:255:0;-1:-1:-1;;;;;45076:255:0;;:::i;36106:49::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36106:49:0;-1:-1:-1;;;;;36106:49:0;;:::i;:::-;;;;-1:-1:-1;;;;;36106:49:0;;;;;;;;;;;;;;43648:1051;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;43648:1051:0;;;;;;;;;;;;;;;;;;;;;;;;:::i;7968:41::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;7968:41:0;-1:-1:-1;;;;;7968:41:0;;:::i;:::-;;;;;;;;;;;;;;;;;;4151:19;;;:::i;45705:387::-;;;:::i;36008:30::-;;;:::i;38390:159::-;4324:11;:9;:11::i;:::-;-1:-1:-1;;;;;4310:25:0;:10;-1:-1:-1;;;;;4310:25:0;;4302:63;;;;;-1:-1:-1;;;4302:63:0;;;;;;;;;;;;-1:-1:-1;;;4302:63:0;;;;;;;;;;;;;;;38506:35;38524:7;38533;38506:17;:35::i;:::-;38390:159;;:::o;36751:480::-;9568:12;;;;;;;;:31;;;9584:15;:13;:15::i;:::-;9568:47;;;-1:-1:-1;9604:11:0;;;;9603:12;9568:47;9560:106;;;;-1:-1:-1;;;9560:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9675:19;9698:12;;;;;;9697:13;9717:83;;;;9746:12;:19;;-1:-1:-1;;;;9746:19:0;;;;;9774:18;9761:4;9774:18;;;9717:83;37011:42;:40;:42::i;:::-;37064:66;37109:6;37117:12;;37064:66;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;37064:44:0;;-1:-1:-1;;;37064:66:0:i;:::-;37141:82;37186:16;37204:8;;37141:82;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;37141:82:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37214:8:0;;-1:-1:-1;37214:8:0;;;;37141:82;;;37214:8;;37141:82;37214:8;37141:82;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;37141:44:0;;-1:-1:-1;;;37141:82:0:i;:::-;9822:14;9818:57;;;9862:5;9847:20;;-1:-1:-1;;9847:20:0;;;9818:57;36751:480;;;;;;;;;:::o;42185:1110::-;8173:10;42378:25;8163:21;;;:9;:21;;;;;;;;8155:59;;;;;-1:-1:-1;;;8155:59:0;;;;;;;;;;;;-1:-1:-1;;;8155:59:0;;;;;;;;;;;;;;;34741:11;;;;34733:55;;;;;-1:-1:-1;;;34733:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;34866:11;:19;;-1:-1:-1;;34866:19:0;;;42429:11;42421:46;;;;;-1:-1:-1;;;42421:46:0;;;;;;;;;;;;-1:-1:-1;;;42421:46:0;;;;;;;;;;;;;;;42511:18;42532:22;42546:7;42532:13;:22::i;:::-;42667:7;;-1:-1:-1;42511:43:0;-1:-1:-1;42709:2:0;42737:481;;;;42826:15;42844:21;42858:6;42844:13;:21::i;:::-;42826:39;;42880:17;:15;:17::i;:::-;:57;;;-1:-1:-1;;;42880:57:0;;-1:-1:-1;;;;;42880:57:0;;;;;;;;;;;;;;;;;;;;;;:25;;;;;;;:57;;;;;-1:-1:-1;;42880:57:0;;;;;;;;-1:-1:-1;42880:25:0;:57;;;5:2:-1;;;;30:1;27;20:12;5:2;42880:57:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;42880:57:0;;;;42952:14;42969:21;42983:6;42969:13;:21::i;:::-;42952:38;-1:-1:-1;43025:44:0;43030:17;43049:19;42952:38;43060:7;43049:19;:10;:19;:::i;:::-;43025:4;:44::i;:::-;43005:64;;42737:481;;;;;43149:17;:15;:17::i;:::-;:57;;;-1:-1:-1;;;43149:57:0;;-1:-1:-1;;;;;43149:57:0;;;;;;;;;;;;;;;;;;;;;;:25;;;;;;;:57;;;;;-1:-1:-1;;43149:57:0;;;;;;;;-1:-1:-1;43149:25:0;:57;;;5:2:-1;;;;30:1;27;20:12;5:2;43149:57:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;43149:57:0;;;;42737:481;43235:52;;;-1:-1:-1;;;;;43235:52:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;35046:11:0;:18;;-1:-1:-1;;35046:18:0;35060:4;35046:18;;;42185:1110;;-1:-1:-1;;;42185:1110:0:o;45076:255::-;45151:15;45241:18;45262:22;45276:7;45262:13;:22::i;:::-;45241:43;;45302:21;45316:6;45302:13;:21::i;:::-;45295:28;45076:255;-1:-1:-1;;;45076:255:0:o;36106:49::-;;;;;;;;;;;;-1:-1:-1;;;;;36106:49:0;;:::o;43648:1051::-;8173:10;8163:21;;;;:9;:21;;;;;;;;8155:59;;;;;-1:-1:-1;;;8155:59:0;;;;;;;;;;;;-1:-1:-1;;;8155:59:0;;;;;;;;;;;;;;;34741:11;;;;34733:55;;;;;-1:-1:-1;;;34733:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;34866:11;:19;;-1:-1:-1;;34866:19:0;;;43876:11;43868:47;;;;;-1:-1:-1;;;43868:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;43959:18;43980:22;43994:7;43980:13;:22::i;:::-;43959:43;-1:-1:-1;44043:7:0;44135:364;;;;44232:26;;;-1:-1:-1;;;44232:26:0;;44252:4;44232:26;;;;;;44191:7;;44173:8;;-1:-1:-1;;;;;44232:11:0;;;;;:26;;;;;;;;;;;;;;:11;:26;;;5:2:-1;;;;30:1;27;20:12;5:2;44232:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;44232:26:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;44232:26:0;44273:22;;;-1:-1:-1;;;44273:22:0;;;;;;;;;;44232:26;;-1:-1:-1;;;;;;44273:13:0;;;;;:22;;;;;-1:-1:-1;;44273:22:0;;;;;;;;-1:-1:-1;44273:13:0;:22;;;5:2:-1;;;;30:1;27;20:12;5:2;44273:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;44327:26:0;;;-1:-1:-1;;;44327:26:0;;44347:4;44327:26;;;;;;44310:14;;-1:-1:-1;;;;;;44327:11:0;;;-1:-1:-1;44327:11:0;;:26;;;;;;;;;;;;;;;:11;:26;;;5:2:-1;;;;30:1;27;20:12;5:2;44327:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;44327:26:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;44327:26:0;;-1:-1:-1;44388:44:0;44393:17;44412:19;44327:26;44423:7;44412:19;:10;:19;:::i;44388:44::-;44368:64;;44135:364;;;;;;44465:6;-1:-1:-1;;;;;44465:13:0;;44479:7;44465:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44465:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;44465:22:0;;;;44135:364;44560:58;-1:-1:-1;;;;;44560:28:0;;44589:9;44600:17;44560:58;:28;:58;:::i;:::-;44636:55;;;-1:-1:-1;;;;;44636:55:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;35046:11:0;:18;;-1:-1:-1;;35046:18:0;35060:4;35046:18;;;-1:-1:-1;;;;43648:1051:0:o;7968:41::-;;;;;;;;;;;;;;;:::o;4151:19::-;;;-1:-1:-1;;;;;4151:19:0;;:::o;45705:387::-;4324:11;:9;:11::i;:::-;-1:-1:-1;;;;;4310:25:0;:10;-1:-1:-1;;;;;4310:25:0;;4302:63;;;;;-1:-1:-1;;;4302:63:0;;;;;;;;;;;;-1:-1:-1;;;4302:63:0;;;;;;;;;;;;;;;45813:13;:20;45791:19;45871:21;:19;:21::i;:::-;45844:48;-1:-1:-1;45956:6:0;45952:133;45972:11;45968:1;:15;45952:133;;;46004:69;46038:13;46052:1;46038:16;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46038:16:0;46056;46004:33;:69::i;:::-;45985:3;;45952:133;;;;4376:1;;45705:387::o;36008:30::-;;;;;;-1:-1:-1;;;;;36008:30:0;;:::o;5666:95::-;5737:5;;:16;;;-1:-1:-1;;;5737:16:0;;;;5710:7;;-1:-1:-1;;;;;5737:5:0;;:14;;:16;;;;;;;;;;;;;;:5;:16;;;5:2:-1;;;;30:1;27;20:12;5:2;5737:16:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;5737:16:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;5737:16:0;;-1:-1:-1;5666:95:0;:::o;38877:438::-;-1:-1:-1;;;;;38980:23:0;;;39015:1;38980:23;;;:14;:23;;;;;;;:37;38972:68;;;;;-1:-1:-1;;;38972:68:0;;;;;;;;;;;;-1:-1:-1;;;38972:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;39059:21:0;;;;;;:46;;-1:-1:-1;;;;;;39084:21:0;;;;39059:46;39051:76;;;;;-1:-1:-1;;;39051:76:0;;;;;;;;;;;;-1:-1:-1;;;39051:76:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;39140:23:0;;;;;;;:14;:23;;;;;;;;:33;;;;;-1:-1:-1;;;;;;39140:33:0;;;;;;;;39184:13;27:10:-1;;39140:33:0;23:18:-1;;45:23;;39184:27:0;;;;;;;;;;;;;;;;39229:29;;;;;;;39140:23;;39229:29;;;;;;;;;39271:36;39290:7;39299;39271:18;:36::i;9969:508::-;10386:4;10432:17;10464:7;9969:508;:::o;33755:487::-;34216:11;:18;;-1:-1:-1;;34216:18:0;34230:4;34216:18;;;33755:487::o;8433:362::-;8560:39;8592:6;8560:31;:39::i;:::-;8642:1;8620:12;:19;:23;8612:57;;;;;-1:-1:-1;;;8612:57:0;;;;;;;;;;;;-1:-1:-1;;;8612:57:0;;;;;;;;;;;;;;;8686:9;8682:106;8705:12;:19;8701:1;:23;8682:106;;;8746:30;8760:12;8773:1;8760:15;;;;;;;;;;;;;;8746:13;:30::i;:::-;8726:3;;8682:106;;37535:455;37704:15;:34;;-1:-1:-1;;;;;;37704:34:0;;-1:-1:-1;;;;;37704:34:0;;;;;;37773:15;;37822;;37807:30;;37799:63;;;;;-1:-1:-1;;;37799:63:0;;;;;;;;;;;;-1:-1:-1;;;37799:63:0;;;;;;;;;;;;;;;37877:9;37873:110;37896:11;37892:1;:15;37873:110;;;37928:43;37946:8;37955:1;37946:11;;;;;;;;;;;;;;37959:8;37968:1;37959:11;;;;;;;;;;;;;;37928:17;:43::i;:::-;37909:3;;37873:110;;;;37535:455;;;;:::o;48176:269::-;-1:-1:-1;;;;;48312:23:0;;;48266:11;48312:23;;;:14;:23;;;;;;48266:11;;48312:23;48354:20;48346:54;;;;;-1:-1:-1;;;48346:54:0;;;;;;;;;;;;-1:-1:-1;;;48346:54:0;;;;;;;;;;;;;;;48430:6;48176:269;-1:-1:-1;;48176:269:0:o;48662:174::-;48796:32;;;-1:-1:-1;;;48796:32:0;;48822:4;48796:32;;;;;;48756:15;;-1:-1:-1;;;;;48796:17:0;;;;;:32;;;;;;;;;;;;;;;:17;:32;;;5:2:-1;;;;30:1;27;20:12;5:2;48796:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48796:32:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;48796:32:0;;48662:174;-1:-1:-1;;48662:174:0:o;46968:327::-;47045:16;47079:19;47131:15;;;;;;;;;-1:-1:-1;;;;;47131:15:0;-1:-1:-1;;;;;47101:61:0;;:63;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47101:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47101:63:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;47101:63:0;;-1:-1:-1;;;;;;47183:25:0;;47175:65;;;;;-1:-1:-1;;;47175:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;47275:11;-1:-1:-1;46968:327:0;:::o;11880:136::-;11938:7;11965:43;11969:1;11972;11965:43;;;;;;;;;;;;;;;;;:3;:43::i;41111:139::-;41197:7;41233:1;41229;:5;:13;;41241:1;41229:13;;;-1:-1:-1;41237:1:0;41111:139;-1:-1:-1;41111:139:0:o;29456:176::-;29565:58;;;-1:-1:-1;;;;;29565:58:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;29565:58:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;29539:85:0;;29558:5;;29539:18;:85::i;47502:359::-;47583:15;47616:31;47680:15;;;;;;;;;-1:-1:-1;;;;;47680:15:0;-1:-1:-1;;;;;47650:65:0;;:67;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47650:67:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47650:67:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;47650:67:0;;-1:-1:-1;;;;;;47736:47:0;;47728:92;;;;;-1:-1:-1;;;47728:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;33466:204;33563:39;-1:-1:-1;;;;;33563:26:0;;33590:8;33600:1;33563:39;:26;:39;:::i;:::-;33613:49;-1:-1:-1;;;;;33613:26:0;;33640:8;-1:-1:-1;;33613:49:0;:26;:49;:::i;46378:276::-;46478:24;46505:21;:19;:21::i;:::-;46478:48;;46586:60;46620:7;46629:16;46586:33;:60::i;5342:200::-;-1:-1:-1;;;;;5407:20:0;;5399:54;;;;;-1:-1:-1;;;5399:54:0;;;;;;;;;;;;-1:-1:-1;;;5399:54:0;;;;;;;;;;;;;;;5464:5;:22;;-1:-1:-1;;;;;;5464:22:0;-1:-1:-1;;;;;5464:22:0;;;;;5497:37;:35;:37::i;:::-;5342:200;:::o;8915:261::-;-1:-1:-1;;;;;8984:22:0;;8976:50;;;;;-1:-1:-1;;;8976:50:0;;;;;;;;;;;;-1:-1:-1;;;8976:50:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;9047:19:0;;;;;;:9;:19;;;;;;;;9045:21;9037:53;;;;;-1:-1:-1;;;9037:53:0;;;;;;;;;;;;-1:-1:-1;;;9037:53:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;9103:19:0;;;;;;:9;:19;;;;;;:26;;-1:-1:-1;;9103:26:0;9125:4;9103:26;;;9147:21;;;9103:19;9147:21;8915:261;:::o;12353:192::-;12439:7;12475:12;12467:6;;;;12459:29;;;;-1:-1:-1;;;12459:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;12459:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;12511:5:0;;;12353:192::o;31495:1114::-;32099:27;32107:5;-1:-1:-1;;;;;32099:25:0;;:27::i;:::-;32091:71;;;;;-1:-1:-1;;;32091:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;32236:12;32250:23;32285:5;-1:-1:-1;;;;;32277:19:0;32297:4;32277:25;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;32277:25:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;32235:67:0;;;;32321:7;32313:52;;;;;-1:-1:-1;;;32313:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32382:17;;:21;32378:224;;32524:10;32513:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;32513:30:0;32505:85;;;;-1:-1:-1;;;32505:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31495:1114;;;;:::o;29852:621::-;30222:10;;;30221:62;;-1:-1:-1;30238:39:0;;;-1:-1:-1;;;30238:39:0;;30262:4;30238:39;;;;-1:-1:-1;;;;;30238:39:0;;;;;;;;;:15;;;;;;:39;;;;;;;;;;;;;;;:15;:39;;;5:2:-1;;;;30:1;27;20:12;5:2;30238:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;30238:39:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;30238:39:0;:44;30221:62;30213:152;;;;-1:-1:-1;;;30213:152:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30402:62;;;-1:-1:-1;;;;;30402:62:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;30402:62:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;30376:89:0;;30395:5;;30376:18;:89::i;2882:623::-;3107:23;;;-1:-1:-1;;;3107:23:0;;;;;;;;;;;;;;3090:14;:40;-1:-1:-1;;;3155:20:0;;;;;;;;;;;;;;3141:11;:34;-1:-1:-1;;;3204:23:0;;;;;;;;;;;;;3186:15;:41;-1:-1:-1;;;3257:22:0;;;;;;;;;;;;;;3240:14;:39;-1:-1:-1;;;3304:20:0;;;;;;;;;;;;;3290:11;:34;-1:-1:-1;;;3358:29:0;;;;;;;;;;;;3335:20;:52;-1:-1:-1;;;3415:22:0;;;;;;;;;;;3398:14;:39;-1:-1:-1;;;3470:27:0;;;;;;;;;;;;3448:19;:49;2882:623::o;27046:619::-;27106:4;27574:20;;27417:66;27614:23;;;;;;:42;;-1:-1:-1;27641:15:0;;;27614:42;27606:51;27046:619;-1:-1:-1;;;;27046:619:0:o
Swarm Source
bzzr://1b95b45862e45392ea5068e238d754d160ac6127f53ab2bdd9bb6ce7f7b01442
Loading...
Loading
Loading...
Loading
OVERVIEW
The logic contract for mStable: mUSD Aave VaultNet Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 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.