Skip to content

Commit

Permalink
Fix pausing functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
haydenshively committed Sep 11, 2023
1 parent 1793b06 commit f58a4f8
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 153 deletions.
26 changes: 13 additions & 13 deletions core/.gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
BorrowerGasTest:test_addMargin() (gas: 16203)
BorrowerGasTest:test_borrow() (gas: 110577)
BorrowerGasTest:test_borrow() (gas: 110553)
BorrowerGasTest:test_getUniswapPositions() (gas: 5219)
BorrowerGasTest:test_modify() (gas: 82174)
BorrowerGasTest:test_modifyWithAnte() (gas: 88629)
BorrowerGasTest:test_repay() (gas: 111936)
BorrowerGasTest:test_uniswapDepositInBorrower() (gas: 257789)
BorrowerGasTest:test_modify() (gas: 82150)
BorrowerGasTest:test_modifyWithAnte() (gas: 88605)
BorrowerGasTest:test_repay() (gas: 65205)
BorrowerGasTest:test_uniswapDepositInBorrower() (gas: 257762)
BorrowerGasTest:test_uniswapDepositStandard() (gas: 167558)
BorrowerGasTest:test_uniswapWithdraw() (gas: 147673)
BorrowerGasTest:test_withdraw() (gas: 105694)
BorrowerGasTest:test_uniswapWithdraw() (gas: 147654)
BorrowerGasTest:test_withdraw() (gas: 105670)
FactoryGasTest:test_createBorrower() (gas: 156519)
FactoryGasTest:test_createMarket() (gas: 3904606)
FactoryGasTest:test_createMarket() (gas: 3879742)
LenderGasTest:test_accrueInterest() (gas: 46070)
LenderGasTest:test_borrow() (gas: 40834)
LenderGasTest:test_deposit() (gas: 53422)
LenderGasTest:test_depositWithCourier() (gas: 53568)
LenderGasTest:test_redeem() (gas: 53114)
LenderGasTest:test_redeemWithCourier() (gas: 83506)
LenderGasTest:test_repay() (gas: 44774)
LiquidatorGasTest:test_noCallbackOneAsset() (gas: 51105)
LiquidatorGasTest:test_noCallbackTwoAssets() (gas: 59286)
LiquidatorGasTest:test_noCallbackTwoAssetsAndUniswapPosition() (gas: 95684)
LiquidatorGasTest:test_warn() (gas: 35089)
LiquidatorGasTest:test_withCallbackAndSwap() (gas: 130270)
LiquidatorGasTest:test_noCallbackOneAsset() (gas: 51108)
LiquidatorGasTest:test_noCallbackTwoAssets() (gas: 59289)
LiquidatorGasTest:test_noCallbackTwoAssetsAndUniswapPosition() (gas: 95669)
LiquidatorGasTest:test_warn() (gas: 35092)
LiquidatorGasTest:test_withCallbackAndSwap() (gas: 130273)
VolatilityGasTest:test_consult() (gas: 43075)
VolatilityGasTest:test_updateNoBinarySearch() (gas: 145902)
33 changes: 18 additions & 15 deletions core/src/Borrower.sol
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ contract Borrower is IUniswapV3MintCallback {

{
// Fetch prices from oracle
Prices memory prices = getPrices(oracleSeed);
(Prices memory prices, ) = getPrices(oracleSeed);
// Tally assets without actually withdrawing Uniswap positions
Assets memory assets = _getAssets(positions.read(), prices, false);
// Fetch liabilities from lenders
Expand Down Expand Up @@ -188,7 +188,7 @@ contract Borrower is IUniswapV3MintCallback {
_saveSlot0(slot0_, _formatted(State.Locked));

// Fetch prices from oracle
Prices memory prices = getPrices(oracleSeed);
(Prices memory prices, ) = getPrices(oracleSeed);

uint256 liabilities0;
uint256 liabilities1;
Expand Down Expand Up @@ -295,21 +295,21 @@ contract Borrower is IUniswapV3MintCallback {
int24[] memory positions_ = positions.write(callee.callback(data, msg.sender));
_saveSlot0(uint160(msg.sender), _formatted(State.Ready));

(uint256 ante, uint256 nSigma, uint256 pausedUntilTime) = FACTORY.getParameters(UNISWAP_POOL);

(Prices memory prices, bool isSus) = _getPrices(nSigma, oracleSeed);
Assets memory assets = _getAssets(positions_, prices, false);
(uint256 liabilities0, uint256 liabilities1) = _getLiabilities();

require(BalanceSheet.isHealthy(prices, assets, liabilities0, liabilities1), "Aloe: unhealthy");
unchecked {
if (liabilities0 + liabilities1 > 0)
if (liabilities0 + liabilities1 > 0) {
(uint256 ante, uint256 nSigma, uint256 pausedUntilTime) = FACTORY.getParameters(UNISWAP_POOL);
(Prices memory prices, bool seemsLegit) = _getPrices(oracleSeed, nSigma);

require(
address(this).balance > ante && !isSus && block.timestamp > pausedUntilTime,
seemsLegit && (block.timestamp > pausedUntilTime) && (address(this).balance >= ante),
"Aloe: missing ante / sus price"
);

Assets memory assets = _getAssets(positions_, prices, false);
require(BalanceSheet.isHealthy(prices, assets, liabilities0, liabilities1), "Aloe: unhealthy");
}
}
if (isSus) FACTORY.pause(UNISWAP_POOL);
}

/*//////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -439,18 +439,21 @@ contract Borrower is IUniswapV3MintCallback {
return positions.read();
}

function getPrices(uint40 oracleSeed) public view returns (Prices memory prices) {
function getPrices(uint40 oracleSeed) public view returns (Prices memory prices, bool seemsLegit) {
(, uint256 nSigma, ) = FACTORY.getParameters(UNISWAP_POOL);
(prices, ) = _getPrices(nSigma, oracleSeed);
(prices, seemsLegit) = _getPrices(oracleSeed, nSigma);
}

function _getPrices(uint256 nSigma, uint40 oracleSeed) private view returns (Prices memory prices, bool isSus) {
function _getPrices(
uint40 oracleSeed,
uint256 nSigma
) private view returns (Prices memory prices, bool seemsLegit) {
uint56 metric;
uint256 iv;
// compute current price and volatility
(metric, prices.c, iv) = ORACLE.consult(UNISWAP_POOL, oracleSeed);
// compute prices at which solvency will be checked
(prices.a, prices.b, isSus) = BalanceSheet.computeProbePrices(prices.c, iv, nSigma, metric);
(prices.a, prices.b, seemsLegit) = BalanceSheet.computeProbePrices(prices.c, iv, nSigma, metric);
}

function _getAssets(
Expand Down
6 changes: 4 additions & 2 deletions core/src/Factory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,10 @@ contract Factory {
DEFAULT_RATE_MODEL = defaultRateModel;
}

function pause(IUniswapV3Pool pool) external {
require(isBorrower[msg.sender]);
function pause(IUniswapV3Pool pool, uint40 oracleSeed) external {
(, bool seemsLegit) = getMarket[pool].borrowerImplementation.getPrices(oracleSeed);
if (seemsLegit) return;

unchecked {
getParameters[pool].pausedUntilTime = uint32(block.timestamp) + UNISWAP_AVG_WINDOW;
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/libraries/BalanceSheet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ library BalanceSheet {
uint256 iv,
uint256 nSigma,
uint56 metric
) internal pure returns (uint160 a, uint160 b, bool isSus) {
) internal pure returns (uint160 a, uint160 b, bool seemsLegit) {
unchecked {
iv = SoladyMath.clamp((nSigma * iv) / 10, PROBE_PERCENT_MIN, PROBE_PERCENT_MAX);
isSus = metric > _manipulationThreshold(_effectiveCollateralFactor(iv));
seemsLegit = metric < _manipulationThreshold(_effectiveCollateralFactor(iv));

a = uint160((sqrtMeanPriceX96 * SoladyMath.sqrt(1e12 - iv)) / 1e6);
b = uint160(SoladyMath.min((sqrtMeanPriceX96 * SoladyMath.sqrt(1e12 + iv)) / 1e6, type(uint160).max));
Expand Down
14 changes: 7 additions & 7 deletions core/test/Liquidator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ contract LiquidatorTest is Test, IManager, ILiquidator {
vm.expectRevert();
account.liquidate(this, bytes(""), 0, (1 << 32));

Prices memory prices = account.getPrices((1 << 32));
(Prices memory prices, ) = account.getPrices(1 << 32);
uint256 price = Math.mulDiv(prices.c, prices.c, Q96);
uint256 incentive1 = Math.mulDiv(debt / LIQUIDATION_INCENTIVE, price, Q96);
uint256 assets1 = Math.mulDiv(debt / strain, price, Q96) + incentive1 / strain;
Expand Down Expand Up @@ -299,7 +299,7 @@ contract LiquidatorTest is Test, IManager, ILiquidator {
uint160(address(this)) + (1 << 160)
)));

Prices memory prices = account.getPrices((1 << 32));
(Prices memory prices, ) = account.getPrices(1 << 32);
uint256 price = Math.mulDiv(prices.c, prices.c, Q96);
uint256 incentive1 = Math.mulDiv(debt / LIQUIDATION_INCENTIVE, price, Q96);
uint256 assets1 = Math.mulDiv(debt / strain, price, Q96) + incentive1 / strain;
Expand All @@ -317,7 +317,7 @@ contract LiquidatorTest is Test, IManager, ILiquidator {
// These tests are forked, so we don't want to spam the RPC with too many fuzzing values
strain = (strain % 8) + 1;

Prices memory prices = account.getPrices((1 << 32));
(Prices memory prices,) = account.getPrices(1 << 32);
uint256 borrow1 = 1e18 * ((scale % 4) + 1); // Same concern here
{
uint256 effectiveLiabilities1 = borrow1 + borrow1 / 200 + borrow1 / 20;
Expand Down Expand Up @@ -369,7 +369,7 @@ contract LiquidatorTest is Test, IManager, ILiquidator {
function test_spec_priceTriggerRepayDAIUsingSwap() public {
uint256 strain = 1;

Prices memory prices = account.getPrices((1 << 32));
(Prices memory prices, ) = account.getPrices(1 << 32);
uint256 borrow0 = 1000e18;
{
uint256 effectiveLiabilities0 = borrow0 + borrow0 / 200;
Expand Down Expand Up @@ -418,7 +418,7 @@ contract LiquidatorTest is Test, IManager, ILiquidator {
uint160(address(this)) + (1 << 160)
)));

prices = account.getPrices((1 << 32));
(prices, ) = account.getPrices(1 << 32);

uint256 price = Math.mulDiv(prices.c, prices.c, Q96);
uint256 assets1 = Math.mulDiv(borrow0 / strain, price, Q96);
Expand All @@ -435,7 +435,7 @@ contract LiquidatorTest is Test, IManager, ILiquidator {
function test_warnDoesProtect() public {
uint256 strain = 1;

Prices memory prices = account.getPrices((1 << 32));
(Prices memory prices, ) = account.getPrices(1 << 32);
uint256 borrow0 = 1000e18;
{
uint256 effectiveLiabilities0 = borrow0 + borrow0 / 200;
Expand Down Expand Up @@ -489,7 +489,7 @@ contract LiquidatorTest is Test, IManager, ILiquidator {

skip(1);

prices = account.getPrices((1 << 32));
(prices, ) = account.getPrices(1 << 32);

uint256 price = Math.mulDiv(prices.c, prices.c, Q96);
uint256 assets1 = Math.mulDiv(borrow0 / strain, price, Q96);
Expand Down
5 changes: 0 additions & 5 deletions core/test/Utils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ import {Lender} from "src/Lender.sol";
import {RateModel} from "src/RateModel.sol";
import {VolatilityOracle} from "src/VolatilityOracle.sol";

function deploySingleBorrower(IUniswapV3Pool pool, Lender lender0, Lender lender1) returns (Borrower) {
address oracleMock = address(new VolatilityOracleMock());
return new Borrower(VolatilityOracle(oracleMock), pool, lender0, lender1);
}

contract FactoryForLenderTests is Factory {
constructor(
RateModel rateModel,
Expand Down
Loading

0 comments on commit f58a4f8

Please sign in to comment.