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;
|
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);
|
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('UniswapLiquiditySwapAdapter', () => {
|
||||||
describe('constructor', () => {
|
describe('constructor', () => {
|
||||||
it('should deploy with correct parameters', async () => {
|
it('should deploy with correct parameters', async () => {
|
||||||
|
@ -328,6 +358,72 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
|
||||||
).to.be.revertedWith('INSUFFICIENT_OUTPUT_AMOUNT');
|
).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', () => {
|
describe('UniswapRepayAdapter', () => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user