mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Fix mockup base tests. Separate uniswap adapter tests into separate files.
This commit is contained in:
parent
e5e61553c8
commit
611605eebf
|
@ -1,7 +1,7 @@
|
||||||
// SPDX-License-Identifier: agpl-3.0
|
// SPDX-License-Identifier: agpl-3.0
|
||||||
pragma solidity 0.6.12;
|
pragma solidity 0.6.12;
|
||||||
|
|
||||||
import {IUniswapV2Router02} from "../../interfaces/IUniswapV2Router02.sol";
|
import {IUniswapV2Router02} from '../../interfaces/IUniswapV2Router02.sol';
|
||||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||||
import {MintableERC20} from '../tokens/MintableERC20.sol';
|
import {MintableERC20} from '../tokens/MintableERC20.sol';
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ contract MockUniswapV2Router02 is IUniswapV2Router02 {
|
||||||
|
|
||||||
function swapExactTokensForTokens(
|
function swapExactTokensForTokens(
|
||||||
uint256 amountIn,
|
uint256 amountIn,
|
||||||
uint256 /* amountOutMin */,
|
uint256, /* amountOutMin */
|
||||||
address[] calldata path,
|
address[] calldata path,
|
||||||
address to,
|
address to,
|
||||||
uint256 /* deadline */
|
uint256 /* deadline */
|
||||||
|
@ -32,50 +32,74 @@ contract MockUniswapV2Router02 is IUniswapV2Router02 {
|
||||||
MintableERC20(path[1]).mint(_amountToReturn[path[0]]);
|
MintableERC20(path[1]).mint(_amountToReturn[path[0]]);
|
||||||
IERC20(path[1]).transfer(to, _amountToReturn[path[0]]);
|
IERC20(path[1]).transfer(to, _amountToReturn[path[0]]);
|
||||||
|
|
||||||
amounts = new uint[](path.length);
|
amounts = new uint256[](path.length);
|
||||||
amounts[0] = amountIn;
|
amounts[0] = amountIn;
|
||||||
amounts[1] = _amountToReturn[path[0]];
|
amounts[1] = _amountToReturn[path[0]];
|
||||||
}
|
}
|
||||||
|
|
||||||
function swapTokensForExactTokens(
|
function swapTokensForExactTokens(
|
||||||
uint amountOut,
|
uint256 amountOut,
|
||||||
uint /* amountInMax */,
|
uint256, /* amountInMax */
|
||||||
address[] calldata path,
|
address[] calldata path,
|
||||||
address to,
|
address to,
|
||||||
uint /* deadline */
|
uint256 /* deadline */
|
||||||
) external override returns (uint256[] memory amounts) {
|
) external override returns (uint256[] memory amounts) {
|
||||||
IERC20(path[0]).transferFrom(msg.sender, address(this), _amountToSwap[path[0]]);
|
IERC20(path[0]).transferFrom(msg.sender, address(this), _amountToSwap[path[0]]);
|
||||||
|
|
||||||
MintableERC20(path[1]).mint(amountOut);
|
MintableERC20(path[1]).mint(amountOut);
|
||||||
IERC20(path[1]).transfer(to, amountOut);
|
IERC20(path[1]).transfer(to, amountOut);
|
||||||
|
|
||||||
amounts = new uint[](path.length);
|
amounts = new uint256[](path.length);
|
||||||
amounts[0] = _amountToSwap[path[0]];
|
amounts[0] = _amountToSwap[path[0]];
|
||||||
amounts[1] = amountOut;
|
amounts[1] = amountOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAmountOut(uint amountIn, address reserveIn, address reserveOut, uint amountOut) public {
|
function setAmountOut(
|
||||||
|
uint256 amountIn,
|
||||||
|
address reserveIn,
|
||||||
|
address reserveOut,
|
||||||
|
uint256 amountOut
|
||||||
|
) public {
|
||||||
_amountsOut[reserveIn][reserveOut][amountIn] = amountOut;
|
_amountsOut[reserveIn][reserveOut][amountIn] = amountOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAmountIn(uint amountOut, address reserveIn, address reserveOut, uint amountIn) public {
|
function setAmountIn(
|
||||||
|
uint256 amountOut,
|
||||||
|
address reserveIn,
|
||||||
|
address reserveOut,
|
||||||
|
uint256 amountIn
|
||||||
|
) public {
|
||||||
_amountsIn[reserveIn][reserveOut][amountOut] = amountIn;
|
_amountsIn[reserveIn][reserveOut][amountOut] = amountIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDefaultMockValue(uint value) public {
|
function setDefaultMockValue(uint256 value) public {
|
||||||
defaultMockValue = value;
|
defaultMockValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAmountsOut(uint amountIn, address[] calldata path) external view override returns (uint[] memory) {
|
function getAmountsOut(uint256 amountIn, address[] calldata path)
|
||||||
uint256[] memory amounts = new uint256[](2);
|
external
|
||||||
|
view
|
||||||
|
override
|
||||||
|
returns (uint256[] memory)
|
||||||
|
{
|
||||||
|
uint256[] memory amounts = new uint256[](path.length);
|
||||||
amounts[0] = amountIn;
|
amounts[0] = amountIn;
|
||||||
amounts[1] = _amountsOut[path[0]][path[1]][amountIn] > 0 ? _amountsOut[path[0]][path[1]][amountIn] : defaultMockValue;
|
amounts[1] = _amountsOut[path[0]][path[1]][amountIn] > 0
|
||||||
|
? _amountsOut[path[0]][path[1]][amountIn]
|
||||||
|
: defaultMockValue;
|
||||||
return amounts;
|
return amounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAmountsIn(uint amountOut, address[] calldata path) external view override returns (uint[] memory) {
|
function getAmountsIn(uint256 amountOut, address[] calldata path)
|
||||||
uint256[] memory amounts = new uint256[](2);
|
external
|
||||||
amounts[0] = _amountsIn[path[0]][path[1]][amountOut] > 0 ? _amountsIn[path[0]][path[1]][amountOut] : defaultMockValue;
|
view
|
||||||
|
override
|
||||||
|
returns (uint256[] memory)
|
||||||
|
{
|
||||||
|
uint256[] memory amounts = new uint256[](path.length);
|
||||||
|
amounts[0] = _amountsIn[path[0]][path[1]][amountOut] > 0
|
||||||
|
? _amountsIn[path[0]][path[1]][amountOut]
|
||||||
|
: defaultMockValue;
|
||||||
amounts[1] = amountOut;
|
amounts[1] = amountOut;
|
||||||
return amounts;
|
return amounts;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,12 @@ import {
|
||||||
import { Signer } from 'ethers';
|
import { Signer } from 'ethers';
|
||||||
import { TokenContractId, eContractid, tEthereumAddress, AavePools } from '../helpers/types';
|
import { TokenContractId, eContractid, tEthereumAddress, AavePools } from '../helpers/types';
|
||||||
import { MintableERC20 } from '../types/MintableERC20';
|
import { MintableERC20 } from '../types/MintableERC20';
|
||||||
import { ConfigNames, getReservesConfigByPool, getTreasuryAddress, loadPoolConfig } from '../helpers/configuration';
|
import {
|
||||||
|
ConfigNames,
|
||||||
|
getReservesConfigByPool,
|
||||||
|
getTreasuryAddress,
|
||||||
|
loadPoolConfig,
|
||||||
|
} from '../helpers/configuration';
|
||||||
import { initializeMakeSuite } from './helpers/make-suite';
|
import { initializeMakeSuite } from './helpers/make-suite';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -38,10 +43,7 @@ import {
|
||||||
setInitialMarketRatesInRatesOracleByHelper,
|
setInitialMarketRatesInRatesOracleByHelper,
|
||||||
} from '../helpers/oracles-helpers';
|
} from '../helpers/oracles-helpers';
|
||||||
import { DRE, waitForTx } from '../helpers/misc-utils';
|
import { DRE, waitForTx } from '../helpers/misc-utils';
|
||||||
import {
|
import { initReservesByHelper, configureReservesByHelper } from '../helpers/init-helpers';
|
||||||
initReservesByHelper,
|
|
||||||
configureReservesByHelper,
|
|
||||||
} from '../helpers/init-helpers';
|
|
||||||
import AaveConfig from '../markets/aave';
|
import AaveConfig from '../markets/aave';
|
||||||
import { ZERO_ADDRESS } from '../helpers/constants';
|
import { ZERO_ADDRESS } from '../helpers/constants';
|
||||||
import {
|
import {
|
||||||
|
@ -216,13 +218,15 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
|
||||||
|
|
||||||
const treasuryAddress = await getTreasuryAddress(config);
|
const treasuryAddress = await getTreasuryAddress(config);
|
||||||
|
|
||||||
await initReservesByHelper(reservesParams, allReservesAddresses, admin, treasuryAddress, ZERO_ADDRESS, false);
|
await initReservesByHelper(
|
||||||
await configureReservesByHelper(
|
|
||||||
reservesParams,
|
reservesParams,
|
||||||
allReservesAddresses,
|
allReservesAddresses,
|
||||||
testHelpers,
|
admin,
|
||||||
admin
|
treasuryAddress,
|
||||||
|
ZERO_ADDRESS,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
await configureReservesByHelper(reservesParams, allReservesAddresses, testHelpers, admin);
|
||||||
|
|
||||||
const collateralManager = await deployLendingPoolCollateralManager();
|
const collateralManager = await deployLendingPoolCollateralManager();
|
||||||
await waitForTx(
|
await waitForTx(
|
||||||
|
@ -238,6 +242,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
|
||||||
const UniswapLiquiditySwapAdapter = await deployUniswapLiquiditySwapAdapter([
|
const UniswapLiquiditySwapAdapter = await deployUniswapLiquiditySwapAdapter([
|
||||||
addressesProvider.address,
|
addressesProvider.address,
|
||||||
mockUniswapRouter.address,
|
mockUniswapRouter.address,
|
||||||
|
mockTokens.WETH.address,
|
||||||
]);
|
]);
|
||||||
await insertContractAddressInDb(
|
await insertContractAddressInDb(
|
||||||
eContractid.UniswapLiquiditySwapAdapter,
|
eContractid.UniswapLiquiditySwapAdapter,
|
||||||
|
@ -247,6 +252,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
|
||||||
const UniswapRepayAdapter = await deployUniswapRepayAdapter([
|
const UniswapRepayAdapter = await deployUniswapRepayAdapter([
|
||||||
addressesProvider.address,
|
addressesProvider.address,
|
||||||
mockUniswapRouter.address,
|
mockUniswapRouter.address,
|
||||||
|
mockTokens.WETH.address,
|
||||||
]);
|
]);
|
||||||
await insertContractAddressInDb(eContractid.UniswapRepayAdapter, UniswapRepayAdapter.address);
|
await insertContractAddressInDb(eContractid.UniswapRepayAdapter, UniswapRepayAdapter.address);
|
||||||
|
|
||||||
|
|
227
test/uniswapAdapters.base.spec.ts
Normal file
227
test/uniswapAdapters.base.spec.ts
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
import { makeSuite, TestEnv } from './helpers/make-suite';
|
||||||
|
import { convertToCurrencyDecimals } from '../helpers/contracts-helpers';
|
||||||
|
import { getMockUniswapRouter } from '../helpers/contracts-getters';
|
||||||
|
import { MockUniswapV2Router02 } from '../types/MockUniswapV2Router02';
|
||||||
|
import BigNumber from 'bignumber.js';
|
||||||
|
import { evmRevert, evmSnapshot } from '../helpers/misc-utils';
|
||||||
|
import { ethers } from 'ethers';
|
||||||
|
import { USD_ADDRESS } from '../helpers/constants';
|
||||||
|
const { parseEther } = ethers.utils;
|
||||||
|
|
||||||
|
const { expect } = require('chai');
|
||||||
|
|
||||||
|
makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
|
||||||
|
let mockUniswapRouter: MockUniswapV2Router02;
|
||||||
|
let evmSnapshotId: string;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
mockUniswapRouter = await getMockUniswapRouter();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
evmSnapshotId = await evmSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await evmRevert(evmSnapshotId);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('BaseUniswapAdapter', () => {
|
||||||
|
describe('getAmountsOut', () => {
|
||||||
|
it('should return the estimated amountOut and prices for the asset swap', async () => {
|
||||||
|
const { weth, dai, uniswapLiquiditySwapAdapter, oracle } = testEnv;
|
||||||
|
|
||||||
|
const amountIn = parseEther('1');
|
||||||
|
const flashloanPremium = amountIn.mul(9).div(10000);
|
||||||
|
const amountToSwap = amountIn.sub(flashloanPremium);
|
||||||
|
|
||||||
|
const wethPrice = await oracle.getAssetPrice(weth.address);
|
||||||
|
const daiPrice = await oracle.getAssetPrice(dai.address);
|
||||||
|
const usdPrice = await oracle.getAssetPrice(USD_ADDRESS);
|
||||||
|
|
||||||
|
const expectedDaiAmount = await convertToCurrencyDecimals(
|
||||||
|
dai.address,
|
||||||
|
new BigNumber(amountToSwap.toString()).div(daiPrice.toString()).toFixed(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
const outPerInPrice = amountToSwap
|
||||||
|
.mul(parseEther('1'))
|
||||||
|
.mul(parseEther('1'))
|
||||||
|
.div(expectedDaiAmount.mul(parseEther('1')));
|
||||||
|
const ethUsdValue = amountIn
|
||||||
|
.mul(wethPrice)
|
||||||
|
.div(parseEther('1'))
|
||||||
|
.mul(usdPrice)
|
||||||
|
.div(parseEther('1'));
|
||||||
|
const daiUsdValue = expectedDaiAmount
|
||||||
|
.mul(daiPrice)
|
||||||
|
.div(parseEther('1'))
|
||||||
|
.mul(usdPrice)
|
||||||
|
.div(parseEther('1'));
|
||||||
|
|
||||||
|
await mockUniswapRouter.setAmountOut(
|
||||||
|
amountToSwap,
|
||||||
|
weth.address,
|
||||||
|
dai.address,
|
||||||
|
expectedDaiAmount
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await uniswapLiquiditySwapAdapter.getAmountsOut(
|
||||||
|
amountIn,
|
||||||
|
weth.address,
|
||||||
|
dai.address
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result['0']).to.be.eq(expectedDaiAmount);
|
||||||
|
expect(result['1']).to.be.eq(outPerInPrice);
|
||||||
|
expect(result['2']).to.be.eq(ethUsdValue);
|
||||||
|
expect(result['3']).to.be.eq(daiUsdValue);
|
||||||
|
});
|
||||||
|
it('should work correctly with different decimals', async () => {
|
||||||
|
const { aave, usdc, uniswapLiquiditySwapAdapter, oracle } = testEnv;
|
||||||
|
|
||||||
|
const amountIn = parseEther('10');
|
||||||
|
const flashloanPremium = amountIn.mul(9).div(10000);
|
||||||
|
const amountToSwap = amountIn.sub(flashloanPremium);
|
||||||
|
|
||||||
|
const aavePrice = await oracle.getAssetPrice(aave.address);
|
||||||
|
const usdcPrice = await oracle.getAssetPrice(usdc.address);
|
||||||
|
const usdPrice = await oracle.getAssetPrice(USD_ADDRESS);
|
||||||
|
|
||||||
|
const expectedUSDCAmount = await convertToCurrencyDecimals(
|
||||||
|
usdc.address,
|
||||||
|
new BigNumber(amountToSwap.toString()).div(usdcPrice.toString()).toFixed(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
const outPerInPrice = amountToSwap
|
||||||
|
.mul(parseEther('1'))
|
||||||
|
.mul('1000000') // usdc 6 decimals
|
||||||
|
.div(expectedUSDCAmount.mul(parseEther('1')));
|
||||||
|
|
||||||
|
const aaveUsdValue = amountIn
|
||||||
|
.mul(aavePrice)
|
||||||
|
.div(parseEther('1'))
|
||||||
|
.mul(usdPrice)
|
||||||
|
.div(parseEther('1'));
|
||||||
|
|
||||||
|
const usdcUsdValue = expectedUSDCAmount
|
||||||
|
.mul(usdcPrice)
|
||||||
|
.div('1000000') // usdc 6 decimals
|
||||||
|
.mul(usdPrice)
|
||||||
|
.div(parseEther('1'));
|
||||||
|
|
||||||
|
await mockUniswapRouter.setAmountOut(
|
||||||
|
amountToSwap,
|
||||||
|
aave.address,
|
||||||
|
usdc.address,
|
||||||
|
expectedUSDCAmount
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await uniswapLiquiditySwapAdapter.getAmountsOut(
|
||||||
|
amountIn,
|
||||||
|
aave.address,
|
||||||
|
usdc.address
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result['0']).to.be.eq(expectedUSDCAmount);
|
||||||
|
expect(result['1']).to.be.eq(outPerInPrice);
|
||||||
|
expect(result['2']).to.be.eq(aaveUsdValue);
|
||||||
|
expect(result['3']).to.be.eq(usdcUsdValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getAmountsIn', () => {
|
||||||
|
it('should return the estimated required amountIn for the asset swap', async () => {
|
||||||
|
const { weth, dai, uniswapLiquiditySwapAdapter, oracle } = testEnv;
|
||||||
|
|
||||||
|
const amountIn = parseEther('1');
|
||||||
|
const flashloanPremium = amountIn.mul(9).div(10000);
|
||||||
|
const amountToSwap = amountIn.add(flashloanPremium);
|
||||||
|
|
||||||
|
const wethPrice = await oracle.getAssetPrice(weth.address);
|
||||||
|
const daiPrice = await oracle.getAssetPrice(dai.address);
|
||||||
|
const usdPrice = await oracle.getAssetPrice(USD_ADDRESS);
|
||||||
|
|
||||||
|
const amountOut = await convertToCurrencyDecimals(
|
||||||
|
dai.address,
|
||||||
|
new BigNumber(amountIn.toString()).div(daiPrice.toString()).toFixed(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
const inPerOutPrice = amountOut
|
||||||
|
.mul(parseEther('1'))
|
||||||
|
.mul(parseEther('1'))
|
||||||
|
.div(amountToSwap.mul(parseEther('1')));
|
||||||
|
|
||||||
|
const ethUsdValue = amountToSwap
|
||||||
|
.mul(wethPrice)
|
||||||
|
.div(parseEther('1'))
|
||||||
|
.mul(usdPrice)
|
||||||
|
.div(parseEther('1'));
|
||||||
|
const daiUsdValue = amountOut
|
||||||
|
.mul(daiPrice)
|
||||||
|
.div(parseEther('1'))
|
||||||
|
.mul(usdPrice)
|
||||||
|
.div(parseEther('1'));
|
||||||
|
|
||||||
|
await mockUniswapRouter.setAmountIn(amountOut, weth.address, dai.address, amountIn);
|
||||||
|
|
||||||
|
const result = await uniswapLiquiditySwapAdapter.getAmountsIn(
|
||||||
|
amountOut,
|
||||||
|
weth.address,
|
||||||
|
dai.address
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result['0']).to.be.eq(amountToSwap);
|
||||||
|
expect(result['1']).to.be.eq(inPerOutPrice);
|
||||||
|
expect(result['2']).to.be.eq(ethUsdValue);
|
||||||
|
expect(result['3']).to.be.eq(daiUsdValue);
|
||||||
|
});
|
||||||
|
it('should work correctly with different decimals', async () => {
|
||||||
|
const { aave, usdc, uniswapLiquiditySwapAdapter, oracle } = testEnv;
|
||||||
|
|
||||||
|
const amountIn = parseEther('10');
|
||||||
|
const flashloanPremium = amountIn.mul(9).div(10000);
|
||||||
|
const amountToSwap = amountIn.add(flashloanPremium);
|
||||||
|
|
||||||
|
const aavePrice = await oracle.getAssetPrice(aave.address);
|
||||||
|
const usdcPrice = await oracle.getAssetPrice(usdc.address);
|
||||||
|
const usdPrice = await oracle.getAssetPrice(USD_ADDRESS);
|
||||||
|
|
||||||
|
const amountOut = await convertToCurrencyDecimals(
|
||||||
|
usdc.address,
|
||||||
|
new BigNumber(amountToSwap.toString()).div(usdcPrice.toString()).toFixed(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
const inPerOutPrice = amountOut
|
||||||
|
.mul(parseEther('1'))
|
||||||
|
.mul(parseEther('1'))
|
||||||
|
.div(amountToSwap.mul('1000000')); // usdc 6 decimals
|
||||||
|
|
||||||
|
const aaveUsdValue = amountToSwap
|
||||||
|
.mul(aavePrice)
|
||||||
|
.div(parseEther('1'))
|
||||||
|
.mul(usdPrice)
|
||||||
|
.div(parseEther('1'));
|
||||||
|
|
||||||
|
const usdcUsdValue = amountOut
|
||||||
|
.mul(usdcPrice)
|
||||||
|
.div('1000000') // usdc 6 decimals
|
||||||
|
.mul(usdPrice)
|
||||||
|
.div(parseEther('1'));
|
||||||
|
|
||||||
|
await mockUniswapRouter.setAmountIn(amountOut, aave.address, usdc.address, amountIn);
|
||||||
|
|
||||||
|
const result = await uniswapLiquiditySwapAdapter.getAmountsIn(
|
||||||
|
amountOut,
|
||||||
|
aave.address,
|
||||||
|
usdc.address
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result['0']).to.be.eq(amountToSwap);
|
||||||
|
expect(result['1']).to.be.eq(inPerOutPrice);
|
||||||
|
expect(result['2']).to.be.eq(aaveUsdValue);
|
||||||
|
expect(result['3']).to.be.eq(usdcUsdValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
File diff suppressed because it is too large
Load Diff
1431
test/uniswapAdapters.repay.spec.ts
Normal file
1431
test/uniswapAdapters.repay.spec.ts
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user