Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion deployments/dev/534352/deployments.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"WormholeModule": "0x96F7C99AeBb38Ccc0Df091F1aD2b8f91ADBA2FCd",
"BeHYPEStakeModule": "0x89EFb0DB949f25E131239b5B41c3Ed5aFaeaaA35",
"EtherFiLiquidModuleWithReferrer": "0xEBC674Ec6c5968bB52Ee3F02C2a6F9Efd4ffa10d",
"LiquidUSDLiquifierModule": "0x1ca1349695E2584EBa01273Fd1EF9D0FffFBc852"
"LiquidUSDLiquifierModule": "0x1ca1349695E2584EBa01273Fd1EF9D0FffFBc852",
"MidasModule": "0xaF5d9AC2725Fdc1Be506347fe163Feac66D7Fdf4"
}
}
3 changes: 2 additions & 1 deletion deployments/mainnet/534352/deployments.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"WormholeModule": "0x96bae80F91DA04a59CeF9dCE3bB1081De041C1d5",
"BeHYPEStakeModule": "0x51142BC586A7b4cbECDCD5B0C68064714B322CBC",
"EtherFiLiquidModuleWithReferrer": "0x5BdD4b0D644c0A573E0eb526aB7D7d332AAaa50e",
"LiquidUSDLiquifierModule": "0x23C4dc847Cd876D4ca2C15b4a1EAD349dC705082"
"LiquidUSDLiquifierModule": "0x23C4dc847Cd876D4ca2C15b4a1EAD349dC705082",
"MidasModule": "0xEE3Fb6914105BA01196ab26191C3BB7448016467"
}
}
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ base = "${BASE_RPC}"
mainnet = { key = "${ETHERSCAN_KEY}" }
scroll = { key = "${ETHERSCAN_KEY}" }
base = { key = "${ETHERSCAN_KEY}" }
hyperevm = { key = "${MAINNET_ETHERSCAN_KEY}", chain = 999 }
hyperevm = { key = "${ETHERSCAN_KEY}", chain = 999 }



Expand Down
34 changes: 34 additions & 0 deletions output/SetMidasConfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"chainId": "534352",
"safeAddress": "0xa6cf33124cb342d1c604cac87986b965f428aac4",
"meta": {
"txBuilderVersion": "1.16.5"
},
"transactions": [
{
"to": "0xdc515cb479a64552c5a11a57109c314e40a1a778",
"value": "0",
"data": "0x54ddbe26000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ee3fb6914105ba01196ab26191c3bb744801646700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001"
},
{
"to": "0x44dd2372fe7b97c4b4d6a7d4decf72466485bacb",
"value": "0",
"data": "0x90883ac5000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000b7fb3768caac98354eadf514b48f28f2fe822bf000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b2a4ec4c9b95d7a87ba3989d0fd38dffdd944a24000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000007e90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
},
{
"to": "0x0078c5a459132e279056b2371fe8a8ec973a9553",
"value": "0",
"data": "0xe5dbbeeb000000000000000000000000b7fb3768caac98354eadf514b48f28f2fe822bf0000000000000000000000000000000000000000000000004563918244f400000000000000000000000000000000000000000000000000004e1003b28d92800000000000000000000000000000000000000000000000000001bc16d674ec80000"
},
{
"to": "0x0078c5a459132e279056b2371fe8a8ec973a9553",
"value": "0",
"data": "0x36394bd1000000000000000000000000b7fb3768caac98354eadf514b48f28f2fe822bf0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000ffffffffffffffffffffffffffffffff"
},
{
"to": "0x7ca0b75e67e33c0014325b739a8d019c4fe445f0",
"value": "0",
"data": "0xd74286f5000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000b7fb3768caac98354eadf514b48f28f2fe822bf000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001"
}
]
}
6 changes: 6 additions & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
forge-std/=lib/forge-std/src/
openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/
openzeppelin-contracts/=lib/openzeppelin-contracts/
solady/=lib/solady/src/
110 changes: 110 additions & 0 deletions scripts/DeployMidasModule.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import { stdJson } from "forge-std/StdJson.sol";

