Skip to content

Commit

Permalink
Merge pull request #35 from OasisDEX/jt/sc-15286/dma-sc-dma-v2-ify-mo…
Browse files Browse the repository at this point in the history
…rphoblue-actions-contracts

feat: DMA V2-ify Morpho actions
  • Loading branch information
zerotucks authored Apr 30, 2024
2 parents 0154434 + aeb70cb commit 82ec556
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 128 deletions.
15 changes: 7 additions & 8 deletions packages/dma-contracts/contracts/actions/morpho-blue/Borrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,29 @@
pragma solidity ^0.8.15;

import { Executable } from "../common/Executable.sol";
import { Write, UseStore } from "../common/UseStore.sol";
import { OperationStorage } from "../../core/OperationStorage.sol";
import { UseStorageSlot, StorageSlot, Write, Read } from "../../libs/UseStorageSlot.sol";
import { ServiceRegistry } from "../../core/ServiceRegistry.sol";
import { BorrowData } from "../../core/types/MorphoBlue.sol";
import { MORPHO_BLUE } from "../../core/constants/MorphoBlue.sol";
import { IMorpho } from "../../interfaces/morpho-blue/IMorpho.sol";
import { UseRegistry } from "../../libs/UseRegistry.sol";

/**
* @title Borrow | Morpho Blue Action contract
* @notice Borrows token from MorphoBlue's lending pool
*/
contract MorphoBlueBorrow is Executable, UseStore {
using Write for OperationStorage;
contract MorphoBlueBorrow is Executable, UseStorageSlot, UseRegistry {
using Write for StorageSlot.TransactionStorage;

constructor(address _registry) UseStore(_registry) {}
constructor(address _registry) UseRegistry(ServiceRegistry(_registry)) {}

/**
* @dev Look at UseStore.sol to get additional info on paramsMapping
*
* @param data Encoded calldata that conforms to the BorrowData struct
*/
function execute(bytes calldata data, uint8[] memory) external payable override {
BorrowData memory borrowData = parseInputs(data);

IMorpho morphoBlue = IMorpho(registry.getRegisteredService(MORPHO_BLUE));
IMorpho morphoBlue = IMorpho(getRegisteredService(MORPHO_BLUE));
morphoBlue.borrow(borrowData.marketParams, borrowData.amount, 0, address(this), address(this));

store().write(bytes32(borrowData.amount));
Expand Down
24 changes: 11 additions & 13 deletions packages/dma-contracts/contracts/actions/morpho-blue/Deposit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,24 @@
pragma solidity ^0.8.15;

import { Executable } from "../common/Executable.sol";
import { UseStore, Write, Read } from "../common/UseStore.sol";
import { OperationStorage } from "../../core/OperationStorage.sol";
import { UseStorageSlot, StorageSlot, Write, Read } from "../../libs/UseStorageSlot.sol";
import { ServiceRegistry } from "../../core/ServiceRegistry.sol";
import { DepositData } from "../../core/types/MorphoBlue.sol";
import { MORPHO_BLUE } from "../../core/constants/MorphoBlue.sol";
import { IMorpho } from "../../interfaces/morpho-blue/IMorpho.sol";
import { UseRegistry } from "../../libs/UseRegistry.sol";

/**
* @title Deposit | Morpho Blue Action contract
* @notice Deposits the specified asset as collateral on MorphoBlue's lending pool
*/
contract MorphoBlueDeposit is Executable, UseStore {
using Write for OperationStorage;
using Read for OperationStorage;
contract MorphoBlueDeposit is Executable, UseStorageSlot, UseRegistry {
using Write for StorageSlot.TransactionStorage;
using Read for StorageSlot.TransactionStorage;

constructor(address _registry) UseStore(_registry) {}
constructor(address _registry) UseRegistry(ServiceRegistry(_registry)) {}

/**
* @dev Look at UseStore.sol to get additional info on paramsMapping
*
* @param data Encoded calldata that conforms to the DepositData struct
* @param paramsMap Maps operation storage values by index (index offset by +1) to execute calldata params
*/
Expand All @@ -29,15 +28,14 @@ contract MorphoBlueDeposit is Executable, UseStore {

uint256 mappedDepositAmount = store().readUint(
bytes32(depositData.amount),
paramsMap[1],
address(this)
paramsMap[1]
);

uint256 actualDepositAmount = depositData.sumAmounts
? mappedDepositAmount + depositData.amount
: mappedDepositAmount;
? mappedDepositAmount + depositData.amount
: mappedDepositAmount;

IMorpho morphoBlue = IMorpho(registry.getRegisteredService(MORPHO_BLUE));
IMorpho morphoBlue = IMorpho(getRegisteredService(MORPHO_BLUE));
morphoBlue.supplyCollateral(
depositData.marketParams,
actualDepositAmount,
Expand Down
47 changes: 35 additions & 12 deletions packages/dma-contracts/contracts/actions/morpho-blue/Payback.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,60 @@
pragma solidity ^0.8.15;

import { Executable } from "../common/Executable.sol";
import { UseStore, Write, Read } from "../common/UseStore.sol";
import { OperationStorage } from "../../core/OperationStorage.sol";
import { UseStorageSlot, StorageSlot, Write, Read } from "../../libs/UseStorageSlot.sol";
import { ServiceRegistry } from "../../core/ServiceRegistry.sol";
import { PaybackData } from "../../core/types/MorphoBlue.sol";
import { MORPHO_BLUE } from "../../core/constants/MorphoBlue.sol";
import { IMorpho } from "../../interfaces/morpho-blue/IMorpho.sol";
import { Id, IMorpho, MarketParams } from "../../interfaces/morpho-blue/IMorpho.sol";
import { MarketParamsLib } from "../../libs/morpho-blue/MarketParamsLib.sol";
import { MorphoLib } from "../../libs/morpho-blue/MorphoLib.sol";
import { SharesMathLib } from "../../libs/morpho-blue/SharesMathLib.sol";
import { UseRegistry } from "../../libs/UseRegistry.sol";

/**
* @title Payback | MorphoBlue Action contract
* @notice Pays back a specified amount to Morpho Blue's lending pool
*/
contract MorphoBluePayback is Executable, UseStore {
using Write for OperationStorage;
using Read for OperationStorage;
contract MorphoBluePayback is Executable, UseStorageSlot, UseRegistry {
using Write for StorageSlot.TransactionStorage;
using Read for StorageSlot.TransactionStorage;
using MarketParamsLib for MarketParams;
using MorphoLib for IMorpho;
using SharesMathLib for uint256;

constructor(address _registry) UseStore(_registry) {}
constructor(address _registry) UseRegistry(ServiceRegistry(_registry)) {}

/**
* @dev Look at UseStore.sol to get additional info on paramsMapping.
*
* @param data Encoded calldata that conforms to the PaybackData struct
* @param paramsMap Maps operation storage values by index (index offset by +1) to execute calldata params
*/
function execute(bytes calldata data, uint8[] memory paramsMap) external payable override {
PaybackData memory paybackData = parseInputs(data);

paybackData.amount = store().readUint(bytes32(paybackData.amount), paramsMap[0], address(this));
paybackData.amount = store().readUint(bytes32(paybackData.amount), paramsMap[0]);

IMorpho morphoBlue = IMorpho(registry.getRegisteredService(MORPHO_BLUE));
IMorpho morphoBlue = IMorpho(getRegisteredService(MORPHO_BLUE));

address onBehalf = paybackData.onBehalf == address(0) ? address(this) : paybackData.onBehalf;
morphoBlue.repay(paybackData.marketParams, paybackData.amount, 0, onBehalf, bytes(""));

if (paybackData.paybackAll) {
Id id = paybackData.marketParams.id();

// Need to call accrueInterest to get the latest snapshot of the shares/asset ratio
morphoBlue.accrueInterest(paybackData.marketParams);

uint256 totalBorrowAssets = morphoBlue.totalBorrowAssets(id);
uint256 totalBorrowShares = morphoBlue.totalBorrowShares(id);
uint256 shares = morphoBlue.borrowShares(id, onBehalf);
uint256 assetsMax = shares.toAssetsUp(totalBorrowAssets, totalBorrowShares);

require(paybackData.amount >= assetsMax, "MorphoBluePayback: payback amount too low");
paybackData.amount = assetsMax;

morphoBlue.repay(paybackData.marketParams, 0, shares, onBehalf, bytes(""));
} else {
morphoBlue.repay(paybackData.marketParams, paybackData.amount, 0, onBehalf, bytes(""));
}

store().write(bytes32(paybackData.amount));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,30 @@
pragma solidity ^0.8.15;

import { Executable } from "../common/Executable.sol";
import { UseStore, Write } from "../common/UseStore.sol";
import { OperationStorage } from "../../core/OperationStorage.sol";
import { UseStorageSlot, StorageSlot, Write, Read } from "../../libs/UseStorageSlot.sol";
import { ServiceRegistry } from "../../core/ServiceRegistry.sol";
import { WithdrawData } from "../../core/types/MorphoBlue.sol";
import { MORPHO_BLUE } from "../../core/constants/MorphoBlue.sol";
import { IMorpho } from "../../interfaces/morpho-blue/IMorpho.sol";
import { UseRegistry } from "../../libs/UseRegistry.sol";

/**
* @title Withdraw | MorphoBlue Action contract
* @notice Withdraw collateral from Morpho Blue's lending pool
* with the amount to withdraw being read from the proxies t/x storage slot
*/
contract MorphoBlueWithdraw is Executable, UseStore {
using Write for OperationStorage;
contract MorphoBlueWithdraw is Executable, UseStorageSlot, UseRegistry {
using Write for StorageSlot.TransactionStorage;

constructor(address _registry) UseStore(_registry) {}
constructor(address _registry) UseRegistry(ServiceRegistry(_registry)) {}

/**
* @param data Encoded calldata that conforms to the WithdrawData struct
*/
function execute(bytes calldata data, uint8[] memory) external payable override {
WithdrawData memory withdrawData = parseInputs(data);

IMorpho morphoBlue = IMorpho(registry.getRegisteredService(MORPHO_BLUE));
IMorpho morphoBlue = IMorpho(getRegisteredService(MORPHO_BLUE));
morphoBlue.withdrawCollateral(
withdrawData.marketParams,
withdrawData.amount,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.15;

import { Executable } from "../common/Executable.sol";
import { UseStorageSlot, StorageSlot, Write, Read } from "../../libs/UseStorageSlot.sol";
import { ServiceRegistry } from "../../core/ServiceRegistry.sol";
import { WithdrawData } from "../../core/types/MorphoBlue.sol";
import { MORPHO_BLUE } from "../../core/constants/MorphoBlue.sol";
import { IMorpho } from "../../interfaces/morpho-blue/IMorpho.sol";
import { UseRegistry } from "../../libs/UseRegistry.sol";

/**
* @title Withdraw | MorphoBlue Action contract
* @notice Withdraw collateral from Morpho Blue's lending pool
* with the amount to withdraw being read from an OperationStorage slot
*/
contract MorphoBlueWithdrawAuto is Executable, UseStorageSlot, UseRegistry {
using Write for StorageSlot.TransactionStorage;
using Read for StorageSlot.TransactionStorage;

constructor(address _registry) UseRegistry(ServiceRegistry(_registry)) {}

/**
* @param data Encoded calldata that conforms to the WithdrawData struct
*/
function execute(bytes calldata data, uint8[] memory paramsMap) external payable override {
WithdrawData memory withdraw = parseInputs(data);

uint256 mappedWithdrawAmount = store().readUint(
bytes32(0),
paramsMap[0]
);

IMorpho morphoBlue = IMorpho(getRegisteredService(MORPHO_BLUE));
morphoBlue.withdrawCollateral(
withdraw.marketParams,
mappedWithdrawAmount,
address(this),
withdraw.to
);

store().write(bytes32(mappedWithdrawAmount));
}

function parseInputs(bytes memory _callData) public pure returns (WithdrawData memory params) {
return abi.decode(_callData, (WithdrawData));
}
}

1 change: 1 addition & 0 deletions packages/dma-contracts/contracts/core/types/MorphoBlue.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ struct PaybackData {
MarketParams marketParams;
uint256 amount;
address onBehalf;
bool paybackAll;
}
Loading

0 comments on commit 82ec556

Please sign in to comment.