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

Commit 1818293

Browse files
authored
Merge branch 'ionicprotocol:development' into feat/adrastia-prudentia-caps
2 parents a933e35 + d7a7826 commit 1818293

File tree

67 files changed

+10325
-8256
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+10325
-8256
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ node_modules/
1515
ionic-contracts.iml
1616
cache_hardhat
1717
transactions.json
18+
*transactions.json
19+
deployments/local

chainDeploy/helpers/logging.ts

+79-18
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,94 @@
1+
import { encodeFunctionData } from "viem"; // Adjust the import path according to your project structure
12
import { promises as fs } from "fs";
23

4+
interface PrepareAndLogTransactionParams {
5+
contractInstance: any; // Replace `any` with the correct contract type if available
6+
functionName: string;
7+
args: any[];
8+
description: string;
9+
inputs: {
10+
internalType: string;
11+
name: string;
12+
type: string;
13+
}[];
14+
}
15+
316
export const logTransaction = (description: string, data: string) => {
417
console.log(`Transaction: ${description}`);
518
console.log(`Data: ${data}`);
619
};
720

821
const transactions: any[] = [];
922

10-
export const addTransaction = (tx: any) => {
23+
export const addTransaction = async (tx: any) => {
1124
transactions.push(tx);
25+
await writeSingleTransactionToFile(tx);
26+
};
27+
28+
const writeSingleTransactionToFile = async (tx: any) => {
29+
const filePath = "./transactions.json";
30+
try {
31+
let batch;
32+
try {
33+
const fileContent = await fs.readFile(filePath, "utf8");
34+
batch = JSON.parse(fileContent);
35+
} catch (error) {
36+
if (error.code === "ENOENT" || error.message === "Unexpected end of JSON input") {
37+
batch = {
38+
version: "1.0",
39+
chainId: "34443",
40+
createdAt: Math.floor(Date.now() / 1000),
41+
meta: {
42+
name: "Transactions Batch",
43+
description: "",
44+
txBuilderVersion: "1.16.5",
45+
createdFromSafeAddress: "0x8Fba84867Ba458E7c6E2c024D2DE3d0b5C3ea1C2",
46+
createdFromOwnerAddress: "",
47+
checksum: "0x"
48+
},
49+
transactions: []
50+
};
51+
} else {
52+
throw error;
53+
}
54+
}
55+
56+
batch.transactions.push(tx);
57+
58+
await fs.writeFile(filePath, JSON.stringify(batch, null, 2));
59+
console.log(`Transaction added and written to ${filePath}`);
60+
} catch (error) {
61+
console.error(`Failed to write transaction to ${filePath}`, error);
62+
}
1263
};
1364

14-
export const writeTransactionsToFile = async () => {
15-
const batch = {
16-
version: "1.0",
17-
chainId: "34443",
18-
createdAt: Math.floor(Date.now() / 1000),
19-
meta: {
20-
name: "Transactions Batch",
21-
description: "",
22-
txBuilderVersion: "1.16.5",
23-
createdFromSafeAddress: "0x8Fba84867Ba458E7c6E2c024D2DE3d0b5C3ea1C2",
24-
createdFromOwnerAddress: "",
25-
checksum: "0x"
65+
export const prepareAndLogTransaction = async ({
66+
contractInstance,
67+
functionName,
68+
args,
69+
description,
70+
inputs
71+
}: PrepareAndLogTransactionParams) => {
72+
const data = encodeFunctionData({
73+
abi: contractInstance.abi,
74+
functionName,
75+
args
76+
});
77+
78+
await addTransaction({
79+
to: contractInstance.address,
80+
value: "0",
81+
data,
82+
contractMethod: {
83+
inputs,
84+
name: functionName,
85+
payable: false
2686
},
27-
transactions
28-
};
87+
contractInputsValues: args.reduce((acc: any, arg: any, index: number) => {
88+
acc[inputs[index].name] = arg;
89+
return acc;
90+
}, {})
91+
});
2992

30-
const filePath = "./transactions.json";
31-
await fs.writeFile(filePath, JSON.stringify(batch, null, 2));
32-
console.log(`Transactions written to ${filePath}`);
93+
logTransaction(description, data);
3394
};

chains/base/params.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,16 @@ const specificParams: ChainParams = {
1313
img: "https://icons.llamao.fi/icons/chains/rsz_base.jpg",
1414
blockExplorerUrls: { default: { name: "basescan", url: "https://basescan.org/" } },
1515
rpcUrls: {
16-
default: { http: ["https://mainnet.base.org"] },
16+
default: {
17+
http: [
18+
"https://mainnet.base.org",
19+
"https://base.llamarpc.com",
20+
"https://base-rpc.publicnode.com",
21+
"https://gateway.tenderly.co/public/base",
22+
"https://base.meowrpc.com",
23+
"https://base-mainnet.public.blastapi.io"
24+
]
25+
},
1726
public: { http: ["https://mainnet.base.org"] }
1827
},
1928
nativeCurrency: {

chains/mode/params.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const specificParams: ChainParams = {
1212
img: "https://1430441113-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmOUA87dDndFyiETJjxpf%2Ficon%2FzSRXk7tkG8rWFi6tG9wV%2FIYXD4bdy_400x400.jpg?alt=media",
1313
blockExplorerUrls: { default: { name: "modeexplorer", url: "https://explorer.mode.network" } },
1414
rpcUrls: {
15-
default: { http: ["https://mainnet.mode.network/"] },
15+
default: { http: ["https://mainnet.mode.network/", "https://1rpc.io/mode", "https://mode.drpc.org"] },
1616
public: { http: ["https://mainnet.mode.network/"] }
1717
},
1818
nativeCurrency: {

contracts/compound/CToken.sol

+15-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { InterestRateModel } from "./InterestRateModel.sol";
1010
import { ComptrollerV3Storage } from "./ComptrollerStorage.sol";
1111
import { IFeeDistributor } from "./IFeeDistributor.sol";
1212
import { DiamondExtension, LibDiamond } from "../ionic/DiamondExtension.sol";
13+
import { PoolLens } from "../PoolLens.sol";
14+
import { IonicUniV3Liquidator } from "../IonicUniV3Liquidator.sol";
1315

1416
/**
1517
* @title Compound's CErc20 Contract
@@ -26,6 +28,18 @@ abstract contract CErc20 is CTokenSecondExtensionBase, TokenErrorReporter, Expon
2628
_;
2729
}
2830

31+
modifier isMinHFThresholdExceeded(address borrower) {
32+
PoolLens lens = PoolLens(ap.getAddress("PoolLens"));
33+
IonicUniV3Liquidator liquidator = IonicUniV3Liquidator(payable(ap.getAddress("IonicUniV3Liquidator")));
34+
35+
if (lens.getHealthFactor(borrower, comptroller) > liquidator.healthFactorThreshold()) {
36+
require(msg.sender == address(liquidator), "Health factor not low enough for non-permissioned liquidations");
37+
_;
38+
} else {
39+
_;
40+
}
41+
}
42+
2943
function _getExtensionFunctions() public pure virtual override returns (bytes4[] memory) {
3044
uint8 fnsCount = 13;
3145
bytes4[] memory functionSelectors = new bytes4[](fnsCount);
@@ -122,7 +136,7 @@ abstract contract CErc20 is CTokenSecondExtensionBase, TokenErrorReporter, Expon
122136
address borrower,
123137
uint256 repayAmount,
124138
address cTokenCollateral
125-
) external override isAuthorized returns (uint256) {
139+
) external override isAuthorized isMinHFThresholdExceeded(borrower) returns (uint256) {
126140
(uint256 err, ) = liquidateBorrowInternal(borrower, repayAmount, cTokenCollateral);
127141
return err;
128142
}

contracts/compound/CTokenFirstExtension.sol

+11-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import { Multicall } from "../utils/Multicall.sol";
1313

1414
import { IERC20, SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
1515

16+
import { AddressesProvider } from "../ionic/AddressesProvider.sol";
17+
1618
contract CTokenFirstExtension is
1719
CErc20FirstExtensionBase,
1820
TokenErrorReporter,
@@ -29,7 +31,7 @@ contract CTokenFirstExtension is
2931
}
3032

3133
function _getExtensionFunctions() external pure virtual override returns (bytes4[] memory) {
32-
uint8 fnsCount = 24;
34+
uint8 fnsCount = 25;
3335
bytes4[] memory functionSelectors = new bytes4[](fnsCount);
3436
functionSelectors[--fnsCount] = this.transfer.selector;
3537
functionSelectors[--fnsCount] = this.transferFrom.selector;
@@ -39,6 +41,7 @@ contract CTokenFirstExtension is
3941
functionSelectors[--fnsCount] = this._setAdminFee.selector;
4042
functionSelectors[--fnsCount] = this._setInterestRateModel.selector;
4143
functionSelectors[--fnsCount] = this._setNameAndSymbol.selector;
44+
functionSelectors[--fnsCount] = this._setAddressesProvider.selector;
4245
functionSelectors[--fnsCount] = this._setReserveFactor.selector;
4346
functionSelectors[--fnsCount] = this.supplyRatePerBlock.selector;
4447
functionSelectors[--fnsCount] = this.borrowRatePerBlock.selector;
@@ -219,6 +222,13 @@ contract CTokenFirstExtension is
219222
symbol = _symbol;
220223
}
221224

225+
function _setAddressesProvider(address _ap) external {
226+
// Check caller is admin
227+
require(hasAdminRights(), "!admin");
228+
229+
ap = AddressesProvider(_ap);
230+
}
231+
222232
/**
223233
* @notice accrues interest and sets a new reserve factor for the protocol using _setReserveFactorFresh
224234
* @dev Admin function to accrue interest and set a new reserve factor

contracts/compound/CTokenInterfaces.sol

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pragma solidity >=0.8.0;
44
import { IonicComptroller } from "./ComptrollerInterface.sol";
55
import { InterestRateModel } from "./InterestRateModel.sol";
66
import { ComptrollerV3Storage } from "./ComptrollerStorage.sol";
7+
import { AddressesProvider } from "../ionic/AddressesProvider.sol";
78

89
abstract contract CTokenAdminStorage {
910
/*
@@ -147,6 +148,11 @@ abstract contract CErc20Storage is CTokenAdminStorage {
147148
* @notice Underlying asset for this CToken
148149
*/
149150
address public underlying;
151+
152+
/**
153+
* @notice Addresses Provider
154+
*/
155+
AddressesProvider public ap;
150156
}
151157

152158
abstract contract CTokenBaseEvents {

contracts/ionic/strategies/IonicERC4626.sol

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ abstract contract IonicERC4626 is SafeOwnableUpgradeable, PausableUpgradeable, E
3131

3232
/* ========== INITIALIZER ========== */
3333

34-
function __MidasER4626_init(ERC20Upgradeable asset_) internal onlyInitializing {
34+
function __IonicER4626_init(ERC20Upgradeable asset_) internal onlyInitializing {
3535
__SafeOwnable_init(msg.sender);
3636
__Pausable_init();
3737
__Context_init();
3838
__ERC20_init(
39-
string(abi.encodePacked("Midas ", asset_.name(), " Vault")),
39+
string(abi.encodePacked("Ionic ", asset_.name(), " Vault")),
4040
string(abi.encodePacked("mv", asset_.symbol()))
4141
);
4242
__ERC4626_init(asset_);

contracts/ionic/strategies/MockERC4626Dynamic.sol

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ERC20 } from "solmate/tokens/ERC20.sol";
55

66
import { ERC4626 } from "solmate/mixins/ERC4626.sol";
77
import { FixedPointMathLib } from "solmate/utils/FixedPointMathLib.sol";
8-
import { FlywheelCore } from "flywheel-v2/FlywheelCore.sol";
8+
import { IonicFlywheelCore } from "./flywheel/IonicFlywheelCore.sol";
99

1010
/**
1111
* @title Mock ERC4626 Contract
@@ -17,7 +17,7 @@ contract MockERC4626Dynamic is ERC4626 {
1717
using FixedPointMathLib for uint256;
1818

1919
/* ========== STATE VARIABLES ========== */
20-
FlywheelCore public immutable flywheel;
20+
IonicFlywheelCore public immutable flywheel;
2121

2222
/* ========== INITIALIZER ========== */
2323

@@ -26,7 +26,7 @@ contract MockERC4626Dynamic is ERC4626 {
2626
@param _asset The ERC20 compliant token the Vault should accept.
2727
@param _flywheel Flywheel to pull in rewardsToken
2828
*/
29-
constructor(ERC20 _asset, FlywheelCore _flywheel)
29+
constructor(ERC20 _asset, IonicFlywheelCore _flywheel)
3030
ERC4626(
3131
_asset,
3232
string(abi.encodePacked("Midas ", _asset.name(), " Vault")),

0 commit comments

Comments
 (0)