import { EtherFiDataProvider } from "../src/data-provider/EtherFiDataProvider.sol";
import { ICashModule } from "../src/interfaces/ICashModule.sol";
import { IDebtManager } from "../src/interfaces/IDebtManager.sol";
import { MidasModule } from "../src/modules/midas/MidasModule.sol";
import { IAggregatorV3, PriceProvider } from "../src/oracle/PriceProvider.sol";
import { ChainConfig, Utils } from "./utils/Utils.sol";

contract DeployMidasModule is Utils {
address midasToken = 0xb7Fb3768CAAC98354EaDF514b48f28F2fE822bF0;
address usdc = 0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4;
address usdt = 0xf55BEC9cafDbE8730f096Aa55dad6D22d44099Df;

address depositVault = 0xcA1C871f8ae2571Cb126A46861fc06cB9E645152;
address redemptionVault = 0x904EA8d7FcaB7351758fAC82bDbc738E2010BC25;

address midasPriceOracle = 0xB2a4eC4C9b95D7a87bA3989d0FD38dFfDd944A24;

IDebtManager debtManager;
PriceProvider priceProvider;
ICashModule cashModule;
address dataProvider;

function run() public {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");

vm.startBroadcast(deployerPrivateKey);

string memory deployments = readDeploymentFile();
dataProvider = stdJson.readAddress(deployments, string(abi.encodePacked(".", "addresses", ".", "EtherFiDataProvider")));

priceProvider = PriceProvider(stdJson.readAddress(deployments, string.concat(".", "addresses", ".", "PriceProvider")));

debtManager = IDebtManager(stdJson.readAddress(deployments, string.concat(".", "addresses", ".", "DebtManager")));

cashModule = ICashModule(stdJson.readAddress(deployments, string.concat(".", "addresses", ".", "CashModule")));

// Prepare arrays for Midas module deployment
address[] memory midasTokens = new address[](1);
midasTokens[0] = midasToken;

address[] memory depositVaults = new address[](1);
depositVaults[0] = depositVault;

address[] memory redemptionVaults = new address[](1);
redemptionVaults[0] = redemptionVault;

//deploy Midas module
MidasModule midasModule = new MidasModule(
dataProvider,
midasTokens,
depositVaults,
redemptionVaults
);

address[] memory defaultModules = new address[](1);
defaultModules[0] = address(midasModule);

bool[] memory shouldWhitelist = new bool[](1);
shouldWhitelist[0] = true;

//configure default module in data provider
EtherFiDataProvider(dataProvider).configureDefaultModules(defaultModules, shouldWhitelist);

address[] memory tokens = new address[](1);
tokens[0] = midasToken;

PriceProvider.Config memory midasConfig = PriceProvider.Config({
oracle: midasPriceOracle,
priceFunctionCalldata: "",
isChainlinkType: true, //chainlink type oracle
oraclePriceDecimals: IAggregatorV3(midasPriceOracle).decimals(),
maxStaleness: 30 days,
dataType: PriceProvider.ReturnType.Int256,
isBaseTokenEth: false,
isStableToken: true,
isBaseTokenBtc: false
});
PriceProvider.Config[] memory midasConfigs = new PriceProvider.Config[](1);
midasConfigs[0] = midasConfig;

//price provider set oracle
PriceProvider(priceProvider).setTokenConfig(tokens, midasConfigs);

IDebtManager.CollateralTokenConfig memory collateralConfig = IDebtManager.CollateralTokenConfig({
ltv: 90e18,
liquidationThreshold: 95e18,
liquidationBonus: 1e18 //confirmed with team
});

uint64 borrowApy = 1; // ~0%
uint128 minShares = type(uint128).max; // Since we dont want to use it in borrow mode

//debt manager set collateral and borrow config
debtManager.supportCollateralToken(address(midasToken), collateralConfig);
debtManager.supportBorrowToken(address(midasToken), borrowApy, minShares);

address[] memory withdrawableAssets = new address[](1);
withdrawableAssets[0] = address(midasToken);

//cash module set withdrawable asset
ICashModule(cashModule).configureWithdrawAssets(withdrawableAssets, shouldWhitelist);

vm.stopBroadcast();
}
}
36 changes: 36 additions & 0 deletions scripts/gnosis-txs/DeployMidasModule.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import { stdJson } from "forge-std/StdJson.sol";

