Skip to content
This repository was archived by the owner on Aug 26, 2024. It is now read-only.

Commit 76513ac

Browse files
authored
Merge pull request #90 from ionicprotocol/fix/always-permission-per
Fix/always permission per
2 parents 0ac137c + f2fd736 commit 76513ac

27 files changed

+4552
-3081
lines changed

.gitmodules

+16-22
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,24 @@
11
[submodule "lib/forge-std"]
2-
path = lib/forge-std
3-
url = https://github.com/brockelmore/forge-std
2+
path = lib/forge-std
3+
url = https://github.com/brockelmore/forge-std
44
[submodule "lib/openzeppelin-contracts-upgradeable"]
5-
path = lib/openzeppelin-contracts-upgradeable
6-
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
5+
path = lib/openzeppelin-contracts-upgradeable
6+
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
77
[submodule "lib/solmate"]
8-
path = lib/solmate
9-
url = https://github.com/rari-capital/solmate
10-
[submodule "lib/fuse-flywheel"]
11-
path = lib/fuse-flywheel
12-
url = https://github.com/fei-protocol/fuse-flywheel
8+
path = lib/solmate
9+
url = https://github.com/rari-capital/solmate
1310
[submodule "lib/openzeppelin-contracts"]
14-
path = lib/openzeppelin-contracts
15-
url = https://github.com/OpenZeppelin/openzeppelin-contracts
11+
path = lib/openzeppelin-contracts
12+
url = https://github.com/OpenZeppelin/openzeppelin-contracts
1613
[submodule "lib/pyth-sdk-solidity"]
17-
path = lib/pyth-sdk-solidity
18-
url = https://github.com/pyth-network/pyth-sdk-solidity
14+
path = lib/pyth-sdk-solidity
15+
url = https://github.com/pyth-network/pyth-sdk-solidity
1916
[submodule "lib/solidity-bytes-utils"]
20-
path = lib/solidity-bytes-utils
21-
url = https://github.com/GNSPS/solidity-bytes-utils
17+
path = lib/solidity-bytes-utils
18+
url = https://github.com/GNSPS/solidity-bytes-utils
2219
[submodule "lib/ops"]
23-
path = lib/ops
24-
url = https://github.com/gelatodigital/ops
20+
path = lib/ops
21+
url = https://github.com/gelatodigital/ops
2522
[submodule "lib/adrastia-periphery"]
26-
path = lib/adrastia-periphery
27-
url = https://github.com/adrastia-oracle/adrastia-periphery
28-
[submodule "lib/flywheel-v2"]
29-
path = lib/flywheel-v2
30-
url = https://github.com/ionicprotocol/flywheel-v2
23+
path = lib/adrastia-periphery
24+
url = https://github.com/adrastia-oracle/adrastia-periphery

chainDeploy/helpers/liquidators/ionicLiquidator.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ export const deployIonicUniV3Liquidator = async ({
8080
args: [deployConfig.wtoken, deployConfig.uniswap.uniswapV3Quoter]
8181
}
8282
},
83-
proxyContract: "OpenZeppelinTransparentProxy",
84-
owner: multisig
83+
proxyContract: "OpenZeppelinTransparentProxy"
8584
}
8685
});
8786
if (uniV3Liquidator.transactionHash)

contracts/IonicLiquidator.sol

+26-7
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,9 @@ contract IonicLiquidator is OwnableUpgradeable, ILiquidator, IUniswapV2Callee, I
8484
*/
8585
uint256 public healthFactorThreshold;
8686

