mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Update getAmountsIn to return prices
This commit is contained in:
parent
5d9cd6ebd1
commit
48b9a603a7
|
@ -40,6 +40,13 @@ contract BaseUniswapAdapter {
|
||||||
bytes32 s;
|
bytes32 s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AmountCalc {
|
||||||
|
uint256 calculatedAmount;
|
||||||
|
uint256 relativePrice;
|
||||||
|
uint256 amountInUsd;
|
||||||
|
uint256 amountOutUsd;
|
||||||
|
}
|
||||||
|
|
||||||
// Max slippage percent allowed
|
// Max slippage percent allowed
|
||||||
uint256 public constant MAX_SLIPPAGE_PERCENT = 3000; // 30%
|
uint256 public constant MAX_SLIPPAGE_PERCENT = 3000; // 30%
|
||||||
// FLash Loan fee set in lending pool
|
// FLash Loan fee set in lending pool
|
||||||
|
@ -64,7 +71,7 @@ contract BaseUniswapAdapter {
|
||||||
* @param amountIn Amount of reserveIn
|
* @param amountIn Amount of reserveIn
|
||||||
* @param reserveIn Address of the asset to be swap from
|
* @param reserveIn Address of the asset to be swap from
|
||||||
* @param reserveOut Address of the asset to be swap to
|
* @param reserveOut Address of the asset to be swap to
|
||||||
* @return uint256 Amount out fo the reserveOut
|
* @return uint256 Amount out of the reserveOut
|
||||||
* @return uint256 The price of out amount denominated in the reserveIn currency (18 decimals)
|
* @return uint256 The price of out amount denominated in the reserveIn currency (18 decimals)
|
||||||
* @return uint256 In amount of reserveIn value denominated in USD (8 decimals)
|
* @return uint256 In amount of reserveIn value denominated in USD (8 decimals)
|
||||||
* @return uint256 Out amount of reserveOut value denominated in USD (8 decimals)
|
* @return uint256 Out amount of reserveOut value denominated in USD (8 decimals)
|
||||||
|
@ -74,46 +81,39 @@ contract BaseUniswapAdapter {
|
||||||
view
|
view
|
||||||
returns (uint256, uint256, uint256, uint256)
|
returns (uint256, uint256, uint256, uint256)
|
||||||
{
|
{
|
||||||
// Subtract flash loan fee
|
AmountCalc memory results = _getAmountsOut(reserveIn, reserveOut, amountIn);
|
||||||
uint256 finalAmountIn = amountIn.sub(amountIn.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000));
|
|
||||||
|
|
||||||
uint256 amountOut = _getAmountsOut(reserveIn, reserveOut, finalAmountIn);
|
|
||||||
|
|
||||||
uint256 reserveInDecimals = _getDecimals(reserveIn);
|
|
||||||
uint256 reserveOutDecimals = _getDecimals(reserveOut);
|
|
||||||
|
|
||||||
uint256 outPerInPrice = finalAmountIn
|
|
||||||
.mul(10**18)
|
|
||||||
.mul(10**reserveOutDecimals)
|
|
||||||
.div(amountOut.mul(10**reserveInDecimals));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
amountOut,
|
results.calculatedAmount,
|
||||||
outPerInPrice,
|
results.relativePrice,
|
||||||
_calcUsdValue(reserveIn, amountIn, reserveInDecimals),
|
results.amountInUsd,
|
||||||
_calcUsdValue(reserveOut, amountOut, reserveOutDecimals)
|
results.amountOutUsd
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Returns the minimum input asset amount required to buy the given output asset amount
|
* @dev Returns the minimum input asset amount required to buy the given output asset amount and the prices
|
||||||
* @param amountOut Amount of reserveOut
|
* @param amountOut Amount of reserveOut
|
||||||
* @param reserveIn Address of the asset to be swap from
|
* @param reserveIn Address of the asset to be swap from
|
||||||
* @param reserveOut Address of the asset to be swap to
|
* @param reserveOut Address of the asset to be swap to
|
||||||
* @return uint256 amountIn
|
* @return uint256 Amount in of the reserveIn
|
||||||
|
* @return uint256 The price of in amount denominated in the reserveOut currency (18 decimals)
|
||||||
|
* @return uint256 In amount of reserveIn value denominated in USD (8 decimals)
|
||||||
|
* @return uint256 Out amount of reserveOut value denominated in USD (8 decimals)
|
||||||
*/
|
*/
|
||||||
function getAmountIn(uint256 amountOut, address reserveIn, address reserveOut)
|
function getAmountsIn(uint256 amountOut, address reserveIn, address reserveOut)
|
||||||
external
|
external
|
||||||
view
|
view
|
||||||
returns (uint256)
|
returns (uint256, uint256, uint256, uint256)
|
||||||
{
|
{
|
||||||
address[] memory path = new address[](2);
|
AmountCalc memory results = _getAmountsIn(reserveIn, reserveOut, amountOut);
|
||||||
path[0] = reserveIn;
|
|
||||||
path[1] = reserveOut;
|
|
||||||
|
|
||||||
uint256[] memory amounts = UNISWAP_ROUTER.getAmountsIn(amountOut, path);
|
return (
|
||||||
|
results.calculatedAmount,
|
||||||
return amounts[0];
|
results.relativePrice,
|
||||||
|
results.amountInUsd,
|
||||||
|
results.amountOutUsd
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -337,15 +337,72 @@ contract BaseUniswapAdapter {
|
||||||
* @param reserveIn Address of the asset to be swap from
|
* @param reserveIn Address of the asset to be swap from
|
||||||
* @param reserveOut Address of the asset to be swap to
|
* @param reserveOut Address of the asset to be swap to
|
||||||
* @param amountIn Amount of reserveIn
|
* @param amountIn Amount of reserveIn
|
||||||
* @return the output amount
|
* @return Struct containing the following information:
|
||||||
|
* uint256 Amount out of the reserveOut
|
||||||
|
* uint256 The price of out amount denominated in the reserveIn currency (18 decimals)
|
||||||
|
* uint256 In amount of reserveIn value denominated in USD (8 decimals)
|
||||||
|
* uint256 Out amount of reserveOut value denominated in USD (8 decimals)
|
||||||
*/
|
*/
|
||||||
function _getAmountsOut(address reserveIn, address reserveOut, uint256 amountIn) internal view returns (uint256) {
|
function _getAmountsOut(address reserveIn, address reserveOut, uint256 amountIn) internal view returns (AmountCalc memory) {
|
||||||
|
// Subtract flash loan fee
|
||||||
|
uint256 finalAmountIn = amountIn.sub(amountIn.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000));
|
||||||
|
|
||||||
address[] memory path = new address[](2);
|
address[] memory path = new address[](2);
|
||||||
path[0] = reserveIn;
|
path[0] = reserveIn;
|
||||||
path[1] = reserveOut;
|
path[1] = reserveOut;
|
||||||
|
|
||||||
uint256[] memory amounts = UNISWAP_ROUTER.getAmountsOut(amountIn, path);
|
uint256[] memory amounts = UNISWAP_ROUTER.getAmountsOut(finalAmountIn, path);
|
||||||
|
|
||||||
return amounts[1];
|
uint256 reserveInDecimals = _getDecimals(reserveIn);
|
||||||
|
uint256 reserveOutDecimals = _getDecimals(reserveOut);
|
||||||
|
|
||||||
|
uint256 outPerInPrice = finalAmountIn
|
||||||
|
.mul(10**18)
|
||||||
|
.mul(10**reserveOutDecimals)
|
||||||
|
.div(amounts[1].mul(10**reserveInDecimals));
|
||||||
|
|
||||||
|
return AmountCalc(
|
||||||
|
amounts[1],
|
||||||
|
outPerInPrice,
|
||||||
|
_calcUsdValue(reserveIn, amountIn, reserveInDecimals),
|
||||||
|
_calcUsdValue(reserveOut, amounts[1], reserveOutDecimals)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Returns the minimum input asset amount required to buy the given output asset amount
|
||||||
|
* @param reserveIn Address of the asset to be swap from
|
||||||
|
* @param reserveOut Address of the asset to be swap to
|
||||||
|
* @param amountOut Amount of reserveOut
|
||||||
|
* @return Struct containing the following information:
|
||||||
|
* uint256 Amount in of the reserveIn
|
||||||
|
* uint256 The price of in amount denominated in the reserveOut currency (18 decimals)
|
||||||
|
* uint256 In amount of reserveIn value denominated in USD (8 decimals)
|
||||||
|
* uint256 Out amount of reserveOut value denominated in USD (8 decimals)
|
||||||
|
*/
|
||||||
|
function _getAmountsIn(address reserveIn, address reserveOut, uint256 amountOut) internal view returns (AmountCalc memory) {
|
||||||
|
address[] memory path = new address[](2);
|
||||||
|
path[0] = reserveIn;
|
||||||
|
path[1] = reserveOut;
|
||||||
|
|
||||||
|
uint256[] memory amounts = UNISWAP_ROUTER.getAmountsIn(amountOut, path);
|
||||||
|
|
||||||
|
// Subtract flash loan fee
|
||||||
|
uint256 finalAmountIn = amounts[0].sub(amounts[0].mul(FLASHLOAN_PREMIUM_TOTAL).div(10000));
|
||||||
|
|
||||||
|
uint256 reserveInDecimals = _getDecimals(reserveIn);
|
||||||
|
uint256 reserveOutDecimals = _getDecimals(reserveOut);
|
||||||
|
|
||||||
|
uint256 inPerOutPrice = amountOut
|
||||||
|
.mul(10**18)
|
||||||
|
.mul(10**reserveInDecimals)
|
||||||
|
.div(finalAmountIn.mul(10**reserveOutDecimals));
|
||||||
|
|
||||||
|
return AmountCalc(
|
||||||
|
finalAmountIn,
|
||||||
|
inPerOutPrice,
|
||||||
|
_calcUsdValue(reserveIn, finalAmountIn, reserveInDecimals),
|
||||||
|
_calcUsdValue(reserveOut, amountOut, reserveOutDecimals)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
|
||||||
|
|
||||||
const outPerInPrice = amountToSwap
|
const outPerInPrice = amountToSwap
|
||||||
.mul(parseEther('1'))
|
.mul(parseEther('1'))
|
||||||
.mul('1000000')
|
.mul('1000000') // usdc 6 decimals
|
||||||
.div(expectedUSDCAmount.mul(parseEther('1')));
|
.div(expectedUSDCAmount.mul(parseEther('1')));
|
||||||
|
|
||||||
const lendUsdValue = amountIn
|
const lendUsdValue = amountIn
|
||||||
|
@ -120,7 +120,7 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
|
||||||
|
|
||||||
const usdcUsdValue = expectedUSDCAmount
|
const usdcUsdValue = expectedUSDCAmount
|
||||||
.mul(usdcPrice)
|
.mul(usdcPrice)
|
||||||
.div('1000000')
|
.div('1000000') // usdc 6 decimals
|
||||||
.mul(usdPrice)
|
.mul(usdPrice)
|
||||||
.div(parseEther('1'));
|
.div(parseEther('1'));
|
||||||
|
|
||||||
|
@ -144,17 +144,97 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getAmountIn', () => {
|
describe('getAmountsIn', () => {
|
||||||
it('should return the estimated required amountIn for the asset swap', async () => {
|
it('should return the estimated required amountIn for the asset swap', async () => {
|
||||||
const {weth, dai, uniswapLiquiditySwapAdapter} = testEnv;
|
const {weth, dai, uniswapLiquiditySwapAdapter, oracle} = testEnv;
|
||||||
|
|
||||||
const amountIn = parseEther('1');
|
const amountIn = parseEther('1');
|
||||||
const amountOut = parseEther('2');
|
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 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);
|
await mockUniswapRouter.setAmountIn(amountOut, weth.address, dai.address, amountIn);
|
||||||
|
|
||||||
expect(
|
const result = await uniswapLiquiditySwapAdapter.getAmountsIn(
|
||||||
await uniswapLiquiditySwapAdapter.getAmountIn(amountOut, weth.address, dai.address)
|
amountOut,
|
||||||
).to.be.eq(amountIn);
|
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 {lend, usdc, uniswapLiquiditySwapAdapter, oracle} = testEnv;
|
||||||
|
|
||||||
|
const amountIn = parseEther('10');
|
||||||
|
const flashloanPremium = amountIn.mul(9).div(10000);
|
||||||
|
const amountToSwap = amountIn.sub(flashloanPremium);
|
||||||
|
|
||||||
|
const lendPrice = await oracle.getAssetPrice(lend.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 lendUsdValue = amountToSwap
|
||||||
|
.mul(lendPrice)
|
||||||
|
.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, lend.address, usdc.address, amountIn);
|
||||||
|
|
||||||
|
const result = await uniswapLiquiditySwapAdapter.getAmountsIn(
|
||||||
|
amountOut,
|
||||||
|
lend.address,
|
||||||
|
usdc.address
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result['0']).to.be.eq(amountToSwap);
|
||||||
|
expect(result['1']).to.be.eq(inPerOutPrice);
|
||||||
|
expect(result['2']).to.be.eq(lendUsdValue);
|
||||||
|
expect(result['3']).to.be.eq(usdcUsdValue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user