import { MidasModule } from "../../src/modules/midas/MidasModule.sol";
import { Utils } from "../utils/Utils.sol";

contract DeployMidasModule is Utils {
address midasToken = 0xb7Fb3768CAAC98354EaDF514b48f28F2fE822bF0;
address depositVault = 0xcA1C871f8ae2571Cb126A46861fc06cB9E645152;
address redemptionVault = 0x904EA8d7FcaB7351758fAC82bDbc738E2010BC25;

function run() public {
string memory deployments = readDeploymentFile();

address dataProvider = stdJson.readAddress(deployments, string(abi.encodePacked(".", "addresses", ".", "EtherFiDataProvider")));

vm.startBroadcast();

// Prepare arrays for Midas module deployment
address[] memory midasTokens = new address[](1);
midasTokens[0] = midasToken;

address[] memory depositVaults = new address[](1);
depositVaults[0] = depositVault;

address[] memory redemptionVaults = new address[](1);
redemptionVaults[0] = redemptionVault;

// Deploy Midas module
MidasModule midasModule = new MidasModule(dataProvider, midasTokens, depositVaults, redemptionVaults);

vm.stopBroadcast();
}
}
108 changes: 108 additions & 0 deletions scripts/gnosis-txs/SetMidasConfig.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import { stdJson } from "forge-std/StdJson.sol";
import { Test } from "forge-std/Test.sol";

import { EtherFiDataProvider } from "../../src/data-provider/EtherFiDataProvider.sol";
import { ICashModule } from "../../src/interfaces/ICashModule.sol";
import { IDebtManager } from "../../src/interfaces/IDebtManager.sol";
import { IAggregatorV3, PriceProvider } from "../../src/oracle/PriceProvider.sol";
import { GnosisHelpers } from "../utils/GnosisHelpers.sol";
import { Utils } from "../utils/Utils.sol";

