Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Aave Migrati... | 12321231 | 1397 days ago | IN | 0 ETH | 0.0014507 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
AaveMigrationReceiver
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-04-27 */ pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; interface ERC20 { function totalSupply() external view returns (uint256 supply); function balanceOf(address _owner) external view returns (uint256 balance); function transfer(address _to, uint256 _value) external returns (bool success); function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); function approve(address _spender, uint256 _value) external returns (bool success); function allowance(address _owner, address _spender) external view returns (uint256 remaining); function decimals() external view returns (uint256 digits); event Approval(address indexed _owner, address indexed _spender, uint256 _value); } library Address { 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); } function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } 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"); } 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"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); 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 // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } 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; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 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; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(ERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(ERC20 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. */ function safeApprove(ERC20 token, address spender, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(ERC20 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(ERC20 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)); } function _callOptionalReturn(ERC20 token, bytes memory data) private { bytes memory returndata = address(token).functionCall(data, "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"); } } } abstract contract DSAuthority { function canCall(address src, address dst, bytes4 sig) public virtual view returns (bool); } contract DSAuthEvents { event LogSetAuthority(address indexed authority); event LogSetOwner(address indexed owner); } contract DSAuth is DSAuthEvents { DSAuthority public authority; address public owner; constructor() public { owner = msg.sender; emit LogSetOwner(msg.sender); } function setOwner(address owner_) public auth { owner = owner_; emit LogSetOwner(owner); } function setAuthority(DSAuthority authority_) public auth { authority = authority_; emit LogSetAuthority(address(authority)); } modifier auth { require(isAuthorized(msg.sender, msg.sig)); _; } function isAuthorized(address src, bytes4 sig) internal view returns (bool) { if (src == address(this)) { return true; } else if (src == owner) { return true; } else if (authority == DSAuthority(0)) { return false; } else { return authority.canCall(src, address(this), sig); } } } contract DSNote { event LogNote( bytes4 indexed sig, address indexed guy, bytes32 indexed foo, bytes32 indexed bar, uint256 wad, bytes fax ) anonymous; modifier note { bytes32 foo; bytes32 bar; assembly { foo := calldataload(4) bar := calldataload(36) } emit LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data); _; } } abstract contract DSProxy is DSAuth, DSNote { DSProxyCache public cache; // global cache for contracts constructor(address _cacheAddr) public { require(setCache(_cacheAddr)); } // solhint-disable-next-line no-empty-blocks receive() external payable {} // use the proxy to execute calldata _data on contract _code // function execute(bytes memory _code, bytes memory _data) // public // payable // virtual // returns (address target, bytes32 response); function execute(address _target, bytes memory _data) public payable virtual returns (bytes32 response); //set new cache function setCache(address _cacheAddr) public virtual payable returns (bool); } contract DSProxyCache { mapping(bytes32 => address) cache; function read(bytes memory _code) public view returns (address) { bytes32 hash = keccak256(_code); return cache[hash]; } function write(bytes memory _code) public returns (address target) { assembly { target := create(0, add(_code, 0x20), mload(_code)) switch iszero(extcodesize(target)) case 1 { // throw if contract failed to deploy revert(0, 0) } } bytes32 hash = keccak256(_code); cache[hash] = target; } } contract AdminAuth { using SafeERC20 for ERC20; address public owner; address public admin; modifier onlyOwner() { require(owner == msg.sender); _; } modifier onlyAdmin() { require(admin == msg.sender); _; } constructor() public { owner = msg.sender; admin = 0x25eFA336886C74eA8E282ac466BdCd0199f85BB9; } /// @notice Admin is set by owner first time, after that admin is super role and has permission to change owner /// @param _admin Address of multisig that becomes admin function setAdminByOwner(address _admin) public { require(msg.sender == owner); require(admin == address(0)); admin = _admin; } /// @notice Admin is able to set new admin /// @param _admin Address of multisig that becomes new admin function setAdminByAdmin(address _admin) public { require(msg.sender == admin); admin = _admin; } /// @notice Admin is able to change owner /// @param _owner Address of new owner function setOwnerByAdmin(address _owner) public { require(msg.sender == admin); owner = _owner; } /// @notice Destroy the contract function kill() public onlyOwner { selfdestruct(payable(owner)); } /// @notice withdraw stuck funds function withdrawStuckFunds(address _token, uint _amount) public onlyOwner { if (_token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) { payable(owner).transfer(_amount); } else { ERC20(_token).safeTransfer(owner, _amount); } } } abstract contract IAaveProtocolDataProviderV2 { struct TokenData { string symbol; address tokenAddress; } function getAllReservesTokens() external virtual view returns (TokenData[] memory); function getAllATokens() external virtual view returns (TokenData[] memory); function getReserveConfigurationData(address asset) external virtual view returns ( uint256 decimals, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, uint256 reserveFactor, bool usageAsCollateralEnabled, bool borrowingEnabled, bool stableBorrowRateEnabled, bool isActive, bool isFrozen ); function getReserveData(address asset) external virtual view returns ( uint256 availableLiquidity, uint256 totalStableDebt, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp ); function getUserReserveData(address asset, address user) external virtual view returns ( uint256 currentATokenBalance, uint256 currentStableDebt, uint256 currentVariableDebt, uint256 principalStableDebt, uint256 scaledVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, uint40 stableRateLastUpdated, bool usageAsCollateralEnabled ); function getReserveTokensAddresses(address asset) external virtual view returns ( address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress ); } /** * @title LendingPoolAddressesProvider contract * @dev Main registry of addresses part of or connected to the protocol, including permissioned roles * - Acting also as factory of proxies and admin of those, so with right to change its implementations * - Owned by the Aave Governance * @author Aave **/ interface ILendingPoolAddressesProviderV2 { event LendingPoolUpdated(address indexed newAddress); event ConfigurationAdminUpdated(address indexed newAddress); event EmergencyAdminUpdated(address indexed newAddress); event LendingPoolConfiguratorUpdated(address indexed newAddress); event LendingPoolCollateralManagerUpdated(address indexed newAddress); event PriceOracleUpdated(address indexed newAddress); event LendingRateOracleUpdated(address indexed newAddress); event ProxyCreated(bytes32 id, address indexed newAddress); event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy); function setAddress(bytes32 id, address newAddress) external; function setAddressAsProxy(bytes32 id, address impl) external; function getAddress(bytes32 id) external view returns (address); function getLendingPool() external view returns (address); function setLendingPoolImpl(address pool) external; function getLendingPoolConfigurator() external view returns (address); function setLendingPoolConfiguratorImpl(address configurator) external; function getLendingPoolCollateralManager() external view returns (address); function setLendingPoolCollateralManager(address manager) external; function getPoolAdmin() external view returns (address); function setPoolAdmin(address admin) external; function getEmergencyAdmin() external view returns (address); function setEmergencyAdmin(address admin) external; function getPriceOracle() external view returns (address); function setPriceOracle(address priceOracle) external; function getLendingRateOracle() external view returns (address); function setLendingRateOracle(address lendingRateOracle) external; } library DataTypes { // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. struct ReserveData { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; //the current stable borrow rate. Expressed in ray uint128 currentStableBorrowRate; uint40 lastUpdateTimestamp; //tokens addresses address aTokenAddress; address stableDebtTokenAddress; address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the id of the reserve. Represents the position in the list of the active reserves uint8 id; } struct ReserveConfigurationMap { //bit 0-15: LTV //bit 16-31: Liq. threshold //bit 32-47: Liq. bonus //bit 48-55: Decimals //bit 56: Reserve is active //bit 57: reserve is frozen //bit 58: borrowing is enabled //bit 59: stable rate borrowing enabled //bit 60-63: reserved //bit 64-79: reserve factor uint256 data; } struct UserConfigurationMap { uint256 data; } enum InterestRateMode {NONE, STABLE, VARIABLE} } interface ILendingPoolV2 { /** * @dev Emitted on deposit() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the deposit * @param onBehalfOf The beneficiary of the deposit, receiving the aTokens * @param amount The amount deposited * @param referral The referral code used **/ event Deposit( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referral ); /** * @dev Emitted on withdraw() * @param reserve The address of the underlyng asset being withdrawn * @param user The address initiating the withdrawal, owner of aTokens * @param to Address that will receive the underlying * @param amount The amount to be withdrawn **/ event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); /** * @dev Emitted on borrow() and flashLoan() when debt needs to be opened * @param reserve The address of the underlying asset being borrowed * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just * initiator of the transaction on flashLoan() * @param onBehalfOf The address that will be getting the debt * @param amount The amount borrowed out * @param borrowRateMode The rate mode: 1 for Stable, 2 for Variable * @param borrowRate The numeric rate at which the user has borrowed * @param referral The referral code used **/ event Borrow( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint256 borrowRateMode, uint256 borrowRate, uint16 indexed referral ); /** * @dev Emitted on repay() * @param reserve The address of the underlying asset of the reserve * @param user The beneficiary of the repayment, getting his debt reduced * @param repayer The address of the user initiating the repay(), providing the funds * @param amount The amount repaid **/ event Repay( address indexed reserve, address indexed user, address indexed repayer, uint256 amount ); /** * @dev Emitted on swapBorrowRateMode() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user swapping his rate mode * @param rateMode The rate mode that the user wants to swap to **/ event Swap(address indexed reserve, address indexed user, uint256 rateMode); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral **/ event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral **/ event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); /** * @dev Emitted on rebalanceStableBorrowRate() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user for which the rebalance has been executed **/ event RebalanceStableBorrowRate(address indexed reserve, address indexed user); /** * @dev Emitted on flashLoan() * @param target The address of the flash loan receiver contract * @param initiator The address initiating the flash loan * @param asset The address of the asset being flash borrowed * @param amount The amount flash borrowed * @param premium The fee flash borrowed * @param referralCode The referral code used **/ event FlashLoan( address indexed target, address indexed initiator, address indexed asset, uint256 amount, uint256 premium, uint16 referralCode ); /** * @dev Emitted when the pause is triggered. */ event Paused(); /** * @dev Emitted when the pause is lifted. */ event Unpaused(); /** * @dev Emitted when a borrower is liquidated. This event is emitted by the LendingPool via * LendingPoolCollateral manager using a DELEGATECALL * This allows to have the events in the generated ABI for LendingPool. * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param liquidatedCollateralAmount The amount of collateral received by the liiquidator * @param liquidator The address of the liquidator * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly **/ event LiquidationCall( address indexed collateralAsset, address indexed debtAsset, address indexed user, uint256 debtToCover, uint256 liquidatedCollateralAmount, address liquidator, bool receiveAToken ); /** * @dev Emitted when the state of a reserve is updated. NOTE: This event is actually declared * in the ReserveLogic library and emitted in the updateInterestRates() function. Since the function is internal, * the event will actually be fired by the LendingPool contract. The event is therefore replicated here so it * gets added to the LendingPool ABI * @param reserve The address of the underlying asset of the reserve * @param liquidityRate The new liquidity rate * @param stableBorrowRate The new stable borrow rate * @param variableBorrowRate The new variable borrow rate * @param liquidityIndex The new liquidity index * @param variableBorrowIndex The new variable borrow index **/ event ReserveDataUpdated( address indexed reserve, uint256 liquidityRate, uint256 stableBorrowRate, uint256 variableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex ); /** * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User deposits 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to deposit * @param amount The amount to be deposited * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man **/ function deposit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * - Send the value type(uint256).max in order to withdraw the whole aToken balance * @param to Address that will receive the underlying, same as msg.sender if the user * wants to receive it on his own wallet, or a different address if the beneficiary is a * different wallet **/ function withdraw( address asset, uint256 amount, address to ) external; /** * @dev Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower * already deposited enough collateral, or he was given enough allowance by a credit delegator on the * corresponding debt token (StableDebtToken or VariableDebtToken) * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet * and 100 stable/variable debt tokens, depending on the `interestRateMode` * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param onBehalfOf Address of the user who will receive the debt. Should be the address of the borrower itself * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator * if he has been given credit delegation allowance **/ function borrow( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; /** * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed **/ function repay( address asset, uint256 amount, uint256 rateMode, address onBehalfOf ) external; /** * @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa * @param asset The address of the underlying asset borrowed * @param rateMode The rate mode that the user wants to swap to **/ function swapBorrowRateMode(address asset, uint256 rateMode) external; /** * @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. * - Users can be rebalanced if the following conditions are satisfied: * 1. Usage ratio is above 95% * 2. the current deposit APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too much has been * borrowed at a stable rate and depositors are not earning enough * @param asset The address of the underlying asset borrowed * @param user The address of the user to be rebalanced **/ function rebalanceStableBorrowRate(address asset, address user) external; /** * @dev Allows depositors to enable/disable a specific deposited asset as collateral * @param asset The address of the underlying asset deposited * @param useAsCollateral `true` if the user wants to use the deposit as collateral, `false` otherwise **/ function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; /** * @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly **/ function liquidationCall( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external; /** * @dev Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept into consideration. * For further details please visit https://developers.aave.com * @param receiverAddress The address of the contract receiving the funds, implementing the IFlashLoanReceiver interface * @param assets The addresses of the assets being flash-borrowed * @param amounts The amounts amounts being flash-borrowed * @param modes Types of the debt to open if the flash loan is not returned: * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver * 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2 * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man **/ function flashLoan( address receiverAddress, address[] calldata assets, uint256[] calldata amounts, uint256[] calldata modes, address onBehalfOf, bytes calldata params, uint16 referralCode ) external; /** * @dev Returns the user account data across all the reserves * @param user The address of the user * @return totalCollateralETH the total collateral in ETH of the user * @return totalDebtETH the total debt in ETH of the user * @return availableBorrowsETH the borrowing power left of the user * @return currentLiquidationThreshold the liquidation threshold of the user * @return ltv the loan to value of the user * @return healthFactor the current health factor of the user **/ function getUserAccountData(address user) external view returns ( uint256 totalCollateralETH, uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); function initReserve( address reserve, address aTokenAddress, address stableDebtAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; function setReserveInterestRateStrategyAddress(address reserve, address rateStrategyAddress) external; function setConfiguration(address reserve, uint256 configuration) external; /** * @dev Returns the configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The configuration of the reserve **/ function getConfiguration(address asset) external view returns (DataTypes.ReserveConfigurationMap memory); /** * @dev Returns the configuration of the user across all the reserves * @param user The user address * @return The configuration of the user **/ function getUserConfiguration(address user) external view returns (DataTypes.UserConfigurationMap memory); /** * @dev Returns the normalized income normalized income of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve's normalized income */ function getReserveNormalizedIncome(address asset) external view returns (uint256); /** * @dev Returns the normalized variable debt per unit of asset * @param asset The address of the underlying asset of the reserve * @return The reserve normalized variable debt */ function getReserveNormalizedVariableDebt(address asset) external view returns (uint256); /** * @dev Returns the state and configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The state of the reserve **/ function getReserveData(address asset) external view returns (DataTypes.ReserveData memory); function finalizeTransfer( address asset, address from, address to, uint256 amount, uint256 balanceFromAfter, uint256 balanceToBefore ) external; function getReservesList() external view returns (address[] memory); function getAddressesProvider() external view returns (ILendingPoolAddressesProviderV2); function setPause(bool val) external; function paused() external view returns (bool); } abstract contract TokenInterface { address public constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; function allowance(address, address) public virtual returns (uint256); function balanceOf(address) public virtual returns (uint256); function approve(address, uint256) public virtual; function transfer(address, uint256) public virtual returns (bool); function transferFrom(address, address, uint256) public virtual returns (bool); function deposit() public virtual payable; function withdraw(uint256) public virtual; } abstract contract IAToken { function redeem(uint256 _amount) external virtual; function balanceOf(address _owner) external virtual view returns (uint256 balance); } abstract contract ILendingPool { function flashLoan( address payable _receiver, address _reserve, uint _amount, bytes calldata _params) external virtual; function deposit(address _reserve, uint256 _amount, uint16 _referralCode) external virtual payable; function setUserUseReserveAsCollateral(address _reserve, bool _useAsCollateral) external virtual; function borrow(address _reserve, uint256 _amount, uint256 _interestRateMode, uint16 _referralCode) external virtual; function repay( address _reserve, uint256 _amount, address payable _onBehalfOf) external virtual payable; function swapBorrowRateMode(address _reserve) external virtual; function getReserves() external virtual view returns(address[] memory); /// @param _reserve underlying token address function getReserveData(address _reserve) external virtual view returns ( uint256 totalLiquidity, // reserve total liquidity uint256 availableLiquidity, // reserve available liquidity for borrowing uint256 totalBorrowsStable, // total amount of outstanding borrows at Stable rate uint256 totalBorrowsVariable, // total amount of outstanding borrows at Variable rate uint256 liquidityRate, // current deposit APY of the reserve for depositors, in Ray units. uint256 variableBorrowRate, // current variable rate APY of the reserve pool, in Ray units. uint256 stableBorrowRate, // current stable rate APY of the reserve pool, in Ray units. uint256 averageStableBorrowRate, // current average stable borrow rate uint256 utilizationRate, // expressed as total borrows/total liquidity. uint256 liquidityIndex, // cumulative liquidity index uint256 variableBorrowIndex, // cumulative variable borrow index address aTokenAddress, // aTokens contract address for the specific _reserve uint40 lastUpdateTimestamp // timestamp of the last update of reserve data ); /// @param _user users address function getUserAccountData(address _user) external virtual view returns ( uint256 totalLiquidityETH, // user aggregated deposits across all the reserves. In Wei uint256 totalCollateralETH, // user aggregated collateral across all the reserves. In Wei uint256 totalBorrowsETH, // user aggregated outstanding borrows across all the reserves. In Wei uint256 totalFeesETH, // user aggregated current outstanding fees in ETH. In Wei uint256 availableBorrowsETH, // user available amount to borrow in ETH uint256 currentLiquidationThreshold, // user current average liquidation threshold across all the collaterals deposited uint256 ltv, // user average Loan-to-Value between all the collaterals uint256 healthFactor // user current Health Factor ); /// @param _reserve underlying token address /// @param _user users address function getUserReserveData(address _reserve, address _user) external virtual view returns ( uint256 currentATokenBalance, // user current reserve aToken balance uint256 currentBorrowBalance, // user current reserve outstanding borrow balance uint256 principalBorrowBalance, // user balance of borrowed asset uint256 borrowRateMode, // user borrow rate mode either Stable or Variable uint256 borrowRate, // user current borrow rate APY uint256 liquidityRate, // user current earn rate on _reserve uint256 originationFee, // user outstanding loan origination fee uint256 variableBorrowIndex, // user variable cumulative index uint256 lastUpdateTimestamp, // Timestamp of the last data update bool usageAsCollateralEnabled // Whether the user's current reserve is enabled as a collateral ); function getReserveConfigurationData(address _reserve) external virtual view returns ( uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, address rateStrategyAddress, bool usageAsCollateralEnabled, bool borrowingEnabled, bool stableBorrowRateEnabled, bool isActive ); // ------------------ LendingPoolCoreData ------------------------ function getReserveATokenAddress(address _reserve) public virtual view returns (address); function getReserveConfiguration(address _reserve) external virtual view returns (uint256, uint256, uint256, bool); function getUserUnderlyingAssetBalance(address _reserve, address _user) public virtual view returns (uint256); function getReserveCurrentLiquidityRate(address _reserve) public virtual view returns (uint256); function getReserveCurrentVariableBorrowRate(address _reserve) public virtual view returns (uint256); function getReserveCurrentStableBorrowRate(address _reserve) public virtual view returns (uint256); function getReserveTotalLiquidity(address _reserve) public virtual view returns (uint256); function getReserveAvailableLiquidity(address _reserve) public virtual view returns (uint256); function getReserveTotalBorrowsVariable(address _reserve) public virtual view returns (uint256); function getReserveTotalBorrowsStable(address _reserve) public virtual view returns (uint256); // ---------------- LendingPoolDataProvider --------------------- function calculateUserGlobalData(address _user) public virtual view returns ( uint256 totalLiquidityBalanceETH, uint256 totalCollateralBalanceETH, uint256 totalBorrowBalanceETH, uint256 totalFeesETH, uint256 currentLtv, uint256 currentLiquidationThreshold, uint256 healthFactor, bool healthFactorBelowThreshold ); } /** @title ILendingPoolAddressesProvider interface @notice provides the interface to fetch the LendingPoolCore address */ abstract contract ILendingPoolAddressesProvider { function getLendingPool() public virtual view returns (address); function getLendingPoolCore() public virtual view returns (address payable); function getLendingPoolConfigurator() public virtual view returns (address); function getLendingPoolDataProvider() public virtual view returns (address); function getLendingPoolParametersProvider() public virtual view returns (address); function getTokenDistributor() public virtual view returns (address); function getFeeProvider() public virtual view returns (address); function getLendingPoolLiquidationManager() public virtual view returns (address); function getLendingPoolManager() public virtual view returns (address); function getPriceOracle() public virtual view returns (address); function getLendingRateOracle() public virtual view returns (address); } contract AaveMigration { using SafeERC20 for ERC20; address public constant ETH_ADDR = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; uint16 public constant AAVE_REFERRAL_CODE = 64; address public constant AAVE_V1_LENDING_POOL_ADDRESSES = 0x24a42fD28C976A61Df5D00D0599C34c4f90748c8; struct MigrateLoanData { address market; address[] collAssets; bool[] isColl; address[] borrowAssets; uint256[] borrowAmounts; uint256[] fees; uint256[] modes; } function migrateLoan(MigrateLoanData memory _loanData) public { address lendingPoolCoreV1 = ILendingPoolAddressesProvider(AAVE_V1_LENDING_POOL_ADDRESSES).getLendingPoolCore(); address lendingPoolV2 = ILendingPoolAddressesProviderV2(_loanData.market).getLendingPool(); // payback AaveV1 loans for (uint256 i = 0; i < _loanData.borrowAssets.length; ++i) { paybackAaveV1(lendingPoolCoreV1, _loanData.borrowAssets[i], _loanData.borrowAmounts[i]); } // withdraw from AaveV1 and deposit to V2 for (uint256 i = 0; i < _loanData.collAssets.length; ++i) { address aTokenAddr = ILendingPool(lendingPoolCoreV1).getReserveATokenAddress(_loanData.collAssets[i]); uint256 withdrawnAmount = withdrawAaveV1(aTokenAddr); depositAaveV2( lendingPoolV2, _loanData.market, _loanData.collAssets[i], withdrawnAmount, _loanData.isColl[i] ); } // borrow debt from AaveV2 for (uint256 i = 0; i < _loanData.borrowAssets.length; ++i) { borrowAaveV2( lendingPoolV2, _loanData.borrowAssets[i], (_loanData.borrowAmounts[i] + _loanData.fees[i]), _loanData.modes[i] ); } } function depositAaveV2( address _lendingPoolV2, address _market, address _tokenAddr, uint256 _amount, bool _isColl ) internal { // handle weth if (_tokenAddr == ETH_ADDR) { TokenInterface(WETH_ADDRESS).deposit{value: _amount}(); _tokenAddr = WETH_ADDRESS; } ERC20(_tokenAddr).safeApprove(_lendingPoolV2, _amount); ILendingPoolV2(_lendingPoolV2).deposit( _tokenAddr, _amount, address(this), AAVE_REFERRAL_CODE ); if (_isColl) { setUserUseReserveAsCollateralIfNeeded(_lendingPoolV2, _market, _tokenAddr); } } function borrowAaveV2( address _lendingPoolV2, address _tokenAddr, uint256 _amount, uint256 _type ) internal { _tokenAddr = _tokenAddr == ETH_ADDR ? WETH_ADDRESS : _tokenAddr; ILendingPoolV2(_lendingPoolV2).borrow( _tokenAddr, _amount, _type, AAVE_REFERRAL_CODE, address(this) ); ERC20(_tokenAddr).safeTransfer(msg.sender, _amount); } function withdrawAaveV1(address _aTokenAddr) internal returns (uint256 amount) { amount = ERC20(_aTokenAddr).balanceOf(address(this)); IAToken(_aTokenAddr).redeem(amount); } function paybackAaveV1( address _lendingPoolCore, address _tokenAddr, uint256 _amount ) internal { address lendingPool = ILendingPoolAddressesProvider(AAVE_V1_LENDING_POOL_ADDRESSES).getLendingPool(); uint256 ethAmount = 0; if (_tokenAddr != WETH_ADDRESS) { ERC20(_tokenAddr).safeApprove(_lendingPoolCore, uint(-1)); } else { ethAmount = _amount; TokenInterface(WETH_ADDRESS).withdraw(ethAmount); } ILendingPool(lendingPool).repay{value: ethAmount}( _tokenAddr, _amount, payable(address(this)) ); } function setUserUseReserveAsCollateralIfNeeded( address _lendingPoolV2, address _market, address _tokenAddr ) public { IAaveProtocolDataProviderV2 dataProvider = getDataProvider(_market); (, , , , , , , , bool collateralEnabled) = dataProvider.getUserReserveData(_tokenAddr, address(this)); if (!collateralEnabled) { ILendingPoolV2(_lendingPoolV2).setUserUseReserveAsCollateral(_tokenAddr, true); } } function getDataProvider(address _market) internal view returns (IAaveProtocolDataProviderV2) { return IAaveProtocolDataProviderV2( ILendingPoolAddressesProviderV2(_market).getAddress( 0x0100000000000000000000000000000000000000000000000000000000000000 ) ); } } /// @title Stores subscription information for Aave automatization contract AaveSubscriptions is AdminAuth { struct AaveHolder { address user; uint128 minRatio; uint128 maxRatio; uint128 optimalRatioBoost; uint128 optimalRatioRepay; bool boostEnabled; } struct SubPosition { uint arrPos; bool subscribed; } AaveHolder[] public subscribers; mapping (address => SubPosition) public subscribersPos; uint public changeIndex; event Subscribed(address indexed user); event Unsubscribed(address indexed user); event Updated(address indexed user); event ParamUpdates(address indexed user, uint128, uint128, uint128, uint128, bool); /// @dev Called by the DSProxy contract which owns the Aave position /// @notice Adds the users Aave poistion in the list of subscriptions so it can be monitored /// @param _minRatio Minimum ratio below which repay is triggered /// @param _maxRatio Maximum ratio after which boost is triggered /// @param _optimalBoost Ratio amount which boost should target /// @param _optimalRepay Ratio amount which repay should target /// @param _boostEnabled Boolean determing if boost is enabled function subscribe(uint128 _minRatio, uint128 _maxRatio, uint128 _optimalBoost, uint128 _optimalRepay, bool _boostEnabled) external { // if boost is not enabled, set max ratio to max uint uint128 localMaxRatio = _boostEnabled ? _maxRatio : uint128(-1); require(checkParams(_minRatio, localMaxRatio), "Must be correct params"); SubPosition storage subInfo = subscribersPos[msg.sender]; AaveHolder memory subscription = AaveHolder({ minRatio: _minRatio, maxRatio: localMaxRatio, optimalRatioBoost: _optimalBoost, optimalRatioRepay: _optimalRepay, user: msg.sender, boostEnabled: _boostEnabled }); changeIndex++; if (subInfo.subscribed) { subscribers[subInfo.arrPos] = subscription; emit Updated(msg.sender); emit ParamUpdates(msg.sender, _minRatio, localMaxRatio, _optimalBoost, _optimalRepay, _boostEnabled); } else { subscribers.push(subscription); subInfo.arrPos = subscribers.length - 1; subInfo.subscribed = true; emit Subscribed(msg.sender); } } /// @notice Called by the users DSProxy /// @dev Owner who subscribed cancels his subscription function unsubscribe() external { _unsubscribe(msg.sender); } /// @dev Checks limit if minRatio is bigger than max /// @param _minRatio Minimum ratio, bellow which repay can be triggered /// @param _maxRatio Maximum ratio, over which boost can be triggered /// @return Returns bool if the params are correct function checkParams(uint128 _minRatio, uint128 _maxRatio) internal pure returns (bool) { if (_minRatio > _maxRatio) { return false; } return true; } /// @dev Internal method to remove a subscriber from the list /// @param _user The actual address that owns the Aave position function _unsubscribe(address _user) internal { require(subscribers.length > 0, "Must have subscribers in the list"); SubPosition storage subInfo = subscribersPos[_user]; require(subInfo.subscribed, "Must first be subscribed"); address lastOwner = subscribers[subscribers.length - 1].user; SubPosition storage subInfo2 = subscribersPos[lastOwner]; subInfo2.arrPos = subInfo.arrPos; subscribers[subInfo.arrPos] = subscribers[subscribers.length - 1]; subscribers.pop(); // remove last element and reduce arr length changeIndex++; subInfo.subscribed = false; subInfo.arrPos = 0; emit Unsubscribed(msg.sender); } /// @dev Checks if the user is subscribed /// @param _user The actual address that owns the Aave position /// @return If the user is subscribed function isSubscribed(address _user) public view returns (bool) { SubPosition storage subInfo = subscribersPos[_user]; return subInfo.subscribed; } /// @dev Returns subscribtion information about a user /// @param _user The actual address that owns the Aave position /// @return Subscription information about the user if exists function getHolder(address _user) public view returns (AaveHolder memory) { SubPosition storage subInfo = subscribersPos[_user]; return subscribers[subInfo.arrPos]; } /// @notice Helper method to return all the subscribed CDPs /// @return List of all subscribers function getSubscribers() public view returns (AaveHolder[] memory) { return subscribers; } /// @notice Helper method for the frontend, returns all the subscribed CDPs paginated /// @param _page What page of subscribers you want /// @param _perPage Number of entries per page /// @return List of all subscribers for that page function getSubscribersByPage(uint _page, uint _perPage) public view returns (AaveHolder[] memory) { AaveHolder[] memory holders = new AaveHolder[](_perPage); uint start = _page * _perPage; uint end = start + _perPage; end = (end > holders.length) ? holders.length : end; uint count = 0; for (uint i = start; i < end; i++) { holders[count] = subscribers[i]; count++; } return holders; } ////////////// ADMIN METHODS /////////////////// /// @notice Admin function to unsubscribe a position /// @param _user The actual address that owns the Aave position function unsubscribeByAdmin(address _user) public onlyOwner { SubPosition storage subInfo = subscribersPos[_user]; if (subInfo.subscribed) { _unsubscribe(_user); } } } /// @title Stores subscription information for Aave automatization contract AaveSubscriptionsV2 is AdminAuth { string public constant NAME = "AaveSubscriptionsV2"; struct AaveHolder { address user; uint128 minRatio; uint128 maxRatio; uint128 optimalRatioBoost; uint128 optimalRatioRepay; bool boostEnabled; } struct SubPosition { uint arrPos; bool subscribed; } AaveHolder[] public subscribers; mapping (address => SubPosition) public subscribersPos; uint public changeIndex; event Subscribed(address indexed user); event Unsubscribed(address indexed user); event Updated(address indexed user); event ParamUpdates(address indexed user, uint128, uint128, uint128, uint128, bool); /// @dev Called by the DSProxy contract which owns the Aave position /// @notice Adds the users Aave poistion in the list of subscriptions so it can be monitored /// @param _minRatio Minimum ratio below which repay is triggered /// @param _maxRatio Maximum ratio after which boost is triggered /// @param _optimalBoost Ratio amount which boost should target /// @param _optimalRepay Ratio amount which repay should target /// @param _boostEnabled Boolean determing if boost is enabled function subscribe(uint128 _minRatio, uint128 _maxRatio, uint128 _optimalBoost, uint128 _optimalRepay, bool _boostEnabled) external { // if boost is not enabled, set max ratio to max uint uint128 localMaxRatio = _boostEnabled ? _maxRatio : uint128(-1); require(checkParams(_minRatio, localMaxRatio), "Must be correct params"); SubPosition storage subInfo = subscribersPos[msg.sender]; AaveHolder memory subscription = AaveHolder({ minRatio: _minRatio, maxRatio: localMaxRatio, optimalRatioBoost: _optimalBoost, optimalRatioRepay: _optimalRepay, user: msg.sender, boostEnabled: _boostEnabled }); changeIndex++; if (subInfo.subscribed) { subscribers[subInfo.arrPos] = subscription; emit Updated(msg.sender); emit ParamUpdates(msg.sender, _minRatio, localMaxRatio, _optimalBoost, _optimalRepay, _boostEnabled); } else { subscribers.push(subscription); subInfo.arrPos = subscribers.length - 1; subInfo.subscribed = true; emit Subscribed(msg.sender); } } /// @notice Called by the users DSProxy /// @dev Owner who subscribed cancels his subscription function unsubscribe() external { _unsubscribe(msg.sender); } /// @dev Checks limit if minRatio is bigger than max /// @param _minRatio Minimum ratio, bellow which repay can be triggered /// @param _maxRatio Maximum ratio, over which boost can be triggered /// @return Returns bool if the params are correct function checkParams(uint128 _minRatio, uint128 _maxRatio) internal pure returns (bool) { if (_minRatio > _maxRatio) { return false; } return true; } /// @dev Internal method to remove a subscriber from the list /// @param _user The actual address that owns the Aave position function _unsubscribe(address _user) internal { require(subscribers.length > 0, "Must have subscribers in the list"); SubPosition storage subInfo = subscribersPos[_user]; require(subInfo.subscribed, "Must first be subscribed"); address lastOwner = subscribers[subscribers.length - 1].user; SubPosition storage subInfo2 = subscribersPos[lastOwner]; subInfo2.arrPos = subInfo.arrPos; subscribers[subInfo.arrPos] = subscribers[subscribers.length - 1]; subscribers.pop(); // remove last element and reduce arr length changeIndex++; subInfo.subscribed = false; subInfo.arrPos = 0; emit Unsubscribed(msg.sender); } /// @dev Checks if the user is subscribed /// @param _user The actual address that owns the Aave position /// @return If the user is subscribed function isSubscribed(address _user) public view returns (bool) { SubPosition storage subInfo = subscribersPos[_user]; return subInfo.subscribed; } /// @dev Returns subscribtion information about a user /// @param _user The actual address that owns the Aave position /// @return Subscription information about the user if exists function getHolder(address _user) public view returns (AaveHolder memory) { SubPosition storage subInfo = subscribersPos[_user]; return subscribers[subInfo.arrPos]; } /// @notice Helper method to return all the subscribed CDPs /// @return List of all subscribers function getSubscribers() public view returns (AaveHolder[] memory) { return subscribers; } /// @notice Helper method for the frontend, returns all the subscribed CDPs paginated /// @param _page What page of subscribers you want /// @param _perPage Number of entries per page /// @return List of all subscribers for that page function getSubscribersByPage(uint _page, uint _perPage) public view returns (AaveHolder[] memory) { AaveHolder[] memory holders = new AaveHolder[](_perPage); uint start = _page * _perPage; uint end = start + _perPage; end = (end > holders.length) ? holders.length : end; uint count = 0; for (uint i = start; i < end; i++) { holders[count] = subscribers[i]; count++; } return holders; } ////////////// ADMIN METHODS /////////////////// /// @notice Admin function to unsubscribe a position /// @param _user The actual address that owns the Aave position function unsubscribeByAdmin(address _user) public onlyOwner { SubPosition storage subInfo = subscribersPos[_user]; if (subInfo.subscribed) { _unsubscribe(_user); } } } abstract contract DSGuard { function canCall(address src_, address dst_, bytes4 sig) public view virtual returns (bool); function permit(bytes32 src, bytes32 dst, bytes32 sig) public virtual; function forbid(bytes32 src, bytes32 dst, bytes32 sig) public virtual; function permit(address src, address dst, bytes32 sig) public virtual; function forbid(address src, address dst, bytes32 sig) public virtual; } abstract contract DSGuardFactory { function newGuard() public virtual returns (DSGuard guard); } contract ProxyPermission { address public constant FACTORY_ADDRESS = 0x5a15566417e6C1c9546523066500bDDBc53F88C7; /// @notice Called in the context of DSProxy to authorize an address /// @param _contractAddr Address which will be authorized function givePermission(address _contractAddr) public { address currAuthority = address(DSAuth(address(this)).authority()); DSGuard guard = DSGuard(currAuthority); if (currAuthority == address(0)) { guard = DSGuardFactory(FACTORY_ADDRESS).newGuard(); DSAuth(address(this)).setAuthority(DSAuthority(address(guard))); } guard.permit(_contractAddr, address(this), bytes4(keccak256("execute(address,bytes)"))); } /// @notice Called in the context of DSProxy to remove authority of an address /// @param _contractAddr Auth address which will be removed from authority list function removePermission(address _contractAddr) public { address currAuthority = address(DSAuth(address(this)).authority()); // if there is no authority, that means that contract doesn't have permission if (currAuthority == address(0)) { return; } DSGuard guard = DSGuard(currAuthority); guard.forbid(_contractAddr, address(this), bytes4(keccak256("execute(address,bytes)"))); } function proxyOwner() internal returns(address) { return DSAuth(address(this)).owner(); } } contract DefisaverLogger { event LogEvent( address indexed contractAddress, address indexed caller, string indexed logName, bytes data ); // solhint-disable-next-line func-name-mixedcase function Log(address _contract, address _caller, string memory _logName, bytes memory _data) public { emit LogEvent(_contract, _caller, _logName, _data); } } /// @title Entry point for an AAVE v1 -> v2 position migration contract AaveMigrationTaker is ProxyPermission { uint16 public constant AAVE_REFERRAL_CODE = 64; address public constant AAVE_V1_LENDING_POOL_ADDRESSES = 0x24a42fD28C976A61Df5D00D0599C34c4f90748c8; address public constant AAVE_V1_SUBSCRIPTION_ADDR = 0xe08ff7A2BADb634F0b581E675E6B3e583De086FC; address public constant AAVE_V2_SUBSCRIPTION_ADDR = 0x6B25043BF08182d8e86056C6548847aF607cd7CD; address public constant AAVE_V1_MONITOR_PROXY = 0xfA560Dba3a8D0B197cA9505A2B98120DD89209AC; address public constant AAVE_V2_MONITOR_PROXY = 0x380982902872836ceC629171DaeAF42EcC02226e; address public constant DEFISAVER_LOGGER = 0x5c55B921f590a89C1Ebe84dF170E655a82b62126; DefisaverLogger public logger = DefisaverLogger(DEFISAVER_LOGGER); address public constant ETH_ADDR = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; struct FlMigrationData { address market; address[] collTokens; uint256[] modes; bool[] isColl; } /// @notice Call through DSProxy to migrate the position on the proxy /// @param _market Market address of Aave V2 /// @param _collTokens Underlying supply addresses where user has non 0 balance /// @param _isColl Bool array indicating if the collTokens are set as collateral /// @param _borrowTokens Underlying borrow addresses where user has non 0 debt /// @param _flModes Type of aave V2 loan (array of 0 same size as borrowTokens) /// @param _aaveMigrationReceiverAddr Receiver address for aave fl function migrateV1Position( address _market, address[] memory _collTokens, bool[] memory _isColl, address[] memory _borrowTokens, uint256[] memory _flModes, address _aaveMigrationReceiverAddr ) public { address lendingPool = ILendingPoolAddressesProviderV2(_market).getLendingPool(); address userProxy = address(this); // called by DSProxy, so it can be set like this (address[] memory assets, uint256[] memory amounts, uint256[] memory modes) = getUserBorrows(userProxy, _borrowTokens); FlMigrationData memory flData = FlMigrationData({ market: _market, collTokens: _collTokens, modes: modes, isColl: _isColl }); bytes memory data = abi.encode(flData); // give permission to receiver and execute tx givePermission(_aaveMigrationReceiverAddr); ILendingPoolV2(lendingPool).flashLoan( _aaveMigrationReceiverAddr, assets, amounts, _flModes, address(this), data, AAVE_REFERRAL_CODE ); removePermission(_aaveMigrationReceiverAddr); unsubAutomationInNeeded(userProxy); logger.Log( address(this), msg.sender, "AaveMigration", abi.encode(_collTokens, _borrowTokens) ); } function unsubAutomationInNeeded(address _userProxy) internal { AaveSubscriptions aaveSubV1 = AaveSubscriptions(AAVE_V1_SUBSCRIPTION_ADDR); AaveSubscriptionsV2 aaveSubV2 = AaveSubscriptionsV2(AAVE_V2_SUBSCRIPTION_ADDR); if (aaveSubV1.isSubscribed(_userProxy)) { AaveSubscriptions.AaveHolder memory holder = aaveSubV1.getHolder(_userProxy); // unsub and remove old permission aaveSubV1.unsubscribe(); removePermission(AAVE_V1_MONITOR_PROXY); // sub and add permission givePermission(AAVE_V2_MONITOR_PROXY); aaveSubV2.subscribe( holder.minRatio, holder.maxRatio, holder.optimalRatioBoost, holder.optimalRatioRepay, holder.boostEnabled ); } } function getUserBorrows(address _user, address[] memory _borrowTokens) public view returns ( address[] memory borrowAddr, uint256[] memory borrowAmounts, uint256[] memory borrowRateModes ) { address lendingPoolAddress = ILendingPoolAddressesProvider(AAVE_V1_LENDING_POOL_ADDRESSES).getLendingPool(); borrowAddr = new address[](_borrowTokens.length); borrowAmounts = new uint256[](_borrowTokens.length); borrowRateModes = new uint256[](_borrowTokens.length); for (uint256 i = 0; i < _borrowTokens.length; i++) { address reserve = _borrowTokens[i]; (, uint256 borrowBalance, , uint256 borrowRateMode, , , uint256 originationFee, , , ) = ILendingPool(lendingPoolAddress).getUserReserveData(reserve, _user); if (reserve == ETH_ADDR) { reserve = WETH_ADDRESS; } borrowAddr[i] = reserve; borrowAmounts[i] = borrowBalance + originationFee; borrowRateModes[i] = borrowRateMode; } } } contract AaveMigrationReceiver is AdminAuth { using SafeERC20 for ERC20; address public AAVE_MIGRATION_ADDR = 0x34e5B3c9109c699D38B111912F068D9F141b5187; address public constant AAVE_V2_LENDING_POOL = 0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9; function executeOperation( address[] calldata borrowAssets, uint256[] calldata amounts, uint256[] calldata fees, address initiator, bytes calldata params ) public returns (bool) { // send loan tokens to proxy for (uint256 i = 0; i < borrowAssets.length; i++) { ERC20(borrowAssets[i]).safeTransfer(initiator, amounts[i]); } (AaveMigrationTaker.FlMigrationData memory flData) = abi.decode(params, (AaveMigrationTaker.FlMigrationData)); AaveMigration.MigrateLoanData memory migrateLoanData = AaveMigration.MigrateLoanData({ market: flData.market, collAssets: flData.collTokens, isColl: flData.isColl, borrowAssets: borrowAssets, borrowAmounts: amounts, fees: fees, modes: flData.modes }); // call DsProxy DSProxy(payable(initiator)).execute{value: address(this).balance}( AAVE_MIGRATION_ADDR, abi.encodeWithSignature( "migrateLoan((address,address[],bool[],address[],uint256[],uint256[],uint256[]))", migrateLoanData ) ); // returnFL(borrowAssets, amounts, fees); return true; } // function returnFL( // address[] memory _borrowAssets, // uint256[] memory _amounts, // uint256[] memory _fees // ) internal { // for (uint256 i = 0; i < _borrowAssets.length; i++) { // ERC20(_borrowAssets[i]).safeApprove(AAVE_V2_LENDING_POOL, (_amounts[i] + _fees[i])); // } // } function setAaveMigrationAddr(address _aaveMigrationAddr) public onlyOwner { AAVE_MIGRATION_ADDR = _aaveMigrationAddr; } /// @dev Allow contract to receive eth receive() external payable {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"AAVE_MIGRATION_ADDR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AAVE_V2_LENDING_POOL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"borrowAssets","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"fees","type":"uint256[]"},{"internalType":"address","name":"initiator","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"executeOperation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"kill","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_aaveMigrationAddr","type":"address"}],"name":"setAaveMigrationAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdminByAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdminByOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwnerByAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawStuckFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6080604052600280546001600160a01b0319167334e5b3c9109c699d38b111912f068d9f141b518717905534801561003657600080fd5b50600080546001600160a01b03199081163317909155600180549091167325efa336886c74ea8e282ac466bdcd0199f85bb91790556110058061007a6000396000f3fe6080604052600436106100a05760003560e01c8063920f5c8411610064578063920f5c8414610143578063a7304bf714610170578063ab57a4ee14610190578063b09e26b8146101a5578063deca5f88146101c5578063f851a440146101e5576100a7565b80631e48907b146100ac5780633a128322146100ce57806341c0e1b5146100ee57806366658d44146101035780638da5cb5b1461012e576100a7565b366100a757005b600080fd5b3480156100b857600080fd5b506100cc6100c7366004610a71565b6101fa565b005b3480156100da57600080fd5b506100cc6100e9366004610a93565b610233565b3480156100fa57600080fd5b506100cc6102cc565b34801561010f57600080fd5b506101186102f1565b6040516101259190610d8d565b60405180910390f35b34801561013a57600080fd5b50610118610309565b34801561014f57600080fd5b5061016361015e366004610abd565b610318565b6040516101259190610dde565b34801561017c57600080fd5b506100cc61018b366004610a71565b610555565b34801561019c57600080fd5b5061011861058e565b3480156101b157600080fd5b506100cc6101c0366004610a71565b61059d565b3480156101d157600080fd5b506100cc6101e0366004610a71565b6105d6565b3480156101f157600080fd5b50610118610603565b6001546001600160a01b0316331461021157600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331461024a57600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b03831614156102ae57600080546040516001600160a01b039091169183156108fc02918491818181858888f193505050501580156102a8573d6000803e3d6000fd5b506102c8565b6000546102c8906001600160a01b03848116911683610612565b5050565b6000546001600160a01b031633146102e357600080fd5b6000546001600160a01b0316ff5b737d2768de32b0b80b7a3454c06bdac94a69ddc7a981565b6000546001600160a01b031681565b6000805b898110156103745761036c858a8a8481811061033457fe5b905060200201358d8d8581811061034757fe5b905060200201602081019061035c9190610a71565b6001600160a01b03169190610612565b60010161031c565b5061037d610819565b61038983850185610bd2565b905061039361084a565b6040518060e0016040528083600001516001600160a01b0316815260200183602001518152602001836060015181526020018d8d808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208d810282810182019093528d82529283019290918e918e9182918501908490808284376000920191909152505050908252506040805160208b810282810182019093528b82529283019290918c918c91829185019084908082843760009201919091525050509082525060408085015160209092019190915260025490519192506001600160a01b0380891692631cff79cd92479216906104a6908690602401610e7d565b60408051601f198184030181529181526020820180516001600160e01b0316639ec6bf1d60e01b1790525160e085901b6001600160e01b03191681526104f0929190600401610da1565b6020604051808303818588803b15801561050957600080fd5b505af115801561051d573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906105429190610bba565b5060019c9b505050505050505050505050565b6001546001600160a01b0316331461056c57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b6000546001600160a01b031633146105b457600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146105ed57600080fd5b6001546001600160a01b03161561056c57600080fd5b6001546001600160a01b031681565b6106688363a9059cbb60e01b8484604051602401610631929190610dc5565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261066d565b505050565b60606106c2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166107059092919063ffffffff16565b80519091501561066857808060200190518101906106e09190610b9e565b6106685760405162461bcd60e51b81526004016106fc90610e33565b60405180910390fd5b6060610714848460008561071c565b949350505050565b6060610727856107e0565b6107435760405162461bcd60e51b81526004016106fc90610dfc565b60006060866001600160a01b031685876040516107609190610d71565b60006040518083038185875af1925050503d806000811461079d576040519150601f19603f3d011682016040523d82523d6000602084013e6107a2565b606091505b509150915081156107b65791506107149050565b8051156107c65780518082602001fd5b8360405162461bcd60e51b81526004016106fc9190610de9565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610714575050151592915050565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001606081525090565b6040518060e0016040528060006001600160a01b031681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b80356001600160a01b03811681146108a757600080fd5b92915050565b60008083601f8401126108be578182fd5b50813567ffffffffffffffff8111156108d5578182fd5b60208301915083602080830285010111156108ef57600080fd5b9250929050565b600082601f830112610906578081fd5b813561091961091482610f6e565b610f47565b81815291506020808301908481018184028601820187101561093a57600080fd5b60005b848110156109615761094f8883610890565b8452928201929082019060010161093d565b505050505092915050565b600082601f83011261097c578081fd5b813561098a61091482610f6e565b8181529150602080830190848101818402860182018710156109ab57600080fd5b60005b848110156109615781356109c181610fbe565b845292820192908201906001016109ae565b600082601f8301126109e3578081fd5b81356109f161091482610f6e565b818152915060208083019084810181840286018201871015610a1257600080fd5b60005b8481101561096157813584529282019290820190600101610a15565b60008083601f840112610a42578182fd5b50813567ffffffffffffffff811115610a59578182fd5b6020830191508360208285010111156108ef57600080fd5b600060208284031215610a82578081fd5b610a8c8383610890565b9392505050565b60008060408385031215610aa5578081fd5b610aaf8484610890565b946020939093013593505050565b600080600080600080600080600060a08a8c031215610ada578485fd5b893567ffffffffffffffff80821115610af1578687fd5b610afd8d838e016108ad565b909b50995060208c0135915080821115610b15578687fd5b610b218d838e016108ad565b909950975060408c0135915080821115610b39578687fd5b610b458d838e016108ad565b909750955060608c013591506001600160a01b0382168214610b65578485fd5b90935060808b01359080821115610b7a578384fd5b50610b878c828d01610a31565b915080935050809150509295985092959850929598565b600060208284031215610baf578081fd5b8151610a8c81610fbe565b600060208284031215610bcb578081fd5b5051919050565b600060208284031215610be3578081fd5b813567ffffffffffffffff80821115610bfa578283fd5b9083019060808286031215610c0d578283fd5b610c176080610f47565b610c218684610890565b8152602083013582811115610c34578485fd5b610c40878286016108f6565b602083015250604083013582811115610c57578485fd5b610c63878286016109d3565b604083015250606083013582811115610c7a578485fd5b610c868782860161096c565b60608301525095945050505050565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015610cda5781516001600160a01b031687529582019590820190600101610cb5565b509495945050505050565b6000815180845260208085019450808401835b83811015610cda578151151587529582019590820190600101610cf8565b6000815180845260208085019450808401835b83811015610cda57815187529582019590820190600101610d29565b60008151808452610d5d816020860160208601610f8e565b601f01601f19169290920160200192915050565b60008251610d83818460208701610f8e565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020820181905260009061071490830184610d45565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b600060208252610a8c6020830184610d45565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b600060208252610e91602083018451610c95565b602083015160e06040840152610eab610100840182610ca2565b90506040840151601f1980858403016060860152610ec98383610ce5565b92506060860151915080858403016080860152610ee68383610ca2565b925060808601519150808584030160a0860152610f038383610d16565b925060a08601519150808584030160c0860152610f208383610d16565b925060c08601519150808584030160e086015250610f3e8282610d16565b95945050505050565b60405181810167ffffffffffffffff81118282101715610f6657600080fd5b604052919050565b600067ffffffffffffffff821115610f84578081fd5b5060209081020190565b60005b83811015610fa9578181015183820152602001610f91565b83811115610fb8576000848401525b50505050565b8015158114610fcc57600080fd5b5056fea26469706673582212200afe145096568db96cad270aaa3a369e4aed2389caa7884c3f1cc33dca4cff0764736f6c634300060c0033
Deployed Bytecode
0x6080604052600436106100a05760003560e01c8063920f5c8411610064578063920f5c8414610143578063a7304bf714610170578063ab57a4ee14610190578063b09e26b8146101a5578063deca5f88146101c5578063f851a440146101e5576100a7565b80631e48907b146100ac5780633a128322146100ce57806341c0e1b5146100ee57806366658d44146101035780638da5cb5b1461012e576100a7565b366100a757005b600080fd5b3480156100b857600080fd5b506100cc6100c7366004610a71565b6101fa565b005b3480156100da57600080fd5b506100cc6100e9366004610a93565b610233565b3480156100fa57600080fd5b506100cc6102cc565b34801561010f57600080fd5b506101186102f1565b6040516101259190610d8d565b60405180910390f35b34801561013a57600080fd5b50610118610309565b34801561014f57600080fd5b5061016361015e366004610abd565b610318565b6040516101259190610dde565b34801561017c57600080fd5b506100cc61018b366004610a71565b610555565b34801561019c57600080fd5b5061011861058e565b3480156101b157600080fd5b506100cc6101c0366004610a71565b61059d565b3480156101d157600080fd5b506100cc6101e0366004610a71565b6105d6565b3480156101f157600080fd5b50610118610603565b6001546001600160a01b0316331461021157600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331461024a57600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b03831614156102ae57600080546040516001600160a01b039091169183156108fc02918491818181858888f193505050501580156102a8573d6000803e3d6000fd5b506102c8565b6000546102c8906001600160a01b03848116911683610612565b5050565b6000546001600160a01b031633146102e357600080fd5b6000546001600160a01b0316ff5b737d2768de32b0b80b7a3454c06bdac94a69ddc7a981565b6000546001600160a01b031681565b6000805b898110156103745761036c858a8a8481811061033457fe5b905060200201358d8d8581811061034757fe5b905060200201602081019061035c9190610a71565b6001600160a01b03169190610612565b60010161031c565b5061037d610819565b61038983850185610bd2565b905061039361084a565b6040518060e0016040528083600001516001600160a01b0316815260200183602001518152602001836060015181526020018d8d808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208d810282810182019093528d82529283019290918e918e9182918501908490808284376000920191909152505050908252506040805160208b810282810182019093528b82529283019290918c918c91829185019084908082843760009201919091525050509082525060408085015160209092019190915260025490519192506001600160a01b0380891692631cff79cd92479216906104a6908690602401610e7d565b60408051601f198184030181529181526020820180516001600160e01b0316639ec6bf1d60e01b1790525160e085901b6001600160e01b03191681526104f0929190600401610da1565b6020604051808303818588803b15801561050957600080fd5b505af115801561051d573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906105429190610bba565b5060019c9b505050505050505050505050565b6001546001600160a01b0316331461056c57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b6000546001600160a01b031633146105b457600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146105ed57600080fd5b6001546001600160a01b03161561056c57600080fd5b6001546001600160a01b031681565b6106688363a9059cbb60e01b8484604051602401610631929190610dc5565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261066d565b505050565b60606106c2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166107059092919063ffffffff16565b80519091501561066857808060200190518101906106e09190610b9e565b6106685760405162461bcd60e51b81526004016106fc90610e33565b60405180910390fd5b6060610714848460008561071c565b949350505050565b6060610727856107e0565b6107435760405162461bcd60e51b81526004016106fc90610dfc565b60006060866001600160a01b031685876040516107609190610d71565b60006040518083038185875af1925050503d806000811461079d576040519150601f19603f3d011682016040523d82523d6000602084013e6107a2565b606091505b509150915081156107b65791506107149050565b8051156107c65780518082602001fd5b8360405162461bcd60e51b81526004016106fc9190610de9565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610714575050151592915050565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001606081525090565b6040518060e0016040528060006001600160a01b031681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b80356001600160a01b03811681146108a757600080fd5b92915050565b60008083601f8401126108be578182fd5b50813567ffffffffffffffff8111156108d5578182fd5b60208301915083602080830285010111156108ef57600080fd5b9250929050565b600082601f830112610906578081fd5b813561091961091482610f6e565b610f47565b81815291506020808301908481018184028601820187101561093a57600080fd5b60005b848110156109615761094f8883610890565b8452928201929082019060010161093d565b505050505092915050565b600082601f83011261097c578081fd5b813561098a61091482610f6e565b8181529150602080830190848101818402860182018710156109ab57600080fd5b60005b848110156109615781356109c181610fbe565b845292820192908201906001016109ae565b600082601f8301126109e3578081fd5b81356109f161091482610f6e565b818152915060208083019084810181840286018201871015610a1257600080fd5b60005b8481101561096157813584529282019290820190600101610a15565b60008083601f840112610a42578182fd5b50813567ffffffffffffffff811115610a59578182fd5b6020830191508360208285010111156108ef57600080fd5b600060208284031215610a82578081fd5b610a8c8383610890565b9392505050565b60008060408385031215610aa5578081fd5b610aaf8484610890565b946020939093013593505050565b600080600080600080600080600060a08a8c031215610ada578485fd5b893567ffffffffffffffff80821115610af1578687fd5b610afd8d838e016108ad565b909b50995060208c0135915080821115610b15578687fd5b610b218d838e016108ad565b909950975060408c0135915080821115610b39578687fd5b610b458d838e016108ad565b909750955060608c013591506001600160a01b0382168214610b65578485fd5b90935060808b01359080821115610b7a578384fd5b50610b878c828d01610a31565b915080935050809150509295985092959850929598565b600060208284031215610baf578081fd5b8151610a8c81610fbe565b600060208284031215610bcb578081fd5b5051919050565b600060208284031215610be3578081fd5b813567ffffffffffffffff80821115610bfa578283fd5b9083019060808286031215610c0d578283fd5b610c176080610f47565b610c218684610890565b8152602083013582811115610c34578485fd5b610c40878286016108f6565b602083015250604083013582811115610c57578485fd5b610c63878286016109d3565b604083015250606083013582811115610c7a578485fd5b610c868782860161096c565b60608301525095945050505050565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015610cda5781516001600160a01b031687529582019590820190600101610cb5565b509495945050505050565b6000815180845260208085019450808401835b83811015610cda578151151587529582019590820190600101610cf8565b6000815180845260208085019450808401835b83811015610cda57815187529582019590820190600101610d29565b60008151808452610d5d816020860160208601610f8e565b601f01601f19169290920160200192915050565b60008251610d83818460208701610f8e565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020820181905260009061071490830184610d45565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b600060208252610a8c6020830184610d45565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b600060208252610e91602083018451610c95565b602083015160e06040840152610eab610100840182610ca2565b90506040840151601f1980858403016060860152610ec98383610ce5565b92506060860151915080858403016080860152610ee68383610ca2565b925060808601519150808584030160a0860152610f038383610d16565b925060a08601519150808584030160c0860152610f208383610d16565b925060c08601519150808584030160e086015250610f3e8282610d16565b95945050505050565b60405181810167ffffffffffffffff81118282101715610f6657600080fd5b604052919050565b600067ffffffffffffffff821115610f84578081fd5b5060209081020190565b60005b83811015610fa9578181015183820152602001610f91565b83811115610fb8576000848401525b50505050565b8015158114610fcc57600080fd5b5056fea26469706673582212200afe145096568db96cad270aaa3a369e4aed2389caa7884c3f1cc33dca4cff0764736f6c634300060c0033
Deployed Bytecode Sourcemap
69194:2231:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11829:122;;;;;;;;;;-1:-1:-1;11829:122:0;;;;;:::i;:::-;;:::i;:::-;;12124:285;;;;;;;;;;-1:-1:-1;12124:285:0;;;;;:::i;:::-;;:::i;11997:80::-;;;;;;;;;;;;;:::i;69365:89::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10787:20;;;;;;;;;;;;;:::i;69463:1378::-;;;;;;;;;;-1:-1:-1;69463:1378:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;11608:122::-;;;;;;;;;;-1:-1:-1;11608:122:0;;;;;:::i;:::-;;:::i;69279:79::-;;;;;;;;;;;;;:::i;71207:134::-;;;;;;;;;;-1:-1:-1;71207:134:0;;;;;:::i;:::-;;:::i;11325:161::-;;;;;;;;;;-1:-1:-1;11325:161:0;;;;;:::i;:::-;;:::i;10814:20::-;;;;;;;;;;;;;:::i;11829:122::-;11910:5;;-1:-1:-1;;;;;11910:5:0;11896:10;:19;11888:28;;;;;;11929:5;:14;;-1:-1:-1;;;;;;11929:14:0;-1:-1:-1;;;;;11929:14:0;;;;;;;;;;11829:122::o;12124:285::-;10883:5;;-1:-1:-1;;;;;10883:5:0;10892:10;10883:19;10875:28;;;;;;12224:42:::1;-1:-1:-1::0;;;;;12214:52:0;::::1;;12210:192;;;12291:5;::::0;;12283:32:::1;::::0;-1:-1:-1;;;;;12291:5:0;;::::1;::::0;12283:32;::::1;;;::::0;12307:7;;12283:32;12291:5;12283:32;12307:7;12291:5;12283:32;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;12210:192;;;12375:5;::::0;12348:42:::1;::::0;-1:-1:-1;;;;;12348:26:0;;::::1;::::0;12375:5:::1;12382:7:::0;12348:26:::1;:42::i;:::-;12124:285:::0;;:::o;11997:80::-;10883:5;;-1:-1:-1;;;;;10883:5:0;10892:10;10883:19;10875:28;;;;;;12062:5:::1;::::0;-1:-1:-1;;;;;12062:5:0::1;12041:28;69365:89:::0;69412:42;69365:89;:::o;10787:20::-;;;-1:-1:-1;;;;;10787:20:0;;:::o;69463:1378::-;69685:4;;69742:135;69762:23;;;69742:135;;;69807:58;69843:9;69854:7;;69862:1;69854:10;;;;;;;;;;;;;69813:12;;69826:1;69813:15;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;69807:35:0;;:58;:35;:58::i;:::-;69787:3;;69742:135;;;;69890:48;;:::i;:::-;69955:56;;;;69966:6;69955:56;:::i;:::-;69889:122;;70024:52;;:::i;:::-;70092:327;;;;;;;;70149:6;:13;;;-1:-1:-1;;;;;70092:327:0;;;;;70193:6;:17;;;70092:327;;;;70237:6;:13;;;70092:327;;;;70283:12;;70092:327;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;70092:327:0;;;-1:-1:-1;70092:327:0;;;;;;;;;;;;;;;;;;;;;;;;70329:7;;;;;;70092:327;;;70329:7;;70092:327;70329:7;70092:327;;;;;;;;;-1:-1:-1;;;70092:327:0;;;-1:-1:-1;70092:327:0;;;;;;;;;;;;;;;;;;;;;;;;70361:4;;;;;;70092:327;;;70361:4;;70092:327;70361:4;70092:327;;;;;;;;;-1:-1:-1;;;70092:327:0;;;-1:-1:-1;70391:12:0;;;;;70092:327;;;;;;;;70539:19;;70573:172;;70024:395;;-1:-1:-1;;;;;;70459:35:0;;;;;;70502:21;;70539:19;;70573:172;;70024:395;;70573:172;;;:::i;:::-;;;;-1:-1:-1;;70573:172:0;;;;;;;;;;;;;;-1:-1:-1;;;;;70573:172:0;-1:-1:-1;;;70573:172:0;;;70459:297;;;;;-1:-1:-1;;;;;;70459:297:0;;;;;;70573:172;70459:297;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;70829:4:0;;69463:1378;-1:-1:-1;;;;;;;;;;;;69463:1378:0:o;11608:122::-;11689:5;;-1:-1:-1;;;;;11689:5:0;11675:10;:19;11667:28;;;;;;11708:5;:14;;-1:-1:-1;;;;;;11708:14:0;-1:-1:-1;;;;;11708:14:0;;;;;;;;;;11608:122::o;69279:79::-;;;-1:-1:-1;;;;;69279:79:0;;:::o;71207:134::-;10883:5;;-1:-1:-1;;;;;10883:5:0;10892:10;10883:19;10875:28;;;;;;71293:19:::1;:40:::0;;-1:-1:-1;;;;;;71293:40:0::1;-1:-1:-1::0;;;;;71293:40:0;;;::::1;::::0;;;::::1;::::0;;71207:134::o;11325:161::-;11406:5;;-1:-1:-1;;;;;11406:5:0;11392:10;:19;11384:28;;;;;;11431:5;;-1:-1:-1;;;;;11431:5:0;:19;11423:28;;;;;10814:20;;;-1:-1:-1;;;;;10814:20:0;;:::o;5647:176::-;5729:86;5749:5;5779:23;;;5804:2;5808:5;5756:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;5756:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;5756:58:0;-1:-1:-1;;;;;;5756:58:0;;;;;;;;;;5729:19;:86::i;:::-;5647:176;;;:::o;7116:419::-;7198:23;7224:69;7252:4;7224:69;;;;;;;;;;;;;;;;;7232:5;-1:-1:-1;;;;;7224:27:0;;;:69;;;;;:::i;:::-;7308:17;;7198:95;;-1:-1:-1;7308:21:0;7304:224;;7450:10;7439:30;;;;;;;;;;;;:::i;:::-;7431:85;;;;-1:-1:-1;;;7431:85:0;;;;;;;:::i;:::-;;;;;;;;2036:196;2139:12;2171:53;2194:6;2202:4;2208:1;2211:12;2171:22;:53::i;:::-;2164:60;2036:196;-1:-1:-1;;;;2036:196:0:o;2798:979::-;2928:12;2961:18;2972:6;2961:10;:18::i;:::-;2953:60;;;;-1:-1:-1;;;2953:60:0;;;;;;;:::i;:::-;3087:12;3101:23;3128:6;-1:-1:-1;;;;;3128:11:0;3148:8;3159:4;3128:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3086:78;;;;3179:7;3175:595;;;3210:10;-1:-1:-1;3203:17:0;;-1:-1:-1;3203:17:0;3175:595;3324:17;;:21;3320:439;;3587:10;3581:17;3648:15;3635:10;3631:2;3627:19;3620:44;3535:148;3730:12;3723:20;;-1:-1:-1;;;3723:20:0;;;;;;;;:::i;823:619::-;883:4;1351:20;;1194:66;1391:23;;;;;;:42;;-1:-1:-1;;1418:15:0;;;1383:51;-1:-1:-1;;823:619:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130::-;72:20;;-1:-1;;;;;22275:54;;22861:35;;22851:2;;22910:1;;22900:12;22851:2;57:78;;;;:::o;160:352::-;;;290:3;283:4;275:6;271:17;267:27;257:2;;-1:-1;;298:12;257:2;-1:-1;328:20;;368:18;357:30;;354:2;;;-1:-1;;390:12;354:2;434:4;426:6;422:17;410:29;;485:3;434:4;;469:6;465:17;426:6;451:32;;448:41;445:2;;;502:1;;492:12;445:2;250:262;;;;;:::o;538:707::-;;655:3;648:4;640:6;636:17;632:27;622:2;;-1:-1;;663:12;622:2;710:6;697:20;732:80;747:64;804:6;747:64;:::i;:::-;732:80;:::i;:::-;840:21;;;723:89;-1:-1;884:4;897:14;;;;872:17;;;986;;;977:27;;;;974:36;-1:-1;971:2;;;1023:1;;1013:12;971:2;1048:1;1033:206;1058:6;1055:1;1052:13;1033:206;;;1138:37;1171:3;1159:10;1138:37;:::i;:::-;1126:50;;1190:14;;;;1218;;;;1080:1;1073:9;1033:206;;;1037:14;;;;;615:630;;;;:::o;1268:698::-;;1382:3;1375:4;1367:6;1363:17;1359:27;1349:2;;-1:-1;;1390:12;1349:2;1437:6;1424:20;1459:77;1474:61;1528:6;1474:61;:::i;1459:77::-;1564:21;;;1450:86;-1:-1;1608:4;1621:14;;;;1596:17;;;1710;;;1701:27;;;;1698:36;-1:-1;1695:2;;;1747:1;;1737:12;1695:2;1772:1;1757:203;1782:6;1779:1;1776:13;1757:203;;;3162:6;3149:20;3174:30;3198:5;3174:30;:::i;:::-;1850:47;;1911:14;;;;1939;;;;1804:1;1797:9;1757:203;;2370:707;;2487:3;2480:4;2472:6;2468:17;2464:27;2454:2;;-1:-1;;2495:12;2454:2;2542:6;2529:20;2564:80;2579:64;2636:6;2579:64;:::i;2564:80::-;2672:21;;;2555:89;-1:-1;2716:4;2729:14;;;;2704:17;;;2818;;;2809:27;;;;2806:36;-1:-1;2803:2;;;2855:1;;2845:12;2803:2;2880:1;2865:206;2890:6;2887:1;2884:13;2865:206;;;5076:20;;2958:50;;3022:14;;;;3050;;;;2912:1;2905:9;2865:206;;3506:336;;;3620:3;3613:4;3605:6;3601:17;3597:27;3587:2;;-1:-1;;3628:12;3587:2;-1:-1;3658:20;;3698:18;3687:30;;3684:2;;;-1:-1;;3720:12;3684:2;3764:4;3756:6;3752:17;3740:29;;3815:3;3764:4;3795:17;3756:6;3781:32;;3778:41;3775:2;;;3832:1;;3822:12;5146:241;;5250:2;5238:9;5229:7;5225:23;5221:32;5218:2;;;-1:-1;;5256:12;5218:2;5318:53;5363:7;5339:22;5318:53;:::i;:::-;5308:63;5212:175;-1:-1;;;5212:175::o;5394:366::-;;;5515:2;5503:9;5494:7;5490:23;5486:32;5483:2;;;-1:-1;;5521:12;5483:2;5583:53;5628:7;5604:22;5583:53;:::i;:::-;5573:63;5673:2;5712:22;;;;5076:20;;-1:-1;;;5477:283::o;5767:1335::-;;;;;;;;;;6063:3;6051:9;6042:7;6038:23;6034:33;6031:2;;;-1:-1;;6070:12;6031:2;6128:17;6115:31;6166:18;;6158:6;6155:30;6152:2;;;-1:-1;;6188:12;6152:2;6226:80;6298:7;6289:6;6278:9;6274:22;6226:80;:::i;:::-;6208:98;;-1:-1;6208:98;-1:-1;6371:2;6356:18;;6343:32;;-1:-1;6384:30;;;6381:2;;;-1:-1;;6417:12;6381:2;6455:80;6527:7;6518:6;6507:9;6503:22;6455:80;:::i;:::-;6437:98;;-1:-1;6437:98;-1:-1;6600:2;6585:18;;6572:32;;-1:-1;6613:30;;;6610:2;;;-1:-1;;6646:12;6610:2;6684:80;6756:7;6747:6;6736:9;6732:22;6684:80;:::i;:::-;6666:98;;-1:-1;6666:98;-1:-1;6801:2;6840:22;;72:20;;-1:-1;;;;;;22275:54;;22861:35;;22851:2;;-1:-1;;22900:12;22851:2;6809:63;;-1:-1;6937:3;6922:19;;6909:33;;6951:30;;;6948:2;;;-1:-1;;6984:12;6948:2;;7022:64;7078:7;7069:6;7058:9;7054:22;7022:64;:::i;:::-;7004:82;;;;;;;;;;6025:1077;;;;;;;;;;;:::o;7109:257::-;;7221:2;7209:9;7200:7;7196:23;7192:32;7189:2;;;-1:-1;;7227:12;7189:2;3297:6;3291:13;3309:30;3333:5;3309:30;:::i;7373:263::-;;7488:2;7476:9;7467:7;7463:23;7459:32;7456:2;;;-1:-1;;7494:12;7456:2;-1:-1;3429:13;;7450:186;-1:-1;7450:186::o;7643:393::-;;7780:2;7768:9;7759:7;7755:23;7751:32;7748:2;;;-1:-1;;7786:12;7748:2;7844:17;7831:31;7882:18;;7874:6;7871:30;7868:2;;;-1:-1;;7904:12;7868:2;7988:22;;;;4020:4;3999:19;;;3995:30;3992:2;;;-1:-1;;4028:12;3992:2;4056:20;4020:4;4056:20;:::i;:::-;4160:49;4205:3;4181:22;4160:49;:::i;:::-;4142:16;4135:75;7780:2;4294:9;4290:18;4277:32;7882:18;4321:6;4318:30;4315:2;;;-1:-1;;4351:12;4315:2;4396:74;4466:3;4457:6;4446:9;4442:22;4396:74;:::i;:::-;7780:2;4382:5;4378:16;4371:100;;4561:2;4550:9;4546:18;4533:32;7882:18;4577:6;4574:30;4571:2;;;-1:-1;;4607:12;4571:2;4652:74;4722:3;4713:6;4702:9;4698:22;4652:74;:::i;:::-;4561:2;4638:5;4634:16;4627:100;;4818:2;4807:9;4803:18;4790:32;7882:18;4834:6;4831:30;4828:2;;;-1:-1;;4864:12;4828:2;4909:71;4976:3;4967:6;4956:9;4952:22;4909:71;:::i;:::-;4818:2;4891:16;;4884:97;-1:-1;4895:5;7742:294;-1:-1;;;;;7742:294::o;8577:103::-;-1:-1;;;;;22275:54;8638:37;;8632:48::o;8838:670::-;;9021:5;19995:12;21041:6;21036:3;21029:19;21078:4;;21073:3;21069:14;9033:83;;21078:4;9187:5;19536:14;-1:-1;9226:260;9251:6;9248:1;9245:13;9226:260;;;9312:13;;-1:-1;;;;;22275:54;8638:37;;8197:14;;;;20667;;;;22286:42;9266:9;9226:260;;;-1:-1;9492:10;;8952:556;-1:-1;;;;;8952:556::o;9541:646::-;;9715:5;19995:12;21041:6;21036:3;21029:19;21078:4;;21073:3;21069:14;9727:80;;21078:4;9875:5;19536:14;-1:-1;9914:251;9939:6;9936:1;9933:13;9914:251;;;10000:13;;22108;22101:21;10959:34;;8367:14;;;;20667;;;;9961:1;9954:9;9914:251;;10226:670;;10409:5;19995:12;21041:6;21036:3;21029:19;21078:4;;21073:3;21069:14;10421:83;;21078:4;10575:5;19536:14;-1:-1;10614:260;10639:6;10636:1;10633:13;10614:260;;;10700:13;;14999:37;;8549:14;;;;20667;;;;10661:1;10654:9;10614:260;;11116:343;;11258:5;19995:12;21041:6;21036:3;21029:19;11351:52;11396:6;21078:4;21073:3;21069:14;21078:4;11377:5;11373:16;11351:52;:::i;:::-;22781:7;22765:14;-1:-1;;22761:28;11415:39;;;;21078:4;11415:39;;11206:253;-1:-1;;11206:253::o;15168:271::-;;11626:5;19995:12;11737:52;11782:6;11777:3;11770:4;11763:5;11759:16;11737:52;:::i;:::-;11801:16;;;;;15302:137;-1:-1;;15302:137::o;15446:222::-;-1:-1;;;;;22275:54;;;;8638:37;;15573:2;15558:18;;15544:124::o;15675:417::-;-1:-1;;;;;22275:54;;8638:37;;15848:2;15966;15951:18;;15944:48;;;15675:417;;16006:76;;15833:18;;16068:6;16006:76;:::i;16099:333::-;-1:-1;;;;;22275:54;;;;8638:37;;16418:2;16403:18;;14999:37;16254:2;16239:18;;16225:207::o;16439:210::-;22108:13;;22101:21;10959:34;;16560:2;16545:18;;16531:118::o;16656:310::-;;16803:2;16824:17;16817:47;16878:78;16803:2;16792:9;16788:18;16942:6;16878:78;:::i;16973:416::-;17173:2;17187:47;;;12408:2;17158:18;;;21029:19;12444:31;21069:14;;;12424:52;12495:12;;;17144:245::o;17396:416::-;17596:2;17610:47;;;12746:2;17581:18;;;21029:19;12782:34;21069:14;;;12762:55;-1:-1;;;12837:12;;;12830:34;12883:12;;;17567:245::o;17819:402::-;;18012:2;18033:17;18026:47;13256:63;18012:2;18001:9;17997:18;13233:16;13227:23;13256:63;:::i;:::-;18012:2;13397:5;13393:16;13387:23;13159:4;13430:14;18001:9;13430:14;13423:38;13476:103;13150:14;18001:9;13150:14;13560:12;13476:103;:::i;:::-;13468:111;;13430:14;13659:5;13655:16;13649:23;22781:7;;13708:14;18001:9;13712:4;13708:14;;13692;18001:9;13692:14;13685:38;13738:97;13830:4;13816:12;13738:97;:::i;:::-;13730:105;;13692:14;13921:5;13917:16;13911:23;13891:43;;13708:14;18001:9;13974:4;13970:14;;13954;18001:9;13954:14;13947:38;14000:103;14098:4;14084:12;14000:103;:::i;:::-;13992:111;;13954:14;14190:5;14186:16;14180:23;14160:43;;13708:14;18001:9;14243:4;14239:14;;14223;18001:9;14223:14;14216:38;14269:103;14367:4;14353:12;14269:103;:::i;:::-;14261:111;;14223:14;14450:5;14446:16;14440:23;14420:43;;13708:14;18001:9;14503:4;14499:14;;14483;18001:9;14483:14;14476:38;14529:103;14627:4;14613:12;14529:103;:::i;:::-;14521:111;;14483:14;14711:5;14707:16;14701:23;14681:43;;13708:14;18001:9;14764:4;14760:14;;13159:4;18001:9;14744:14;14737:38;;14790:103;14888:4;14874:12;14790:103;:::i;:::-;18079:132;17983:238;-1:-1;;;;;17983:238::o;18228:256::-;18290:2;18284:9;18316:17;;;18391:18;18376:34;;18412:22;;;18373:62;18370:2;;;18448:1;;18438:12;18370:2;18290;18457:22;18268:216;;-1:-1;18268:216::o;18491:304::-;;18650:18;18642:6;18639:30;18636:2;;;-1:-1;;18672:12;18636:2;-1:-1;18717:4;18705:17;;;18770:15;;18573:222::o;22421:268::-;22486:1;22493:101;22507:6;22504:1;22501:13;22493:101;;;22574:11;;;22568:18;22555:11;;;22548:39;22529:2;22522:10;22493:101;;;22609:6;22606:1;22603:13;22600:2;;;22486:1;22665:6;22660:3;22656:16;22649:27;22600:2;;22470:219;;;:::o;22926:111::-;23007:5;22108:13;22101:21;22985:5;22982:32;22972:2;;23028:1;;23018:12;22972:2;22966:71;:::o
Swarm Source
ipfs://0afe145096568db96cad270aaa3a369e4aed2389caa7884c3f1cc33dca4cff07
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.