87-
modifier onlyPERPermissioned(address borrower, ICErc20 cToken) {
87+
modifier onlyLowHF(address borrower, ICErc20 cToken) {
8888
uint256 currentHealthFactor = lens.getHealthFactor(borrower, cToken.comptroller());
89-
if (currentHealthFactor > healthFactorThreshold) {
90-
require(expressRelay.isPermissioned(address(this), abi.encode(borrower)), "invalid liquidation");
91-
}
89+
require(currentHealthFactor < healthFactorThreshold, "HF not low enough, reserving for PYTH");
9290
_;
9391
}
9492

@@ -141,13 +139,13 @@ contract IonicLiquidator is OwnableUpgradeable, ILiquidator, IUniswapV2Callee, I
141139
* @param cTokenCollateral The cToken collateral to be liquidated.
142140
* @param minOutputAmount The minimum amount of collateral to seize (or the minimum exchange output if applicable) required for execution. Reverts if this condition is not met.
143141
*/
144-
function safeLiquidate(
142+
function _safeLiquidate(
145143
address borrower,
146144
uint256 repayAmount,
147145
ICErc20 cErc20,
148146
ICErc20 cTokenCollateral,
149147
uint256 minOutputAmount
150-
) external onlyPERPermissioned(borrower, cTokenCollateral) returns (uint256) {
148+
) internal returns (uint256) {
151149
// Transfer tokens in, approve to cErc20, and liquidate borrow
152150
require(repayAmount > 0, "Repay amount (transaction value) must be greater than 0.");
153151
IERC20Upgradeable underlying = IERC20Upgradeable(cErc20.underlying());
@@ -164,6 +162,27 @@ contract IonicLiquidator is OwnableUpgradeable, ILiquidator, IUniswapV2Callee, I
164162
return transferSeizedFunds(address(cTokenCollateral.underlying()), minOutputAmount);
165163
}
166164

165+
function safeLiquidate(
166+
address borrower,
167+
uint256 repayAmount,
168+
ICErc20 cErc20,
169+
ICErc20 cTokenCollateral,
170+
uint256 minOutputAmount
171+
) external onlyLowHF(borrower, cTokenCollateral) returns (uint256) {
172+
return _safeLiquidate(borrower, repayAmount, cErc20, cTokenCollateral, minOutputAmount);
173+
}
174+
175+
function safeLiquidatePyth(
176+
address borrower,
177+
uint256 repayAmount,
178+
ICErc20 cErc20,
179+
ICErc20 cTokenCollateral,
180+
uint256 minOutputAmount
181+
) external returns (uint256) {
182+
require(expressRelay.isPermissioned(address(this), abi.encode(borrower)), "invalid liquidation");
183+
return _safeLiquidate(borrower, repayAmount, cErc20, cTokenCollateral, minOutputAmount);
184+
}
185+
167186
/**
168187
* @dev Transfers seized funds to the sender.
169188
* @param erc20Contract The address of the token to transfer.
@@ -184,7 +203,7 @@ contract IonicLiquidator is OwnableUpgradeable, ILiquidator, IUniswapV2Callee, I
184203
*/
185204
function safeLiquidateToTokensWithFlashLoan(LiquidateToTokensWithFlashSwapVars calldata vars)
186205
external
187-
onlyPERPermissioned(vars.borrower, vars.cTokenCollateral)
206+
onlyLowHF(vars.borrower, vars.cTokenCollateral)
188207
returns (uint256)
189208
{
190209
// Input validation

contracts/IonicUniV3Liquidator.sol

+26-7
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,9 @@ contract IonicUniV3Liquidator is OwnableUpgradeable, ILiquidator, IUniswapV3Flas
6666
*/
6767
uint256 public healthFactorThreshold;
6868

69-
modifier onlyPERPermissioned(address borrower, ICErc20 cToken) {
69+
modifier onlyLowHF(address borrower, ICErc20 cToken) {
7070
uint256 currentHealthFactor = lens.getHealthFactor(borrower, cToken.comptroller());
71-
if (currentHealthFactor > healthFactorThreshold) {
72-
require(expressRelay.isPermissioned(address(this), abi.encode(borrower)), "invalid liquidation");
73-
}
71+
require(currentHealthFactor < healthFactorThreshold, "HF not low enough, reserving for PYTH");
7472
_;
7573
}
7674

@@ -88,13 +86,13 @@ contract IonicUniV3Liquidator is OwnableUpgradeable, ILiquidator, IUniswapV3Flas
8886
* @param cTokenCollateral The cToken collateral to be liquidated.
8987
* @param minOutputAmount The minimum amount of collateral to seize (or the minimum exchange output if applicable) required for execution. Reverts if this condition is not met.
9088
*/
91-
function safeLiquidate(
89+
function _safeLiquidate(
9290
address borrower,
9391
uint256 repayAmount,
9492
ICErc20 cErc20,
9593
ICErc20 cTokenCollateral,
9694
uint256 minOutputAmount
97-
) external onlyPERPermissioned(borrower, cTokenCollateral) returns (uint256) {
95+
) internal returns (uint256) {
9896
// Transfer tokens in, approve to cErc20, and liquidate borrow
9997
require(repayAmount > 0, "Repay amount (transaction value) must be greater than 0.");
10098
IERC20Upgradeable underlying = IERC20Upgradeable(cErc20.underlying());
@@ -111,6 +109,27 @@ contract IonicUniV3Liquidator is OwnableUpgradeable, ILiquidator, IUniswapV3Flas
111109
return transferSeizedFunds(address(cTokenCollateral.underlying()), minOutputAmount);
112110
}
113111

112+
function safeLiquidate(
113+
address borrower,
114+
uint256 repayAmount,
115+
ICErc20 cErc20,
116+
ICErc20 cTokenCollateral,
117+
uint256 minOutputAmount
118+
) external onlyLowHF(borrower, cTokenCollateral) returns (uint256) {
119+
return _safeLiquidate(borrower, repayAmount, cErc20, cTokenCollateral, minOutputAmount);
120+
}
121+
122+
function safeLiquidatePyth(
123+
address borrower,
124+
uint256 repayAmount,
125+
ICErc20 cErc20,
126+
ICErc20 cTokenCollateral,
127+
uint256 minOutputAmount
128+
) external returns (uint256) {
129+
require(expressRelay.isPermissioned(address(this), abi.encode(borrower)), "invalid liquidation");
130+
return _safeLiquidate(borrower, repayAmount, cErc20, cTokenCollateral, minOutputAmount);
131+
}
132+
114133
/**
115134
* @dev Transfers seized funds to the sender.
116135
* @param erc20Contract The address of the token to transfer.
@@ -127,7 +146,7 @@ contract IonicUniV3Liquidator is OwnableUpgradeable, ILiquidator, IUniswapV3Flas
127146

128147
function safeLiquidateToTokensWithFlashLoan(LiquidateToTokensWithFlashSwapVars calldata vars)
129148
external
130-
onlyPERPermissioned(vars.borrower, vars.cTokenCollateral)
149+
onlyLowHF(vars.borrower, vars.cTokenCollateral)
131150
returns (uint256)
132151
{
133152
// Input validation

contracts/ionic/strategies/flywheel/LooplessFlywheelBooster.sol

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
// SPDX-License-Identifier: AGPL-3.0-only
22
pragma solidity ^0.8.10;
33

4-
import "./IFlywheelBooster.sol";
4+
import {IFlywheelBooster} from "./IFlywheelBooster.sol";
55
import { ICErc20 } from "../../../compound/CTokenInterfaces.sol";
6+
import {ERC20} from "solmate/tokens/ERC20.sol";
67

78
contract LooplessFlywheelBooster is IFlywheelBooster {
89
string public constant BOOSTER_TYPE = "LooplessFlywheelBooster";

contracts/ionic/strategies/flywheel/rewards/FlywheelDynamicRewards.sol

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// SPDX-License-Identifier: AGPL-3.0-only
22
pragma solidity ^0.8.10;
33

4-
import "./BaseFlywheelRewards.sol";
4+
import {BaseFlywheelRewards} from "./BaseFlywheelRewards.sol";
5+
import {IonicFlywheelCore} from "../IonicFlywheelCore.sol";
6+
import {SafeTransferLib, ERC20} from "solmate/utils/SafeTransferLib.sol";
57
import {SafeCastLib} from "solmate/utils/SafeCastLib.sol";
68

79
/**

contracts/ionic/strategies/flywheel/rewards/FlywheelStaticRewards.sol

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
pragma solidity ^0.8.10;
33

44
import {Auth, Authority} from "solmate/auth/Auth.sol";
5-
import "./BaseFlywheelRewards.sol";
5+
import {BaseFlywheelRewards} from "./BaseFlywheelRewards.sol";
6+
import {ERC20} from "solmate/utils/SafeTransferLib.sol";
7+
import {IonicFlywheelCore} from "../IonicFlywheelCore.sol";
68

79
/**
810
@title Flywheel Static Reward Stream

contracts/ionic/strategies/flywheel/rewards/IonicFlywheelDynamicRewardsPlugin.sol

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ interface ICERC20 {
77
function plugin() external returns (address);
88
}
99

10-
interface IPlugin {
10+
interface IPlugin_FDR {
1111
function claimRewards() external;
1212
}
1313

@@ -28,7 +28,7 @@ contract IonicFlywheelDynamicRewardsPlugin is FlywheelDynamicRewards {
2828
override
2929
returns (uint192)
3030
{
31-
IPlugin plugin = IPlugin(ICERC20(address(strategy)).plugin());
31+
IPlugin_FDR plugin = IPlugin_FDR(ICERC20(address(strategy)).plugin());
3232
try plugin.claimRewards() {} catch {}
3333

3434
uint256 rewardAmount = rewardToken.balanceOf(address(strategy));

contracts/ionic/strategies/flywheel/rewards/ReplacingFlywheelDynamicRewards.sol

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
pragma solidity ^0.8.10;
33

44
import { FlywheelDynamicRewards } from "./FlywheelDynamicRewards.sol";
5-
import { BaseFlywheelRewards } from "./BaseFlywheelRewards.sol";
65
import { IonicFlywheelCore } from "../IonicFlywheelCore.sol";
76
import { Auth, Authority } from "solmate/auth/Auth.sol";
87
import { SafeTransferLib, ERC20 } from "solmate/utils/SafeTransferLib.sol";

contracts/ionic/strategies/flywheel/rewards/ReplacingFlywheelStaticRewards.sol

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
pragma solidity ^0.8.10;
33

44
import { FlywheelStaticRewards } from "./FlywheelStaticRewards.sol";
5-
import { BaseFlywheelRewards } from "./BaseFlywheelRewards.sol";
65
import { IonicFlywheelCore } from "../IonicFlywheelCore.sol";
76
import { Auth, Authority } from "solmate/auth/Auth.sol";
87
import { SafeTransferLib, ERC20 } from "solmate/utils/SafeTransferLib.sol";

contracts/ionic/strategies/flywheel/rewards/WithdrawableFlywheelStaticRewards.sol

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
pragma solidity ^0.8.10;
33

44
import { FlywheelStaticRewards } from "./FlywheelStaticRewards.sol";
5-
import { BaseFlywheelRewards } from "./BaseFlywheelRewards.sol";
65
import { IonicFlywheelCore } from "../IonicFlywheelCore.sol";
76
import { Auth, Authority } from "solmate/auth/Auth.sol";
87
import { SafeTransferLib, ERC20 } from "solmate/utils/SafeTransferLib.sol";

contracts/test/DeployMarkets.t.sol

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { ERC20 } from "solmate/tokens/ERC20.sol";
77
import { Auth, Authority } from "solmate/auth/Auth.sol";
88
import { MockERC20 } from "solmate/test/utils/mocks/MockERC20.sol";
99
import { IonicFlywheelDynamicRewardsPlugin } from "../ionic/strategies/flywheel/rewards/IonicFlywheelDynamicRewardsPlugin.sol";
10-
import { FlywheelCore } from "flywheel/FlywheelCore.sol";
1110
import { IFlywheelBooster } from "../ionic/strategies/flywheel/IFlywheelBooster.sol";
1211
import { IFlywheelRewards } from "../ionic/strategies/flywheel/rewards/IFlywheelRewards.sol";
1312
import { TransparentUpgradeableProxy } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";

0 commit comments

Comments
 (0)