-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
52 changed files
with
4,855 additions
and
2 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
/** | ||
* @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places. | ||
* Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is: | ||
* `Exp({mantissa: 5100000000000000000})`. | ||
*/ | ||
contract ExponentialNoError { | ||
uint256 constant expScale = 1e18; | ||
uint256 constant doubleScale = 1e36; | ||
uint256 constant halfExpScale = expScale / 2; | ||
uint256 constant mantissaOne = expScale; | ||
|
||
struct Exp { | ||
uint256 mantissa; | ||
} | ||
|
||
struct Double { | ||
uint256 mantissa; | ||
} | ||
|
||
/** | ||
* @dev Truncates the given exp to a whole number value. | ||
* For example, truncate(Exp{mantissa: 15 * expScale}) = 15 | ||
*/ | ||
function truncate(Exp memory _exp) internal pure returns (uint256) { | ||
// Note: We are not using careful math here as we're performing a division that cannot fail | ||
return _exp.mantissa / expScale; | ||
} | ||
|
||
/** | ||
* @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer. | ||
*/ | ||
function mul_ScalarTruncate(Exp memory _a, uint256 _scalar) internal pure returns (uint256) { | ||
Exp memory product = mul_(_a, _scalar); | ||
return truncate(product); | ||
} | ||
|
||
/** | ||
* @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer. | ||
*/ | ||
function mul_ScalarTruncateAddUInt( | ||
Exp memory _a, | ||
uint256 _scalar, | ||
uint256 _addend | ||
) internal pure returns (uint256) { | ||
Exp memory product = mul_(_a, _scalar); | ||
return add_(truncate(product), _addend); | ||
} | ||
|
||
/** | ||
* @dev Multiply an Exp by a scalar, truncate, then minus an unsigned integer, returning an unsigned integer. | ||
*/ | ||
function mul_ScalarTruncateSubUInt(Exp memory _a, uint256 _scalar, uint256 _minus) internal pure returns (uint256) { | ||
Exp memory product = mul_(_a, _scalar); | ||
return sub_(truncate(product), _minus); | ||
} | ||
|
||
/** | ||
* @dev Checks if first Exp is less than second Exp. | ||
*/ | ||
function lessThanExp(Exp memory _left, Exp memory _right) internal pure returns (bool) { | ||
return _left.mantissa < _right.mantissa; | ||
} | ||
|
||
/** | ||
* @dev Checks if left Exp <= right Exp. | ||
*/ | ||
function lessThanOrEqualExp(Exp memory _left, Exp memory _right) internal pure returns (bool) { | ||
return _left.mantissa <= _right.mantissa; | ||
} | ||
|
||
/** | ||
* @dev Checks if left Exp > right Exp. | ||
*/ | ||
function greaterThanExp(Exp memory _left, Exp memory _right) internal pure returns (bool) { | ||
return _left.mantissa > _right.mantissa; | ||
} | ||
|
||
/** | ||
* @dev returns true if Exp is exactly zero | ||
*/ | ||
function isZeroExp(Exp memory _value) internal pure returns (bool) { | ||
return _value.mantissa == 0; | ||
} | ||
|
||
function safe224(uint256 _n, string memory _errorMessage) internal pure returns (uint224) { | ||
require(_n < 2 ** 224, _errorMessage); | ||
return uint224(_n); | ||
} | ||
|
||
function safe32(uint256 _n, string memory _errorMessage) internal pure returns (uint32) { | ||
require(_n < 2 ** 32, _errorMessage); | ||
return uint32(_n); | ||
} | ||
|
||
function add_(Exp memory _a, Exp memory _b) internal pure returns (Exp memory) { | ||
return Exp({ mantissa: add_(_a.mantissa, _b.mantissa) }); | ||
} | ||
|
||
function add_(Double memory _a, Double memory _b) internal pure returns (Double memory) { | ||
return Double({ mantissa: add_(_a.mantissa, _b.mantissa) }); | ||
} | ||
|
||
function add_(uint256 _a, uint256 _b) internal pure returns (uint256) { | ||
return _a + _b; | ||
} | ||
|
||
function sub_(Exp memory _a, Exp memory _b) internal pure returns (Exp memory) { | ||
return Exp({ mantissa: sub_(_a.mantissa, _b.mantissa) }); | ||
} | ||
|
||
function sub_(Double memory _a, Double memory _b) internal pure returns (Double memory) { | ||
return Double({ mantissa: sub_(_a.mantissa, _b.mantissa) }); | ||
} | ||
|
||
function sub_(uint256 _a, uint256 _b) internal pure returns (uint256) { | ||
return _a - _b; | ||
} | ||
|
||
function mul_(Exp memory _a, Exp memory _b) internal pure returns (Exp memory) { | ||
return Exp({ mantissa: mul_(_a.mantissa, _b.mantissa) / expScale }); | ||
} | ||
|
||
function mul_(Exp memory _a, uint256 _b) internal pure returns (Exp memory) { | ||
return Exp({ mantissa: mul_(_a.mantissa, _b) }); | ||
} | ||
|
||
function mul_(uint256 _a, Exp memory _b) internal pure returns (uint256) { | ||
return mul_(_a, _b.mantissa) / expScale; | ||
} | ||
|
||
function mul_(Double memory _a, Double memory _b) internal pure returns (Double memory) { | ||
return Double({ mantissa: mul_(_a.mantissa, _b.mantissa) / doubleScale }); | ||
} | ||
|
||
function mul_(Double memory _a, uint256 _b) internal pure returns (Double memory) { | ||
return Double({ mantissa: mul_(_a.mantissa, _b) }); | ||
} | ||
|
||
function mul_(uint256 _a, Double memory _b) internal pure returns (uint256) { | ||
return mul_(_a, _b.mantissa) / doubleScale; | ||
} | ||
|
||
function mul_(uint256 _a, uint256 _b) internal pure returns (uint256) { | ||
return _a * _b; | ||
} | ||
|
||
function div_(Exp memory _a, Exp memory _b) internal pure returns (Exp memory) { | ||
return Exp({ mantissa: div_(mul_(_a.mantissa, expScale), _b.mantissa) }); | ||
} | ||
|
||
function div_(Exp memory _a, uint256 _b) internal pure returns (Exp memory) { | ||
return Exp({ mantissa: div_(_a.mantissa, _b) }); | ||
} | ||
|
||
function div_(uint256 _a, Exp memory _b) internal pure returns (uint256) { | ||
return div_(mul_(_a, expScale), _b.mantissa); | ||
} | ||
|
||
function div_(Double memory _a, Double memory _b) internal pure returns (Double memory) { | ||
return Double({ mantissa: div_(mul_(_a.mantissa, doubleScale), _b.mantissa) }); | ||
} | ||
|
||
function div_(Double memory _a, uint256 _b) internal pure returns (Double memory) { | ||
return Double({ mantissa: div_(_a.mantissa, _b) }); | ||
} | ||
|
||
function div_(uint256 _a, Double memory _b) internal pure returns (uint256) { | ||
return div_(mul_(_a, doubleScale), _b.mantissa); | ||
} | ||
|
||
function div_(uint256 _a, uint256 _b) internal pure returns (uint256) { | ||
return _a / _b; | ||
} | ||
|
||
function fraction(uint256 _a, uint256 _b) internal pure returns (Double memory) { | ||
return Double({ mantissa: div_(mul_(_a, doubleScale), _b) }); | ||
} | ||
} |
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,79 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
import "./TokenBase.sol"; | ||
import "./TokenStorages.sol"; | ||
import "./interfaces/IFErc20.sol"; | ||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
|
||
contract FErc20 is TokenBase, FErc20Storage, IFErc20 { | ||
function initialize( | ||
address _underlying, | ||
address _riskManager, | ||
address _interestRateModel, | ||
address _priceOracle, | ||
address _checker, | ||
string memory _name, | ||
string memory _symbol | ||
) public initializer { | ||
__TokenBase_init(_riskManager, _interestRateModel, _priceOracle, _checker, _name, _symbol); | ||
|
||
underlying = _underlying; | ||
} | ||
|
||
function supply(uint256 _supplyAmount) external { | ||
// Params: supplier, supply amount | ||
supplyInternal(msg.sender, _supplyAmount); | ||
} | ||
|
||
function redeem(uint256 _redeemTokens) external { | ||
// Params: redeemer, tokens supplied for redemption, amount of underlying to receive | ||
redeemInternal(msg.sender, _redeemTokens, 0); | ||
} | ||
|
||
function redeemUnderlying(uint256 _redeemAmount) external { | ||
// Params: redeemer, tokens supplied for redemption, amount of underlying to receive | ||
redeemInternal(msg.sender, 0, _redeemAmount); | ||
} | ||
|
||
function borrow(uint256 _borrowAmount) external { | ||
// Params: borrower, borrow amount | ||
borrowInternal(msg.sender, _borrowAmount); | ||
} | ||
|
||
function repayBorrow(uint256 _repayAmount) external { | ||
// Params: payer, borrower, repay amount | ||
repayBorrowInternal(msg.sender, msg.sender, _repayAmount); | ||
} | ||
|
||
function repayBorrowBehalf(address _borrower, uint256 _repayAmount) external { | ||
// Params: payer, borrower, repay amount | ||
repayBorrowInternal(msg.sender, _borrower, _repayAmount); | ||
} | ||
|
||
function liquidateBorrow(address _borrower, uint256 _repayAmount, address _fTokenCollateral) external { | ||
// Params: liquidator, borrower, repay amount, collateral token to be seized | ||
liquidateBorrowInternal(msg.sender, _borrower, _repayAmount, _fTokenCollateral); | ||
} | ||
|
||
/******************************* Safe Token *******************************/ | ||
|
||
function getUnderlying() public view override returns (address) { | ||
return underlying; | ||
} | ||
|
||
function doTransferIn(address _from, uint256 _amount) internal override { | ||
IERC20 underlyingToken = IERC20(underlying); | ||
underlyingToken.transferFrom(_from, address(this), _amount); | ||
|
||
totalCash += _amount; | ||
} | ||
|
||
function doTransferOut(address payable _to, uint256 _amount) internal override { | ||
IERC20 underlyingToken = IERC20(underlying); | ||
underlyingToken.transfer(_to, _amount); | ||
|
||
totalCash -= _amount; | ||
} | ||
} |
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,92 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
import "./TokenBase.sol"; | ||
|
||
contract FEther is TokenBase { | ||
function initialize( | ||
address _riskManager, | ||
address _interestRateModel, | ||
address _priceOracle, | ||
address _checker | ||
) public initializer { | ||
__TokenBase_init(_riskManager, _interestRateModel, _priceOracle, _checker, "Furion Ether", "fETH"); | ||
} | ||
|
||
/** | ||
* @notice Sender supplies ETH into the market and receives fETH in exchange | ||
* @dev Reverts upon any failure | ||
*/ | ||
function supply() external payable { | ||
// Params: supplier, supply amount | ||
supplyInternal(msg.sender, msg.value); | ||
} | ||
|
||
/** | ||
* @notice Sender redeems fETH in exchange for ETH. | ||
* @dev Accrues interest whether or not the operation succeeds, unless reverted | ||
* @param _redeemTokens The number of fETH to redeem into underlying | ||
*/ | ||
function redeem(uint256 _redeemTokens) external { | ||
// Params: redeemer, tokens supplied for redemption, amount of underlying to receive | ||
redeemInternal(msg.sender, _redeemTokens, 0); | ||
} | ||
|
||
/** | ||
* @notice Sender redeems fETH in exchange for a specified amount of ETH. | ||
* @dev Accrues interest whether or not the operation succeeds, unless reverted | ||
* @param _redeemAmount The amount of ETH to redeem | ||
*/ | ||
function redeemUnderlying(uint256 _redeemAmount) external { | ||
// Params: redeemer, tokens supplied for redemption, amount of underlying to receive | ||
redeemInternal(msg.sender, 0, _redeemAmount); | ||
} | ||
|
||
/** | ||
* @notice Sender borrows ETH from the protocol to their own address | ||
* @param _borrowAmount The amount of ETH to borrow | ||
*/ | ||
function borrow(uint256 _borrowAmount) external { | ||
// Params: borrower, borrow amount | ||
borrowInternal(msg.sender, _borrowAmount); | ||
} | ||
|
||
/** | ||
* @notice Sender repays their own borrow | ||
* @dev Reverts upon any failure | ||
*/ | ||
function repayBorrow() external payable { | ||
// Params: payer, borrower, repay amount | ||
repayBorrowInternal(msg.sender, msg.sender, msg.value); | ||
} | ||
|
||
/** | ||
* @notice Sender repays a borrow belonging to borrower | ||
* @dev Reverts upon any failure | ||
* @param _borrower the account with the debt being payed off | ||
*/ | ||
function repayBorrowBehalf(address _borrower) external payable { | ||
// Params: payer, borrower, repay amount | ||
repayBorrowInternal(msg.sender, _borrower, msg.value); | ||
} | ||
|
||
function liquidateBorrow(address _borrower, address _fTokenCollateral) external payable { | ||
liquidateBorrowInternal(msg.sender, _borrower, msg.value, _fTokenCollateral); | ||
} | ||
|
||
/******************************* Safe Token *******************************/ | ||
|
||
function doTransferIn(address _from, uint256 _amount) internal override { | ||
require(msg.sender == _from, "FEther: Not owner of account"); | ||
require(msg.value == _amount, "FEther: Not enough ETH supplied"); | ||
|
||
totalCash += _amount; | ||
} | ||
|
||
function doTransferOut(address payable _to, uint256 _amount) internal override { | ||
_to.transfer(_amount); | ||
|
||
totalCash -= _amount; | ||
} | ||
} |
Oops, something went wrong.