-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #109 from morpho-labs/refactor/morpho-utils
Refactor: shares management
- Loading branch information
Showing
6 changed files
with
177 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.0; | ||
|
||
/// @notice Arithmetic library with operations for fixed-point numbers. | ||
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol) | ||
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol) | ||
library FixedPointMathLib { | ||
/*////////////////////////////////////////////////////////////// | ||
SIMPLIFIED FIXED POINT OPERATIONS | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
uint256 internal constant MAX_UINT256 = 2 ** 256 - 1; | ||
|
||
uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s. | ||
|
||
function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { | ||
return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. | ||
} | ||
|
||
function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) { | ||
return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up. | ||
} | ||
|
||
function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) { | ||
return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down. | ||
} | ||
|
||
function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) { | ||
return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up. | ||
} | ||
|
||
/*////////////////////////////////////////////////////////////// | ||
LOW LEVEL FIXED POINT OPERATIONS | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
function mulDivDown(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 z) { | ||
/// @solidity memory-safe-assembly | ||
assembly { | ||
// Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) | ||
if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } | ||
|
||
// Divide x * y by the denominator. | ||
z := div(mul(x, y), denominator) | ||
} | ||
} | ||
|
||
function mulDivUp(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 z) { | ||
/// @solidity memory-safe-assembly | ||
assembly { | ||
// Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) | ||
if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } | ||
|
||
// If x * y modulo the denominator is strictly greater than 0, | ||
// 1 is added to round up the division of x * y by the denominator. | ||
z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator)) | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.0; | ||
|
||
import {FixedPointMathLib} from "./FixedPointMathLib.sol"; | ||
|
||
/// @notice Shares management library. | ||
/// @dev This implementation mitigates share price manipulations, using OpenZeppelin's method of virtual shares: https://docs.openzeppelin.com/contracts/4.x/erc4626#inflation-attack. | ||
library SharesMath { | ||
using FixedPointMathLib for uint256; | ||
|
||
uint256 internal constant VIRTUAL_SHARES = 1e18; | ||
uint256 internal constant VIRTUAL_ASSETS = 1; | ||
|
||
/// @dev Calculates the value of the given assets quoted in shares, rounding down. | ||
/// Note: provided that assets <= totalAssets, this function satisfies the invariant: shares <= totalShares. | ||
function toSharesDown(uint256 assets, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) { | ||
return assets.mulDivDown(totalShares + VIRTUAL_SHARES, totalAssets + VIRTUAL_ASSETS); | ||
} | ||
|
||
/// @dev Calculates the value of the given shares quoted in assets, rounding down. | ||
/// Note: provided that shares <= totalShares, this function satisfies the invariant: assets <= totalAssets. | ||
function toAssetsDown(uint256 shares, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) { | ||
return shares.mulDivDown(totalAssets + VIRTUAL_ASSETS, totalShares + VIRTUAL_SHARES); | ||
} | ||
|
||
/// @dev Calculates the value of the given assets quoted in shares, rounding up. | ||
/// Note: provided that assets <= totalAssets, this function satisfies the invariant: shares <= totalShares + VIRTUAL_SHARES. | ||
function toSharesUp(uint256 assets, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) { | ||
return assets.mulDivUp(totalShares + VIRTUAL_SHARES, totalAssets + VIRTUAL_ASSETS); | ||
} | ||
|
||
/// @dev Calculates the value of the given shares quoted in assets, rounding up. | ||
/// Note: provided that shares <= totalShares, this function satisfies the invariant: assets <= totalAssets + VIRTUAL_SHARES. | ||
function toAssetsUp(uint256 shares, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) { | ||
return shares.mulDivUp(totalAssets + VIRTUAL_ASSETS, totalShares + VIRTUAL_SHARES); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.