contract SetMidasConfig is GnosisHelpers, Utils, Test {
address cashControllerSafe = 0xA6cf33124cb342D1c604cAC87986B965F428AAC4;

address midasToken = 0xb7Fb3768CAAC98354EaDF514b48f28F2fE822bF0;
address midasPriceOracle = 0xB2a4eC4C9b95D7a87bA3989d0FD38dFfDd944A24;

// Set this to the deployed MidasModule address after deployment
// If the address is in the deployments file under "MidasModule", it will be read automatically
address midasModule = 0xEE3Fb6914105BA01196ab26191C3BB7448016467;

IDebtManager debtManager;
PriceProvider priceProvider;
ICashModule cashModule;
address dataProvider;

function run() public {
string memory chainId = vm.toString(block.chainid);
string memory deployments = readDeploymentFile();

dataProvider = stdJson.readAddress(deployments, string(abi.encodePacked(".", "addresses", ".", "EtherFiDataProvider")));

priceProvider = PriceProvider(stdJson.readAddress(deployments, string.concat(".", "addresses", ".", "PriceProvider")));

debtManager = IDebtManager(stdJson.readAddress(deployments, string.concat(".", "addresses", ".", "DebtManager")));

cashModule = ICashModule(stdJson.readAddress(deployments, string.concat(".", "addresses", ".", "CashModule")));

// Generate Gnosis transactions
string memory txs = _getGnosisHeader(chainId, addressToHex(cashControllerSafe));

// Configure default module in data provider
address[] memory defaultModules = new address[](1);
defaultModules[0] = midasModule;

bool[] memory shouldWhitelist = new bool[](1);
shouldWhitelist[0] = true;

string memory configureDefaultModules = iToHex(abi.encodeWithSelector(EtherFiDataProvider.configureDefaultModules.selector, defaultModules, shouldWhitelist));
txs = string(abi.encodePacked(txs, _getGnosisTransaction(addressToHex(dataProvider), configureDefaultModules, "0", false)));

// Set price provider config
address[] memory tokens = new address[](1);
tokens[0] = midasToken;

PriceProvider.Config memory midasConfig = PriceProvider.Config({
oracle: midasPriceOracle,
priceFunctionCalldata: "",
isChainlinkType: true, // chainlink type oracle
oraclePriceDecimals: IAggregatorV3(midasPriceOracle).decimals(),
maxStaleness: 6 days,
dataType: PriceProvider.ReturnType.Int256,
isBaseTokenEth: false,
isStableToken: false,
isBaseTokenBtc: false
});
PriceProvider.Config[] memory midasConfigs = new PriceProvider.Config[](1);
midasConfigs[0] = midasConfig;

string memory setTokenConfig = iToHex(abi.encodeWithSelector(PriceProvider.setTokenConfig.selector, tokens, midasConfigs));
txs = string(abi.encodePacked(txs, _getGnosisTransaction(addressToHex(address(priceProvider)), setTokenConfig, "0", false)));

// Set collateral and borrow config in debt manager
IDebtManager.CollateralTokenConfig memory collateralConfig = IDebtManager.CollateralTokenConfig({
ltv: 80e18,
liquidationThreshold: 90e18,
liquidationBonus: 2e18 // same as liquid USD
});

uint64 borrowApy = 1; // ~0%
uint128 minShares = type(uint128).max; // Since we dont want to use it in borrow mode

string memory supportCollateralToken = iToHex(abi.encodeWithSelector(IDebtManager.supportCollateralToken.selector, midasToken, collateralConfig));
txs = string(abi.encodePacked(txs, _getGnosisTransaction(addressToHex(address(debtManager)), supportCollateralToken, "0", false)));

string memory supportBorrowToken = iToHex(abi.encodeWithSelector(IDebtManager.supportBorrowToken.selector, midasToken, borrowApy, minShares));
txs = string(abi.encodePacked(txs, _getGnosisTransaction(addressToHex(address(debtManager)), supportBorrowToken, "0", false)));

// Configure withdrawable assets in cash module
address[] memory withdrawableAssets = new address[](1);
withdrawableAssets[0] = midasToken;

string memory configureWithdrawAssets = iToHex(abi.encodeWithSelector(ICashModule.configureWithdrawAssets.selector, withdrawableAssets, shouldWhitelist));
txs = string(abi.encodePacked(txs, _getGnosisTransaction(addressToHex(address(cashModule)), configureWithdrawAssets, "0", true)));

vm.createDir("./output", true);
string memory path = "./output/SetMidasConfig.json";
vm.writeFile(path, txs);

// Test execution
executeGnosisTransactionBundle(path);

assert(EtherFiDataProvider(dataProvider).isDefaultModule(midasModule) == true);
assert(IDebtManager(debtManager).isCollateralToken(midasToken) == true);
}
}
41 changes: 41 additions & 0 deletions src/interfaces/IMidasVault.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

interface IMidasVault {
/**
* @notice depositing proccess with auto mint if
* account fit daily limit and token allowance.
* Transfers token from the user.
* Transfers fee in tokenIn to feeReceiver.
* Mints mToken to user.
* @param tokenIn address of tokenIn
* @param amountToken amount of `tokenIn` that will be taken from user (decimals 18)
* @param minReceiveAmount minimum expected amount of mToken to receive (decimals 18)
* @param referrerId referrer id
*/
function depositInstant(address tokenIn, uint256 amountToken, uint256 minReceiveAmount, bytes32 referrerId) external;

/**
* @notice redeem mToken to tokenOut if daily limit and allowance not exceeded
* Burns mToken from the user.
* Transfers fee in mToken to feeReceiver
* Transfers tokenOut to user.
* @param tokenOut stable coin token address to redeem to
* @param amountMTokenIn amount of mToken to redeem (decimals 18)
* @param minReceiveAmount minimum expected amount of tokenOut to receive (decimals 18)
*/
function redeemInstant(address tokenOut, uint256 amountMTokenIn, uint256 minReceiveAmount) external;

/**
* @notice creating redeem request if tokenOut not fiat
* Transfers amount in mToken to contract
* Transfers fee in mToken to feeReceiver
* @param tokenOut stable coin token address to redeem to
* @param amountMTokenIn amount of mToken to redeem (decimals 18)
* @param recipient address to receive the redeemed tokens
* @return request id
*/
function redeemRequest(address tokenOut, uint256 amountMTokenIn, address recipient) external returns (uint256);
}
Loading