mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Add swapAndDeposit method to use without flashloan
This commit is contained in:
parent
e5d37e1a8c
commit
16a28d6223
|
@ -60,4 +60,31 @@ contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Swaps an `amountToSwap` of an asset to another and deposits the funds on behalf of the user without using a flashloan.
|
||||
* This method can be used when the user has no debts.
|
||||
* The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset and
|
||||
* perform the swap.
|
||||
* @param assetToSwapFrom Address of the underlying asset to be swap from
|
||||
* @param assetToSwapTo Address of the underlying asset to be swap to and deposited
|
||||
* @param amountToSwap How much `assetToSwapFrom` needs to be swapped
|
||||
* @param user Address that will be pulling the swapped funds
|
||||
* @param slippage The max slippage percentage allowed for the swap
|
||||
*/
|
||||
function swapAndDeposit(
|
||||
address assetToSwapFrom,
|
||||
address assetToSwapTo,
|
||||
uint256 amountToSwap,
|
||||
address user,
|
||||
uint256 slippage
|
||||
) external {
|
||||
pullAToken(assetToSwapFrom, user, amountToSwap);
|
||||
|
||||
uint256 receivedAmount = swapExactTokensForTokens(assetToSwapFrom, assetToSwapTo, amountToSwap, slippage);
|
||||
|
||||
// Deposit new reserve
|
||||
IERC20(assetToSwapTo).approve(address(pool), receivedAmount);
|
||||
pool.deposit(assetToSwapTo, receivedAmount, user, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,36 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
|
|||
await evmRevert(evmSnapshotId);
|
||||
});
|
||||
|
||||
describe('BaseUniswapAdapter', () => {
|
||||
describe('getAmountOut', () => {
|
||||
it('should return the estimated amountOut for the asset swap', async () => {
|
||||
const {weth, dai, uniswapLiquiditySwapAdapter} = testEnv;
|
||||
const amountIn = parseEther('1');
|
||||
const amountOut = parseEther('2');
|
||||
|
||||
await mockUniswapRouter.setAmountOut(amountIn, weth.address, dai.address, amountOut);
|
||||
|
||||
expect(
|
||||
await uniswapLiquiditySwapAdapter.getAmountOut(amountIn, weth.address, dai.address)
|
||||
).to.be.eq(amountOut);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAmountIn', () => {
|
||||
it('should return the estimated required amountIn for the asset swap', async () => {
|
||||
const {weth, dai, uniswapLiquiditySwapAdapter} = testEnv;
|
||||
const amountIn = parseEther('1');
|
||||
const amountOut = parseEther('2');
|
||||
|
||||
await mockUniswapRouter.setAmountIn(amountOut, weth.address, dai.address, amountIn);
|
||||
|
||||
expect(
|
||||
await uniswapLiquiditySwapAdapter.getAmountIn(amountOut, weth.address, dai.address)
|
||||
).to.be.eq(amountIn);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('UniswapLiquiditySwapAdapter', () => {
|
||||
describe('constructor', () => {
|
||||
it('should deploy with correct parameters', async () => {
|
||||
|
@ -328,6 +358,72 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
|
|||
).to.be.revertedWith('INSUFFICIENT_OUTPUT_AMOUNT');
|
||||
});
|
||||
});
|
||||
|
||||
describe('swapAndDeposit', () => {
|
||||
beforeEach(async () => {
|
||||
const {users, weth, dai, pool, deployer} = testEnv;
|
||||
const userAddress = users[0].address;
|
||||
|
||||
// Provide liquidity
|
||||
await dai.mint(parseEther('20000'));
|
||||
await dai.approve(pool.address, parseEther('20000'));
|
||||
await pool.deposit(dai.address, parseEther('20000'), deployer.address, 0);
|
||||
|
||||
// Make a deposit for user
|
||||
await weth.mint(parseEther('100'));
|
||||
await weth.approve(pool.address, parseEther('100'));
|
||||
await pool.deposit(weth.address, parseEther('100'), userAddress, 0);
|
||||
});
|
||||
|
||||
it('should correctly swap tokens and deposit the out tokens in the pool', async () => {
|
||||
const {users, weth, oracle, dai, aDai, aEth, uniswapLiquiditySwapAdapter} = testEnv;
|
||||
const user = users[0].signer;
|
||||
const userAddress = users[0].address;
|
||||
|
||||
const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10');
|
||||
|
||||
const daiPrice = await oracle.getAssetPrice(dai.address);
|
||||
const expectedDaiAmount = await convertToCurrencyDecimals(
|
||||
dai.address,
|
||||
new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0)
|
||||
);
|
||||
|
||||
await mockUniswapRouter.setAmountToReturn(expectedDaiAmount);
|
||||
|
||||
// User will swap liquidity 10 aEth to aDai
|
||||
const liquidityToSwap = parseEther('10');
|
||||
await aEth.connect(user).approve(uniswapLiquiditySwapAdapter.address, liquidityToSwap);
|
||||
const userAEthBalanceBefore = await aEth.balanceOf(userAddress);
|
||||
|
||||
await expect(
|
||||
uniswapLiquiditySwapAdapter.swapAndDeposit(
|
||||
weth.address,
|
||||
dai.address,
|
||||
amountWETHtoSwap,
|
||||
userAddress,
|
||||
50
|
||||
)
|
||||
)
|
||||
.to.emit(uniswapLiquiditySwapAdapter, 'Swapped')
|
||||
.withArgs(weth.address, dai.address, amountWETHtoSwap.toString(), expectedDaiAmount);
|
||||
|
||||
const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address);
|
||||
const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address);
|
||||
const adapterDaiAllowance = await dai.allowance(
|
||||
uniswapLiquiditySwapAdapter.address,
|
||||
userAddress
|
||||
);
|
||||
const userADaiBalance = await aDai.balanceOf(userAddress);
|
||||
const userAEthBalance = await aEth.balanceOf(userAddress);
|
||||
|
||||
expect(adapterWethBalance).to.be.eq(Zero);
|
||||
expect(adapterDaiBalance).to.be.eq(Zero);
|
||||
expect(adapterDaiAllowance).to.be.eq(Zero);
|
||||
expect(userADaiBalance).to.be.eq(expectedDaiAmount);
|
||||
expect(userAEthBalance).to.be.lt(userAEthBalanceBefore);
|
||||
expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('UniswapRepayAdapter', () => {
|
||||
|
|
Loading…
Reference in New Issue
Block a user