mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
167 lines
4.4 KiB
Solidity
167 lines
4.4 KiB
Solidity
//SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.7.0;
|
|
pragma experimental ABIEncoderV2;
|
|
|
|
import "./interface.sol";
|
|
import "../../common/stores.sol";
|
|
import "../../common/basic.sol";
|
|
import "../../common/interfaces.sol";
|
|
|
|
abstract contract Helpers is Stores, Basic {
|
|
IMorpho public constant MORPHO_BLUE =
|
|
IMorpho(0x777777c9898D384F785Ee44Acfe945efDFf5f3E0); // TODO: Update
|
|
|
|
uint256 internal constant MARKET_PARAMS_BYTES_LENGTH = 5 * 32;
|
|
|
|
/// @dev The number of virtual assets of 1 enforces a conversion rate between shares and assets when a market is
|
|
/// empty.
|
|
uint256 internal constant VIRTUAL_ASSETS = 1;
|
|
|
|
/// @dev The number of virtual shares has been chosen low enough to prevent overflows, and high enough to ensure
|
|
/// high precision computations.
|
|
uint256 internal constant VIRTUAL_SHARES = 1e6;
|
|
|
|
enum Mode {
|
|
Collateral,
|
|
Repay,
|
|
Other // Neither collateral nor repay
|
|
}
|
|
|
|
/// @notice Handles Eth to Weth conversion if assets are provided.
|
|
function _performEthToWethConversion(
|
|
MarketParams memory _marketParams,
|
|
uint256 _assets,
|
|
address _onBehalf,
|
|
uint256 _getId,
|
|
Mode _mode
|
|
) internal returns (TokenInterface _tokenContract, uint256 _amt) {
|
|
_amt = getUint(_getId, _assets);
|
|
|
|
bool _isEth;
|
|
if (_mode == Mode.Collateral) {
|
|
_isEth = _marketParams.collateralToken == ethAddr;
|
|
} else {
|
|
_isEth = _marketParams.loanToken == ethAddr;
|
|
}
|
|
|
|
// Set the correct token contract
|
|
_tokenContract = _isEth
|
|
? TokenInterface(wethAddr)
|
|
: TokenInterface(_marketParams.loanToken);
|
|
|
|
// Check for max value
|
|
if (_assets == type(uint256).max) {
|
|
uint256 _maxAvailable = _isEth
|
|
? address(this).balance
|
|
: _tokenContract.balanceOf(address(this));
|
|
if (_mode == Mode.Repay) {
|
|
uint256 _amtDebt = getPaybackBalance(_marketParams, _onBehalf);
|
|
_amt = min(_maxAvailable, _amtDebt);
|
|
} else {
|
|
_amt = _maxAvailable;
|
|
}
|
|
}
|
|
|
|
// Perform conversion if necessary
|
|
if (_isEth) {
|
|
convertEthToWeth(true, _tokenContract, _amt);
|
|
}
|
|
}
|
|
|
|
/// @notice Handles Eth to Weth conversion if shares are provided.
|
|
function _performEthToWethSharesConversion(
|
|
MarketParams memory _marketParams,
|
|
uint256 _shares,
|
|
address _onBehalf,
|
|
uint256 _getId,
|
|
bool _isRepay
|
|
) internal returns (TokenInterface _tokenContract, uint256 _assets) {
|
|
uint256 _shareAmt = getUint(_getId, _shares);
|
|
bool _isEth = _marketParams.loanToken == ethAddr;
|
|
|
|
// Set the token contract based on whether the loan token is ETH
|
|
_tokenContract = _isEth
|
|
? TokenInterface(wethAddr)
|
|
: TokenInterface(_marketParams.loanToken);
|
|
|
|
// Handle the max share case or normal share conversion
|
|
if (_isRepay && _shares == type(uint256).max) {
|
|
uint256 _maxAvailable = _isEth
|
|
? address(this).balance
|
|
: _tokenContract.balanceOf(address(this));
|
|
_assets = min(
|
|
_maxAvailable,
|
|
getPaybackBalance(_marketParams, _onBehalf)
|
|
);
|
|
} else {
|
|
bytes32 _id = id(_marketParams);
|
|
_assets = _toAssetsUp(
|
|
_shareAmt,
|
|
MORPHO_BLUE.market(_id).totalSupplyAssets,
|
|
MORPHO_BLUE.market(_id).totalSupplyShares
|
|
);
|
|
}
|
|
|
|
// Perform ETH to WETH conversion if necessary
|
|
if (_isEth) {
|
|
convertEthToWeth(true, _tokenContract, _assets);
|
|
}
|
|
}
|
|
|
|
/// @notice Helper function to find the minimum of two values
|
|
function min(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
return a < b ? a : b;
|
|
}
|
|
|
|
/// @notice Returns the payback balance in assets.
|
|
function getPaybackBalance(
|
|
MarketParams memory _marketParams,
|
|
address _onBehalf
|
|
) internal view returns (uint256 _assets) {
|
|
bytes32 _id = id(_marketParams);
|
|
|
|
uint256 _shareAmt = MORPHO_BLUE.position(_id, _onBehalf).supplyShares;
|
|
|
|
_assets = _toAssetsUp(
|
|
_shareAmt,
|
|
MORPHO_BLUE.market(_id).totalSupplyAssets,
|
|
MORPHO_BLUE.market(_id).totalSupplyShares
|
|
);
|
|
}
|
|
|
|
/// @notice Returns the id of the market `marketParams`.
|
|
function id(
|
|
MarketParams memory marketParams
|
|
) internal pure returns (bytes32 marketParamsId) {
|
|
assembly {
|
|
marketParamsId := keccak256(
|
|
marketParams,
|
|
MARKET_PARAMS_BYTES_LENGTH
|
|
)
|
|
}
|
|
}
|
|
|
|
/// @notice Calculates the value of `shares` quoted in assets, rounding up.
|
|
function _toAssetsUp(
|
|
uint256 _shares,
|
|
uint256 _totalAssets,
|
|
uint256 _totalShares
|
|
) internal pure returns (uint256) {
|
|
return
|
|
_mulDivUp(
|
|
_shares,
|
|
_totalAssets + VIRTUAL_ASSETS,
|
|
_totalShares + VIRTUAL_SHARES
|
|
);
|
|
}
|
|
|
|
/// @notice Returns (`x` * `y`) / `d` rounded up.
|
|
function _mulDivUp(
|
|
uint256 x,
|
|
uint256 y,
|
|
uint256 d
|
|
) internal pure returns (uint256) {
|
|
return (x * y + (d - 1)) / d;
|
|
}
|
|
}
|