mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
242826ded6
Complete with unit tests (using a mock AugustusSwapper contract). Has similar functionality/tests as for existing Uniswap adapter. Fixed a couple bugs in tests for Uniswap adapters.
125 lines
4.1 KiB
Solidity
125 lines
4.1 KiB
Solidity
// SPDX-License-Identifier: agpl-3.0
|
|
pragma solidity 0.6.12;
|
|
pragma experimental ABIEncoderV2;
|
|
|
|
import {SafeMath} from '../dependencies/openzeppelin/contracts/SafeMath.sol';
|
|
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
|
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
|
import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
|
import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
|
|
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
|
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
|
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
|
import {IERC20WithPermit} from '../interfaces/IERC20WithPermit.sol';
|
|
import {FlashLoanReceiverBase} from '../flashloan/base/FlashLoanReceiverBase.sol';
|
|
|
|
/**
|
|
* @title BaseParaSwapAdapter
|
|
* @notice Utility functions for adapters using ParaSwap
|
|
* @author Jason Raymond Bell
|
|
*/
|
|
abstract contract BaseParaSwapAdapter is FlashLoanReceiverBase, Ownable {
|
|
using SafeMath for uint256;
|
|
using SafeERC20 for IERC20;
|
|
|
|
struct PermitSignature {
|
|
uint256 amount;
|
|
uint256 deadline;
|
|
uint8 v;
|
|
bytes32 r;
|
|
bytes32 s;
|
|
}
|
|
|
|
// Max slippage percent allowed
|
|
uint256 public constant MAX_SLIPPAGE_PERCENT = 3000; // 30%
|
|
|
|
IPriceOracleGetter public immutable ORACLE;
|
|
|
|
event Swapped(address indexed fromAsset, address indexed toAsset, uint256 fromAmount, uint256 receivedAmount);
|
|
|
|
constructor(
|
|
ILendingPoolAddressesProvider addressesProvider
|
|
) public FlashLoanReceiverBase(addressesProvider) {
|
|
ORACLE = IPriceOracleGetter(addressesProvider.getPriceOracle());
|
|
}
|
|
|
|
/**
|
|
* @dev Get the price of the asset from the oracle denominated in eth
|
|
* @param asset address
|
|
* @return eth price for the asset
|
|
*/
|
|
function _getPrice(address asset) internal view returns (uint256) {
|
|
return ORACLE.getAssetPrice(asset);
|
|
}
|
|
|
|
/**
|
|
* @dev Get the decimals of an asset
|
|
* @return number of decimals of the asset
|
|
*/
|
|
function _getDecimals(address asset) internal view returns (uint256) {
|
|
return IERC20Detailed(asset).decimals();
|
|
}
|
|
|
|
/**
|
|
* @dev Get the aToken associated to the asset
|
|
* @return address of the aToken
|
|
*/
|
|
function _getReserveData(address asset) internal view returns (DataTypes.ReserveData memory) {
|
|
return LENDING_POOL.getReserveData(asset);
|
|
}
|
|
|
|
/**
|
|
* @dev Pull the ATokens from the user
|
|
* @param reserve address of the asset
|
|
* @param reserveAToken address of the aToken of the reserve
|
|
* @param user address
|
|
* @param amount of tokens to be transferred to the contract
|
|
* @param permitSignature struct containing the permit signature
|
|
*/
|
|
function _pullAToken(
|
|
address reserve,
|
|
address reserveAToken,
|
|
address user,
|
|
uint256 amount,
|
|
PermitSignature memory permitSignature
|
|
) internal {
|
|
if (_usePermit(permitSignature)) {
|
|
IERC20WithPermit(reserveAToken).permit(
|
|
user,
|
|
address(this),
|
|
permitSignature.amount,
|
|
permitSignature.deadline,
|
|
permitSignature.v,
|
|
permitSignature.r,
|
|
permitSignature.s
|
|
);
|
|
}
|
|
|
|
// transfer from user to adapter
|
|
IERC20(reserveAToken).safeTransferFrom(user, address(this), amount);
|
|
|
|
// withdraw reserve
|
|
LENDING_POOL.withdraw(reserve, amount, address(this));
|
|
}
|
|
|
|
/**
|
|
* @dev Tells if the permit method should be called by inspecting if there is a valid signature.
|
|
* If signature params are set to 0, then permit won't be called.
|
|
* @param signature struct containing the permit signature
|
|
* @return whether or not permit should be called
|
|
*/
|
|
function _usePermit(PermitSignature memory signature) internal pure returns (bool) {
|
|
return
|
|
!(uint256(signature.deadline) == uint256(signature.v) && uint256(signature.deadline) == 0);
|
|
}
|
|
|
|
/**
|
|
* @dev Emergency rescue for token stucked on this contract, as failsafe mechanism
|
|
* - Funds should never remain in this contract more time than during transactions
|
|
* - Only callable by the owner
|
|
*/
|
|
function rescueTokens(IERC20 token) external onlyOwner {
|
|
token.transfer(owner(), token.balanceOf(address(this)));
|
|
}
|
|
}
|