mirror of
https://github.com/Instadapp/fluid-contracts-public.git
synced 2024-07-29 21:57:37 +00:00
1237 lines
46 KiB
Solidity
1237 lines
46 KiB
Solidity
//SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.21;
|
|
|
|
import { LiquidityUserModuleOperateTestSuite } from "./liquidityOperate.t.sol";
|
|
import { LiquidityCalcs } from "../../../../contracts/libraries/liquidityCalcs.sol";
|
|
|
|
/***********************************|
|
|
| SUPPLY & BORROW |
|
|
|__________________________________*/
|
|
|
|
contract LiquidityUserModuleSupplyAndBorrowTestSuite is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
uint256 supplyExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
uint256 borrowExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
|
|
uint256 exchangePricesAndConfig;
|
|
{
|
|
uint256 utilization = (DEFAULT_BORROW_AMOUNT * FOUR_DECIMALS) / DEFAULT_SUPPLY_AMOUNT;
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(address(USDC)),
|
|
utilization
|
|
);
|
|
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
address(USDC),
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
_setTestOperateParams(
|
|
address(USDC),
|
|
int256(DEFAULT_SUPPLY_AMOUNT),
|
|
int256(DEFAULT_BORROW_AMOUNT),
|
|
alice,
|
|
address(0),
|
|
alice,
|
|
_simulateTotalAmounts(DEFAULT_SUPPLY_AMOUNT, 0, DEFAULT_BORROW_AMOUNT, 0),
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
_simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
DEFAULT_SUPPLY_AMOUNT,
|
|
0, // previous limit
|
|
block.timestamp
|
|
),
|
|
_simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
DEFAULT_BORROW_AMOUNT,
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
contract LiquidityUserModuleSupplyAndBorrowTestSuiteInterestFree is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
_setUserAllowancesDefaultInterestFree(address(liquidity), admin, address(USDC), address(mockProtocol));
|
|
|
|
uint256 supplyExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
uint256 borrowExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
|
|
uint256 exchangePricesAndConfig;
|
|
{
|
|
uint256 utilization = (DEFAULT_BORROW_AMOUNT * FOUR_DECIMALS) / DEFAULT_SUPPLY_AMOUNT;
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(address(USDC)),
|
|
utilization
|
|
);
|
|
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
address(USDC),
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
1,
|
|
1
|
|
);
|
|
}
|
|
|
|
_setTestOperateParams(
|
|
address(USDC),
|
|
int256(DEFAULT_SUPPLY_AMOUNT),
|
|
int256(DEFAULT_BORROW_AMOUNT),
|
|
alice,
|
|
address(0),
|
|
alice,
|
|
_simulateTotalAmounts(0, DEFAULT_SUPPLY_AMOUNT, 0, DEFAULT_BORROW_AMOUNT),
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
_simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
DEFAULT_SUPPLY_AMOUNT,
|
|
0, // previous limit
|
|
block.timestamp
|
|
),
|
|
_simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
DEFAULT_BORROW_AMOUNT,
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
contract LiquidityUserModuleSupplyAndBorrowTestSuiteNative is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
uint256 supplyExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
uint256 borrowExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
|
|
uint256 exchangePricesAndConfig;
|
|
{
|
|
uint256 utilization = (DEFAULT_BORROW_AMOUNT * FOUR_DECIMALS) / DEFAULT_SUPPLY_AMOUNT;
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(NATIVE_TOKEN_ADDRESS),
|
|
utilization
|
|
);
|
|
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
NATIVE_TOKEN_ADDRESS,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
_setTestOperateParams(
|
|
NATIVE_TOKEN_ADDRESS,
|
|
int256(DEFAULT_SUPPLY_AMOUNT),
|
|
int256(DEFAULT_BORROW_AMOUNT),
|
|
alice,
|
|
address(0),
|
|
alice,
|
|
_simulateTotalAmounts(DEFAULT_SUPPLY_AMOUNT, 0, DEFAULT_BORROW_AMOUNT, 0),
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
_simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
DEFAULT_SUPPLY_AMOUNT,
|
|
0, // previous limit
|
|
block.timestamp
|
|
),
|
|
_simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
DEFAULT_BORROW_AMOUNT,
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
contract LiquidityUserModuleSupplyAndBorrowTestSuiteInterestFreeNative is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
_setUserAllowancesDefaultInterestFree(address(liquidity), admin, NATIVE_TOKEN_ADDRESS, address(mockProtocol));
|
|
|
|
uint256 supplyExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
uint256 borrowExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
|
|
uint256 exchangePricesAndConfig;
|
|
{
|
|
uint256 utilization = (DEFAULT_BORROW_AMOUNT * FOUR_DECIMALS) / DEFAULT_SUPPLY_AMOUNT;
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(NATIVE_TOKEN_ADDRESS),
|
|
utilization
|
|
);
|
|
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
NATIVE_TOKEN_ADDRESS,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
1,
|
|
1
|
|
);
|
|
}
|
|
|
|
_setTestOperateParams(
|
|
NATIVE_TOKEN_ADDRESS,
|
|
int256(DEFAULT_SUPPLY_AMOUNT),
|
|
int256(DEFAULT_BORROW_AMOUNT),
|
|
alice,
|
|
address(0),
|
|
alice,
|
|
_simulateTotalAmounts(0, DEFAULT_SUPPLY_AMOUNT, 0, DEFAULT_BORROW_AMOUNT),
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
_simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
DEFAULT_SUPPLY_AMOUNT,
|
|
0, // previous limit
|
|
block.timestamp
|
|
),
|
|
_simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
DEFAULT_BORROW_AMOUNT,
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
/***********************************|
|
|
| SUPPLY & PAYBACK |
|
|
|__________________________________*/
|
|
|
|
contract LiquidityUserModuleSupplyAndPaybackTestSuite is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
// alice supplies USDC liquidity
|
|
_supply(mockProtocol, address(USDC), alice, DEFAULT_SUPPLY_AMOUNT);
|
|
|
|
// alice borrows USDC liquidity
|
|
_borrow(mockProtocol, address(USDC), alice, DEFAULT_BORROW_AMOUNT);
|
|
|
|
// simulate passing time 1 year to get a better predicatable borrow rate and amounts
|
|
vm.warp(block.timestamp + PASS_1YEAR_TIME);
|
|
|
|
uint256 supplyExchangePrice = 1038750000000; // increased half of 7.75% -> 3.875% (because half of supply is borrowed out)
|
|
uint256 borrowExchangePrice = 1077500000000; // increased 7.75%
|
|
|
|
uint256 totalAmounts;
|
|
uint256 userBorrowData;
|
|
uint256 exchangePricesAndConfig;
|
|
uint256 totalSupplyRawInterest;
|
|
{
|
|
uint256 defaultBorrowAmountAfterRounding = 500000000000000008; // BigMath round up at borrow leads to minor difference
|
|
|
|
uint256 totalBorrow = (((defaultBorrowAmountAfterRounding * borrowExchangePrice) /
|
|
EXCHANGE_PRICES_PRECISION) - DEFAULT_PAYBACK_AMOUNT);
|
|
assertEq(totalBorrow, 238750000000000008);
|
|
uint256 totalBorrowRawInterest = ((totalBorrow * EXCHANGE_PRICES_PRECISION) / borrowExchangePrice) + 1; // should be 0.221577726218097455 +1 for round up
|
|
assertEq(totalBorrowRawInterest, 221577726218097456);
|
|
|
|
totalSupplyRawInterest =
|
|
DEFAULT_SUPPLY_AMOUNT + // previous supply raw
|
|
((DEFAULT_SUPPLY_AMOUNT * EXCHANGE_PRICES_PRECISION) / supplyExchangePrice); // new supply adjusted to raw
|
|
assertEq(totalSupplyRawInterest, 1962695547533092659);
|
|
|
|
uint256 totalSupply = ((DEFAULT_SUPPLY_AMOUNT * supplyExchangePrice) / EXCHANGE_PRICES_PRECISION) +
|
|
DEFAULT_SUPPLY_AMOUNT;
|
|
assertEq(totalSupply, 2038750000000000000); // 1 ether * 1038750000000 + 1 ether
|
|
|
|
totalAmounts = _simulateTotalAmounts(totalSupplyRawInterest, 0, totalBorrowRawInterest, 0);
|
|
|
|
userBorrowData = _simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
totalBorrowRawInterest, // taking interest on borrow amount until payback into account
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
);
|
|
|
|
// utilization AFTER payback
|
|
uint256 utilization = (totalBorrow * FOUR_DECIMALS) / totalSupply; // results in 11,7106 %
|
|
assertEq(utilization, 1171);
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(address(USDC)),
|
|
utilization
|
|
);
|
|
assertEq(borrowRate, 487); // expected borrow rate at ~11,71% utilization
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
address(USDC),
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
_setTestOperateParams(
|
|
address(USDC),
|
|
int256(DEFAULT_SUPPLY_AMOUNT),
|
|
-int256(DEFAULT_PAYBACK_AMOUNT),
|
|
alice,
|
|
address(0),
|
|
address(0),
|
|
totalAmounts,
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
_simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
totalSupplyRawInterest,
|
|
0, // previous limit
|
|
block.timestamp
|
|
),
|
|
userBorrowData,
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
contract LiquidityUserModuleSupplyAndPaybackTestSuiteInterestFree is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
_setUserAllowancesDefaultInterestFree(address(liquidity), admin, address(USDC), address(mockProtocol));
|
|
|
|
// alice supplies USDC liquidity
|
|
_supply(mockProtocol, address(USDC), alice, DEFAULT_SUPPLY_AMOUNT);
|
|
|
|
// alice borrows USDC liquidity
|
|
_borrow(mockProtocol, address(USDC), alice, DEFAULT_BORROW_AMOUNT);
|
|
|
|
// simulate passing time 1 year to get a better predicatable borrow rate and amounts
|
|
vm.warp(block.timestamp + PASS_1YEAR_TIME);
|
|
|
|
// exchange prices are not changing because of interest free mode
|
|
uint256 supplyExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
uint256 borrowExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
|
|
uint256 totalAmounts;
|
|
uint256 totalSupply = DEFAULT_SUPPLY_AMOUNT * 2;
|
|
uint256 exchangePricesAndConfig;
|
|
{
|
|
uint256 defaultBorrowAmountAfterRounding = 500000000000000008; // BigMath round up at borrow leads to minor difference
|
|
uint256 totalBorrow = defaultBorrowAmountAfterRounding - DEFAULT_PAYBACK_AMOUNT;
|
|
totalAmounts = _simulateTotalAmounts(0, totalSupply, 0, totalBorrow);
|
|
|
|
// utilization AFTER payback
|
|
uint256 utilization = (totalBorrow * FOUR_DECIMALS) / totalSupply; // results in 10%
|
|
assertEq(utilization, 1000);
|
|
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(address(USDC)),
|
|
utilization
|
|
);
|
|
assertEq(borrowRate, 475); // expected borrow rate at 10% utilization
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
address(USDC),
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
1, // supplyRatio = 1 for mode set to total supply with interest < interest free
|
|
1 // borrowRatio = 1 for mode set to total supply with interest < interest free
|
|
);
|
|
}
|
|
|
|
uint256 userSupplyData = _simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
totalSupply,
|
|
0, // previous limit
|
|
block.timestamp
|
|
);
|
|
|
|
_setTestOperateParams(
|
|
address(USDC),
|
|
int256(DEFAULT_SUPPLY_AMOUNT),
|
|
-int256(DEFAULT_PAYBACK_AMOUNT),
|
|
alice,
|
|
address(0),
|
|
address(0),
|
|
totalAmounts,
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
userSupplyData,
|
|
_simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
DEFAULT_BORROW_AMOUNT_AFTER_BIGMATH - DEFAULT_PAYBACK_AMOUNT,
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
contract LiquidityUserModuleSupplyAndPaybackTestSuiteNative is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
// alice supplies liquidity
|
|
_supplyNative(mockProtocol, alice, DEFAULT_SUPPLY_AMOUNT);
|
|
|
|
// alice borrows liquidity
|
|
_borrowNative(mockProtocol, alice, DEFAULT_BORROW_AMOUNT);
|
|
|
|
// simulate passing time 1 year to get a better predicatable borrow rate and amounts
|
|
vm.warp(block.timestamp + PASS_1YEAR_TIME);
|
|
|
|
uint256 supplyExchangePrice = 1038750000000; // increased half of 7.75% -> 3.875% (because half of supply is borrowed out)
|
|
uint256 borrowExchangePrice = 1077500000000; // increased 7.75%
|
|
|
|
uint256 totalAmounts;
|
|
uint256 userBorrowData;
|
|
uint256 exchangePricesAndConfig;
|
|
uint256 totalSupplyRawInterest;
|
|
{
|
|
uint256 defaultBorrowAmountAfterRounding = 500000000000000008; // BigMath round up at borrow leads to minor difference
|
|
|
|
uint256 totalBorrow = (((defaultBorrowAmountAfterRounding * borrowExchangePrice) /
|
|
EXCHANGE_PRICES_PRECISION) - DEFAULT_PAYBACK_AMOUNT);
|
|
assertEq(totalBorrow, 238750000000000008);
|
|
uint256 totalBorrowRawInterest = ((totalBorrow * EXCHANGE_PRICES_PRECISION) / borrowExchangePrice) + 1; // should be 0.221577726218097455 +1 for round up
|
|
assertEq(totalBorrowRawInterest, 221577726218097456);
|
|
|
|
totalSupplyRawInterest =
|
|
DEFAULT_SUPPLY_AMOUNT + // previous supply raw
|
|
((DEFAULT_SUPPLY_AMOUNT * EXCHANGE_PRICES_PRECISION) / supplyExchangePrice); // new supply adjusted to raw
|
|
assertEq(totalSupplyRawInterest, 1962695547533092659);
|
|
|
|
uint256 totalSupply = ((DEFAULT_SUPPLY_AMOUNT * supplyExchangePrice) / EXCHANGE_PRICES_PRECISION) +
|
|
DEFAULT_SUPPLY_AMOUNT;
|
|
assertEq(totalSupply, 2038750000000000000); // 1 ether * 1038750000000 + 1 ether
|
|
|
|
totalAmounts = _simulateTotalAmounts(totalSupplyRawInterest, 0, totalBorrowRawInterest, 0);
|
|
|
|
userBorrowData = _simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
totalBorrowRawInterest, // taking interest on borrow amount until payback into account
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
);
|
|
|
|
// utilization AFTER payback
|
|
uint256 utilization = (totalBorrow * FOUR_DECIMALS) / totalSupply; // results in 11,7106 %
|
|
assertEq(utilization, 1171);
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(NATIVE_TOKEN_ADDRESS),
|
|
utilization
|
|
);
|
|
assertEq(borrowRate, 487); // expected borrow rate at ~11,71% utilization
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
NATIVE_TOKEN_ADDRESS,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
_setTestOperateParams(
|
|
NATIVE_TOKEN_ADDRESS,
|
|
int256(DEFAULT_SUPPLY_AMOUNT),
|
|
-int256(DEFAULT_PAYBACK_AMOUNT),
|
|
alice,
|
|
address(0),
|
|
address(0),
|
|
totalAmounts,
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
_simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
totalSupplyRawInterest,
|
|
0, // previous limit
|
|
block.timestamp
|
|
),
|
|
userBorrowData,
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
contract LiquidityUserModuleSupplyAndPaybackTestSuiteInterestFreeNative is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
_setUserAllowancesDefaultInterestFree(address(liquidity), admin, NATIVE_TOKEN_ADDRESS, address(mockProtocol));
|
|
|
|
_supplyNative(mockProtocol, alice, DEFAULT_SUPPLY_AMOUNT);
|
|
|
|
// alice borrows liquidity
|
|
_borrowNative(mockProtocol, alice, DEFAULT_BORROW_AMOUNT);
|
|
|
|
// simulate passing time 1 year to get a better predicatable borrow rate and amounts
|
|
vm.warp(block.timestamp + PASS_1YEAR_TIME);
|
|
|
|
// exchange prices are not changing because of interest free mode
|
|
uint256 supplyExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
uint256 borrowExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
|
|
uint256 totalAmounts;
|
|
uint256 totalSupply = DEFAULT_SUPPLY_AMOUNT * 2;
|
|
uint256 exchangePricesAndConfig;
|
|
{
|
|
uint256 defaultBorrowAmountAfterRounding = 500000000000000008; // BigMath round up at borrow leads to minor difference
|
|
uint256 totalBorrow = defaultBorrowAmountAfterRounding - DEFAULT_PAYBACK_AMOUNT;
|
|
totalAmounts = _simulateTotalAmounts(0, totalSupply, 0, totalBorrow);
|
|
|
|
// utilization AFTER payback
|
|
uint256 utilization = (totalBorrow * FOUR_DECIMALS) / totalSupply; // results in 10%
|
|
assertEq(utilization, 1000);
|
|
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(NATIVE_TOKEN_ADDRESS),
|
|
utilization
|
|
);
|
|
assertEq(borrowRate, 475); // expected borrow rate at 10% utilization
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
NATIVE_TOKEN_ADDRESS,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
1, // supplyRatio = 1 for mode set to total supply with interest < interest free
|
|
1 // borrowRatio = 1 for mode set to total supply with interest < interest free
|
|
);
|
|
}
|
|
|
|
uint256 userSupplyData = _simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
totalSupply,
|
|
0, // previous limit
|
|
block.timestamp
|
|
);
|
|
|
|
_setTestOperateParams(
|
|
NATIVE_TOKEN_ADDRESS,
|
|
int256(DEFAULT_SUPPLY_AMOUNT),
|
|
-int256(DEFAULT_PAYBACK_AMOUNT),
|
|
alice,
|
|
address(0),
|
|
address(0),
|
|
totalAmounts,
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
userSupplyData,
|
|
_simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
DEFAULT_BORROW_AMOUNT_AFTER_BIGMATH - DEFAULT_PAYBACK_AMOUNT,
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
/***********************************|
|
|
| WITHDRAW & BORROW |
|
|
|__________________________________*/
|
|
|
|
contract LiquidityUserModuleWithdrawAndBorrowTestSuite is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
// alice supplies USDC liquidity
|
|
_supply(mockProtocol, address(USDC), alice, DEFAULT_SUPPLY_AMOUNT);
|
|
|
|
uint256 supplyExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
uint256 borrowExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
|
|
uint256 exchangePricesAndConfig;
|
|
{
|
|
uint256 utilization = (DEFAULT_BORROW_AMOUNT * FOUR_DECIMALS) /
|
|
(DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT);
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(address(USDC)),
|
|
utilization
|
|
);
|
|
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
address(USDC),
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
_setTestOperateParams(
|
|
address(USDC),
|
|
-int256(DEFAULT_WITHDRAW_AMOUNT),
|
|
int256(DEFAULT_BORROW_AMOUNT),
|
|
alice,
|
|
alice,
|
|
alice,
|
|
_simulateTotalAmounts(DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT, 0, DEFAULT_BORROW_AMOUNT, 0),
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
_simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT,
|
|
0, // previous limit
|
|
block.timestamp
|
|
),
|
|
_simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
DEFAULT_BORROW_AMOUNT,
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
contract LiquidityUserModuleWithdrawAndBorrowTestSuiteInterestFree is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
_setUserAllowancesDefaultInterestFree(address(liquidity), admin, address(USDC), address(mockProtocol));
|
|
|
|
// alice supplies USDC liquidity
|
|
_supply(mockProtocol, address(USDC), alice, DEFAULT_SUPPLY_AMOUNT);
|
|
|
|
uint256 supplyExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
uint256 borrowExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
|
|
uint256 exchangePricesAndConfig;
|
|
{
|
|
uint256 utilization = (DEFAULT_BORROW_AMOUNT * FOUR_DECIMALS) /
|
|
(DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT);
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(address(USDC)),
|
|
utilization
|
|
);
|
|
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
address(USDC),
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
1,
|
|
1
|
|
);
|
|
}
|
|
|
|
_setTestOperateParams(
|
|
address(USDC),
|
|
-int256(DEFAULT_WITHDRAW_AMOUNT),
|
|
int256(DEFAULT_BORROW_AMOUNT),
|
|
alice,
|
|
alice,
|
|
alice,
|
|
_simulateTotalAmounts(0, DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT, 0, DEFAULT_BORROW_AMOUNT),
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
_simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT,
|
|
0, // previous limit
|
|
block.timestamp
|
|
),
|
|
_simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
DEFAULT_BORROW_AMOUNT,
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
contract LiquidityUserModuleWithdrawAndBorrowTestSuiteNative is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
// alice supplies liquidity
|
|
_supplyNative(mockProtocol, alice, DEFAULT_SUPPLY_AMOUNT);
|
|
|
|
uint256 supplyExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
uint256 borrowExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
|
|
uint256 exchangePricesAndConfig;
|
|
{
|
|
uint256 utilization = (DEFAULT_BORROW_AMOUNT * FOUR_DECIMALS) /
|
|
(DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT);
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(NATIVE_TOKEN_ADDRESS),
|
|
utilization
|
|
);
|
|
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
NATIVE_TOKEN_ADDRESS,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
_setTestOperateParams(
|
|
NATIVE_TOKEN_ADDRESS,
|
|
-int256(DEFAULT_WITHDRAW_AMOUNT),
|
|
int256(DEFAULT_BORROW_AMOUNT),
|
|
alice,
|
|
alice,
|
|
alice,
|
|
_simulateTotalAmounts(DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT, 0, DEFAULT_BORROW_AMOUNT, 0),
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
_simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT,
|
|
0, // previous limit
|
|
block.timestamp
|
|
),
|
|
_simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
DEFAULT_BORROW_AMOUNT,
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
contract LiquidityUserModuleWithdrawAndBorrowTestSuiteInterestFreeNative is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
_setUserAllowancesDefaultInterestFree(address(liquidity), admin, NATIVE_TOKEN_ADDRESS, address(mockProtocol));
|
|
|
|
// alice supplies liquidity
|
|
_supplyNative(mockProtocol, alice, DEFAULT_SUPPLY_AMOUNT);
|
|
|
|
uint256 supplyExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
uint256 borrowExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
|
|
uint256 exchangePricesAndConfig;
|
|
{
|
|
uint256 utilization = (DEFAULT_BORROW_AMOUNT * FOUR_DECIMALS) /
|
|
(DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT);
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(NATIVE_TOKEN_ADDRESS),
|
|
utilization
|
|
);
|
|
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
NATIVE_TOKEN_ADDRESS,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
1,
|
|
1
|
|
);
|
|
}
|
|
|
|
_setTestOperateParams(
|
|
NATIVE_TOKEN_ADDRESS,
|
|
-int256(DEFAULT_WITHDRAW_AMOUNT),
|
|
int256(DEFAULT_BORROW_AMOUNT),
|
|
alice,
|
|
alice,
|
|
alice,
|
|
_simulateTotalAmounts(0, DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT, 0, DEFAULT_BORROW_AMOUNT),
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
_simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT,
|
|
0, // previous limit
|
|
block.timestamp
|
|
),
|
|
_simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
DEFAULT_BORROW_AMOUNT,
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
/***********************************|
|
|
| WITHDRAW & PAYBACK |
|
|
|__________________________________*/
|
|
|
|
contract LiquidityUserModuleWithdrawAndPaybackTestSuite is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
// alice supplies USDC liquidity
|
|
_supply(mockProtocol, address(USDC), alice, DEFAULT_SUPPLY_AMOUNT);
|
|
|
|
// alice borrows USDC liquidity
|
|
_borrow(mockProtocol, address(USDC), alice, DEFAULT_BORROW_AMOUNT);
|
|
|
|
// simulate passing time 1 year to get a better predicatable borrow rate and amounts
|
|
vm.warp(block.timestamp + PASS_1YEAR_TIME);
|
|
|
|
uint256 supplyExchangePrice = 1038750000000; // increased half of 7.75% -> 3.875% (because half of supply is borrowed out)
|
|
uint256 borrowExchangePrice = 1077500000000; // increased 7.75%
|
|
|
|
uint256 totalAmounts;
|
|
uint256 userBorrowData;
|
|
uint256 exchangePricesAndConfig;
|
|
uint256 totalSupplyRawInterest;
|
|
{
|
|
uint256 defaultBorrowAmountAfterRounding = 500000000000000008; // BigMath round up at borrow leads to minor difference
|
|
|
|
uint256 totalBorrow = (((defaultBorrowAmountAfterRounding * borrowExchangePrice) /
|
|
EXCHANGE_PRICES_PRECISION) - DEFAULT_PAYBACK_AMOUNT);
|
|
assertEq(totalBorrow, 238750000000000008);
|
|
uint256 totalBorrowRawInterest = ((totalBorrow * EXCHANGE_PRICES_PRECISION) / borrowExchangePrice) + 1; // should be 0.221577726218097455 +1 for round up
|
|
assertEq(totalBorrowRawInterest, 221577726218097456);
|
|
|
|
totalSupplyRawInterest =
|
|
DEFAULT_SUPPLY_AMOUNT - // previous supply raw
|
|
((DEFAULT_WITHDRAW_AMOUNT * EXCHANGE_PRICES_PRECISION) / supplyExchangePrice); // new supply adjusted to raw
|
|
assertEq(totalSupplyRawInterest, 518652226233453671);
|
|
|
|
uint256 totalSupply = ((DEFAULT_SUPPLY_AMOUNT * supplyExchangePrice) / EXCHANGE_PRICES_PRECISION) -
|
|
DEFAULT_WITHDRAW_AMOUNT;
|
|
assertEq(totalSupply, 538750000000000000); // 1 ether * 1038750000000 - 0.5 ether
|
|
|
|
totalAmounts = _simulateTotalAmounts(totalSupplyRawInterest, 0, totalBorrowRawInterest, 0);
|
|
|
|
userBorrowData = _simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
totalBorrowRawInterest, // taking interest on borrow amount until payback into account
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
);
|
|
|
|
// utilization AFTER payback
|
|
uint256 utilization = (totalBorrow * FOUR_DECIMALS) / totalSupply; // results in 44,31554 %
|
|
assertEq(utilization, 4431);
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(address(USDC)),
|
|
utilization
|
|
);
|
|
assertEq(borrowRate, 732); // expected borrow rate at ~44,31% utilization
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
address(USDC),
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
_setTestOperateParams(
|
|
address(USDC),
|
|
-int256(DEFAULT_WITHDRAW_AMOUNT),
|
|
-int256(DEFAULT_PAYBACK_AMOUNT),
|
|
alice,
|
|
alice,
|
|
address(0),
|
|
totalAmounts,
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
_simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
totalSupplyRawInterest,
|
|
0, // previous limit
|
|
block.timestamp
|
|
),
|
|
userBorrowData,
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
contract LiquidityUserModuleWithdrawAndPaybackTestSuiteInterestFree is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
_setUserAllowancesDefaultInterestFree(address(liquidity), admin, address(USDC), address(mockProtocol));
|
|
|
|
// alice supplies USDC liquidity
|
|
_supply(mockProtocol, address(USDC), alice, DEFAULT_SUPPLY_AMOUNT);
|
|
|
|
// alice borrows USDC liquidity
|
|
_borrow(mockProtocol, address(USDC), alice, DEFAULT_BORROW_AMOUNT);
|
|
|
|
// simulate passing time 1 year to get a better predicatable borrow rate and amounts
|
|
vm.warp(block.timestamp + PASS_1YEAR_TIME);
|
|
|
|
// exchange prices are not changing because of interest free mode
|
|
uint256 supplyExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
uint256 borrowExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
|
|
uint256 totalAmounts;
|
|
uint256 totalSupply = DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT;
|
|
uint256 exchangePricesAndConfig;
|
|
{
|
|
uint256 defaultBorrowAmountAfterRounding = 500000000000000008; // BigMath round up at borrow leads to minor difference
|
|
uint256 totalBorrow = defaultBorrowAmountAfterRounding - DEFAULT_PAYBACK_AMOUNT;
|
|
totalAmounts = _simulateTotalAmounts(0, totalSupply, 0, totalBorrow);
|
|
|
|
// utilization AFTER payback
|
|
uint256 utilization = (totalBorrow * FOUR_DECIMALS) / totalSupply; // results in 40%
|
|
assertEq(utilization, 4000);
|
|
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(address(USDC)),
|
|
utilization
|
|
);
|
|
assertEq(borrowRate, 700); // expected borrow rate at 40% utilization
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
address(USDC),
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
1, // supplyRatio = 1 for mode set to total supply with interest < interest free
|
|
1 // borrowRatio = 1 for mode set to total supply with interest < interest free
|
|
);
|
|
}
|
|
|
|
uint256 userSupplyData = _simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
totalSupply,
|
|
0, // previous limit
|
|
block.timestamp
|
|
);
|
|
|
|
_setTestOperateParams(
|
|
address(USDC),
|
|
-int256(DEFAULT_WITHDRAW_AMOUNT),
|
|
-int256(DEFAULT_PAYBACK_AMOUNT),
|
|
alice,
|
|
alice,
|
|
address(0),
|
|
totalAmounts,
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
userSupplyData,
|
|
_simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
address(USDC),
|
|
DEFAULT_BORROW_AMOUNT_AFTER_BIGMATH - DEFAULT_PAYBACK_AMOUNT,
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
contract LiquidityUserModuleWithdrawAndPaybackTestSuiteNative is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
// alice supplies liquidity
|
|
_supplyNative(mockProtocol, alice, DEFAULT_SUPPLY_AMOUNT);
|
|
|
|
// alice borrows liquidity
|
|
_borrowNative(mockProtocol, alice, DEFAULT_BORROW_AMOUNT);
|
|
|
|
// simulate passing time 1 year to get a better predicatable borrow rate and amounts
|
|
vm.warp(block.timestamp + PASS_1YEAR_TIME);
|
|
|
|
uint256 supplyExchangePrice = 1038750000000; // increased half of 7.75% -> 3.875% (because half of supply is borrowed out)
|
|
uint256 borrowExchangePrice = 1077500000000; // increased 7.75%
|
|
|
|
uint256 totalAmounts;
|
|
uint256 userBorrowData;
|
|
uint256 exchangePricesAndConfig;
|
|
uint256 totalSupplyRawInterest;
|
|
{
|
|
uint256 defaultBorrowAmountAfterRounding = 500000000000000008; // BigMath round up at borrow leads to minor difference
|
|
|
|
uint256 totalBorrow = (((defaultBorrowAmountAfterRounding * borrowExchangePrice) /
|
|
EXCHANGE_PRICES_PRECISION) - DEFAULT_PAYBACK_AMOUNT);
|
|
assertEq(totalBorrow, 238750000000000008);
|
|
uint256 totalBorrowRawInterest = ((totalBorrow * EXCHANGE_PRICES_PRECISION) / borrowExchangePrice) + 1; // should be 0.221577726218097455 +1 for round up
|
|
assertEq(totalBorrowRawInterest, 221577726218097456);
|
|
|
|
totalSupplyRawInterest =
|
|
DEFAULT_SUPPLY_AMOUNT - // previous supply raw
|
|
((DEFAULT_WITHDRAW_AMOUNT * EXCHANGE_PRICES_PRECISION) / supplyExchangePrice); // new supply adjusted to raw
|
|
assertEq(totalSupplyRawInterest, 518652226233453671);
|
|
|
|
uint256 totalSupply = ((DEFAULT_SUPPLY_AMOUNT * supplyExchangePrice) / EXCHANGE_PRICES_PRECISION) -
|
|
DEFAULT_WITHDRAW_AMOUNT;
|
|
assertEq(totalSupply, 538750000000000000); // 1 ether * 1038750000000 - 0.5 ether
|
|
|
|
totalAmounts = _simulateTotalAmounts(totalSupplyRawInterest, 0, totalBorrowRawInterest, 0);
|
|
|
|
userBorrowData = _simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
totalBorrowRawInterest, // taking interest on borrow amount until payback into account
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
);
|
|
|
|
// utilization AFTER payback
|
|
uint256 utilization = (totalBorrow * FOUR_DECIMALS) / totalSupply; // results in 44,31554 %
|
|
assertEq(utilization, 4431);
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(NATIVE_TOKEN_ADDRESS),
|
|
utilization
|
|
);
|
|
assertEq(borrowRate, 732); // expected borrow rate at ~44,31% utilization
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
NATIVE_TOKEN_ADDRESS,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
_setTestOperateParams(
|
|
NATIVE_TOKEN_ADDRESS,
|
|
-int256(DEFAULT_WITHDRAW_AMOUNT),
|
|
-int256(DEFAULT_PAYBACK_AMOUNT),
|
|
alice,
|
|
alice,
|
|
address(0),
|
|
totalAmounts,
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
_simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
totalSupplyRawInterest,
|
|
0, // previous limit
|
|
block.timestamp
|
|
),
|
|
userBorrowData,
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
contract LiquidityUserModuleWithdrawAndPaybackTestSuiteInterestFreeNative is LiquidityUserModuleOperateTestSuite {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
_setUserAllowancesDefaultInterestFree(address(liquidity), admin, NATIVE_TOKEN_ADDRESS, address(mockProtocol));
|
|
|
|
// alice supplies liquidity
|
|
_supplyNative(mockProtocol, alice, DEFAULT_SUPPLY_AMOUNT);
|
|
|
|
// alice borrows liquidity
|
|
_borrowNative(mockProtocol, alice, DEFAULT_BORROW_AMOUNT);
|
|
|
|
// simulate passing time 1 year to get a better predicatable borrow rate and amounts
|
|
vm.warp(block.timestamp + PASS_1YEAR_TIME);
|
|
|
|
// exchange prices are not changing because of interest free mode
|
|
uint256 supplyExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
uint256 borrowExchangePrice = EXCHANGE_PRICES_PRECISION;
|
|
|
|
uint256 totalAmounts;
|
|
uint256 totalSupply = DEFAULT_SUPPLY_AMOUNT - DEFAULT_WITHDRAW_AMOUNT;
|
|
uint256 exchangePricesAndConfig;
|
|
{
|
|
uint256 defaultBorrowAmountAfterRounding = 500000000000000008; // BigMath round up at borrow leads to minor difference
|
|
uint256 totalBorrow = defaultBorrowAmountAfterRounding - DEFAULT_PAYBACK_AMOUNT;
|
|
totalAmounts = _simulateTotalAmounts(0, totalSupply, 0, totalBorrow);
|
|
|
|
// utilization AFTER payback
|
|
uint256 utilization = (totalBorrow * FOUR_DECIMALS) / totalSupply; // results in 40%
|
|
assertEq(utilization, 4000);
|
|
|
|
uint256 borrowRate = LiquidityCalcs.calcBorrowRateFromUtilization(
|
|
resolver.getRateConfig(NATIVE_TOKEN_ADDRESS),
|
|
utilization
|
|
);
|
|
assertEq(borrowRate, 700); // expected borrow rate at 40% utilization
|
|
exchangePricesAndConfig = _simulateExchangePricesWithRatesAndRatios(
|
|
resolver,
|
|
NATIVE_TOKEN_ADDRESS,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
utilization,
|
|
borrowRate,
|
|
block.timestamp,
|
|
1, // supplyRatio = 1 for mode set to total supply with interest < interest free
|
|
1 // borrowRatio = 1 for mode set to total supply with interest < interest free
|
|
);
|
|
}
|
|
|
|
uint256 userSupplyData = _simulateUserSupplyData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
totalSupply,
|
|
0, // previous limit
|
|
block.timestamp
|
|
);
|
|
|
|
_setTestOperateParams(
|
|
NATIVE_TOKEN_ADDRESS,
|
|
-int256(DEFAULT_WITHDRAW_AMOUNT),
|
|
-int256(DEFAULT_PAYBACK_AMOUNT),
|
|
alice,
|
|
alice,
|
|
address(0),
|
|
totalAmounts,
|
|
exchangePricesAndConfig,
|
|
supplyExchangePrice,
|
|
borrowExchangePrice,
|
|
userSupplyData,
|
|
_simulateUserBorrowData(
|
|
resolver,
|
|
address(mockProtocol),
|
|
NATIVE_TOKEN_ADDRESS,
|
|
DEFAULT_BORROW_AMOUNT_AFTER_BIGMATH - DEFAULT_PAYBACK_AMOUNT,
|
|
DEFAULT_BASE_DEBT_CEILING_AFTER_BIGMATH, // base borrow limit will be set as previous limit
|
|
block.timestamp
|
|
),
|
|
true
|
|
);
|
|
}
|
|
}
|