Skip to content

Commit

Permalink
Merge branch 'main' of github.com:morpho-labs/blue into feat/flashloan
Browse files Browse the repository at this point in the history
  • Loading branch information
MerlinEgalite committed Jul 27, 2023
2 parents 762b88d + 17ec24a commit 82284e9
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 16 deletions.
43 changes: 30 additions & 13 deletions src/Blue.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {Id, Market, MarketLib} from "src/libraries/MarketLib.sol";
import {SafeTransferLib} from "src/libraries/SafeTransferLib.sol";

uint256 constant WAD = 1e18;
uint256 constant MAX_FEE = 0.2e18;
uint256 constant MAX_FEE = 0.25e18;
uint256 constant ALPHA = 0.5e18;

contract Blue is IFlashLender {
Expand Down Expand Up @@ -82,7 +82,7 @@ contract Blue is IFlashLender {
}

/// @notice It is the owner's responsibility to ensure a fee recipient is set before setting a non-zero fee.
function setFee(Market calldata market, uint256 newFee) external onlyOwner {
function setFee(Market memory market, uint256 newFee) external onlyOwner {
Id id = market.id();
require(lastUpdate[id] != 0, Errors.MARKET_NOT_CREATED);
require(newFee <= MAX_FEE, Errors.MAX_FEE_EXCEEDED);
Expand All @@ -95,7 +95,7 @@ contract Blue is IFlashLender {

// Markets management.

function createMarket(Market calldata market) external {
function createMarket(Market memory market) external {
Id id = market.id();
require(isIrmEnabled[market.irm], Errors.IRM_NOT_ENABLED);
require(isLltvEnabled[market.lltv], Errors.LLTV_NOT_ENABLED);
Expand All @@ -106,7 +106,7 @@ contract Blue is IFlashLender {

// Supply management.

function supply(Market calldata market, uint256 amount, address onBehalf) external {
function supply(Market memory market, uint256 amount, address onBehalf) external {
Id id = market.id();
require(lastUpdate[id] != 0, Errors.MARKET_NOT_CREATED);
require(amount != 0, Errors.ZERO_AMOUNT);
Expand All @@ -122,7 +122,7 @@ contract Blue is IFlashLender {
market.borrowableAsset.safeTransferFrom(msg.sender, address(this), amount);
}

function withdraw(Market calldata market, uint256 amount, address onBehalf) external {
function withdraw(Market memory market, uint256 amount, address onBehalf) external {
Id id = market.id();
require(lastUpdate[id] != 0, Errors.MARKET_NOT_CREATED);
require(amount != 0, Errors.ZERO_AMOUNT);
Expand All @@ -143,7 +143,7 @@ contract Blue is IFlashLender {

// Borrow management.

function borrow(Market calldata market, uint256 amount, address onBehalf) external {
function borrow(Market memory market, uint256 amount, address onBehalf) external {
Id id = market.id();
require(lastUpdate[id] != 0, Errors.MARKET_NOT_CREATED);
require(amount != 0, Errors.ZERO_AMOUNT);
Expand All @@ -163,7 +163,7 @@ contract Blue is IFlashLender {
market.borrowableAsset.safeTransfer(msg.sender, amount);
}

function repay(Market calldata market, uint256 amount, address onBehalf) external {
function repay(Market memory market, uint256 amount, address onBehalf) external {
Id id = market.id();
require(lastUpdate[id] != 0, Errors.MARKET_NOT_CREATED);
require(amount != 0, Errors.ZERO_AMOUNT);
Expand All @@ -182,7 +182,7 @@ contract Blue is IFlashLender {
// Collateral management.

/// @dev Don't accrue interests because it's not required and it saves gas.
function supplyCollateral(Market calldata market, uint256 amount, address onBehalf) external {
function supplyCollateral(Market memory market, uint256 amount, address onBehalf) external {
Id id = market.id();
require(lastUpdate[id] != 0, Errors.MARKET_NOT_CREATED);
require(amount != 0, Errors.ZERO_AMOUNT);
Expand All @@ -194,7 +194,7 @@ contract Blue is IFlashLender {
market.collateralAsset.safeTransferFrom(msg.sender, address(this), amount);
}

function withdrawCollateral(Market calldata market, uint256 amount, address onBehalf) external {
function withdrawCollateral(Market memory market, uint256 amount, address onBehalf) external {
Id id = market.id();
require(lastUpdate[id] != 0, Errors.MARKET_NOT_CREATED);
require(amount != 0, Errors.ZERO_AMOUNT);
Expand All @@ -211,7 +211,7 @@ contract Blue is IFlashLender {

// Liquidation.

function liquidate(Market calldata market, address borrower, uint256 seized) external {
function liquidate(Market memory market, address borrower, uint256 seized) external {
Id id = market.id();
require(lastUpdate[id] != 0, Errors.MARKET_NOT_CREATED);
require(seized != 0, Errors.ZERO_AMOUNT);
Expand Down Expand Up @@ -270,7 +270,7 @@ contract Blue is IFlashLender {

// Interests management.

function _accrueInterests(Market calldata market, Id id) internal {
function _accrueInterests(Market memory market, Id id) internal {
uint256 marketTotalBorrow = totalBorrow[id];

if (marketTotalBorrow != 0) {
Expand All @@ -293,7 +293,7 @@ contract Blue is IFlashLender {

// Health check.

function _isHealthy(Market calldata market, Id id, address user) internal view returns (bool) {
function _isHealthy(Market memory market, Id id, address user) internal view returns (bool) {
if (borrowShare[id][user] == 0) return true;

uint256 collateralPrice = market.collateralOracle.price();
Expand All @@ -302,7 +302,7 @@ contract Blue is IFlashLender {
return _isHealthy(market, id, user, collateralPrice, borrowablePrice);
}

function _isHealthy(Market calldata market, Id id, address user, uint256 collateralPrice, uint256 borrowablePrice)
function _isHealthy(Market memory market, Id id, address user, uint256 collateralPrice, uint256 borrowablePrice)
internal
view
returns (bool)
Expand All @@ -313,4 +313,21 @@ contract Blue is IFlashLender {

return collateralValue.mulWadDown(market.lltv) >= borrowValue;
}

// Storage view.

function extsload(bytes32[] calldata slots) external view returns (bytes32[] memory res) {
uint256 nSlots = slots.length;

res = new bytes32[](nSlots);

for (uint256 i; i < nSlots;) {
bytes32 slot = slots[i++];

/// @solidity memory-safe-assembly
assembly {
mstore(add(res, mul(i, 32)), sload(slot))
}
}
}
}
2 changes: 1 addition & 1 deletion src/interfaces/IIrm.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ pragma solidity >=0.5.0;
import {Market} from "src/libraries/MarketLib.sol";

interface IIrm {
function borrowRate(Market calldata market) external returns (uint256);
function borrowRate(Market memory market) external returns (uint256);
}
2 changes: 1 addition & 1 deletion src/libraries/MarketLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct Market {
}

library MarketLib {
function id(Market calldata market) internal pure returns (Id) {
function id(Market memory market) internal pure returns (Id) {
return Id.wrap(keccak256(abi.encode(market)));
}
}
2 changes: 1 addition & 1 deletion src/mocks/IrmMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ contract IrmMock is IIrm {
blue = Blue(blueInstance);
}

function borrowRate(Market calldata market) external view returns (uint256) {
function borrowRate(Market memory market) external view returns (uint256) {
Id id = market.id();
uint256 utilization = blue.totalBorrow(id).divWadDown(blue.totalSupply(id));

Expand Down
16 changes: 16 additions & 0 deletions test/forge/Blue.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,22 @@ contract BlueTest is Test {

assertEq(borrowableAsset.balanceOf(address(blue)), amount, "balanceOf");
}

function testExtsLoad(uint256 slot, bytes32 value0) public {
bytes32[] memory slots = new bytes32[](2);
slots[0] = bytes32(slot);
slots[1] = bytes32(slot / 2);

bytes32 value1 = keccak256(abi.encode(value0));
vm.store(address(blue), slots[0], value0);
vm.store(address(blue), slots[1], value1);

bytes32[] memory values = blue.extsload(slots);

assertEq(values.length, 2, "values.length");
assertEq(values[0], slot > 0 ? value0 : value1, "value0");
assertEq(values[1], value1, "value1");
}
}

function neq(Market memory a, Market memory b) pure returns (bool) {
Expand Down

0 comments on commit 82284e9

Please sign in to comment.