Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed rate irm #123

Merged
merged 30 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e259e87
feat: fixed rate
MathisGD Jan 18, 2024
a24554d
Merge remote-tracking branch 'origin/main' into feat/fixed-rate
MathisGD Jan 19, 2024
169a57c
test: add testing
MathisGD Jan 25, 2024
84f2fd2
docs: minor improvements
MathisGD Jan 25, 2024
6ae27d9
refactor: remove errors from lib
MathisGD Feb 5, 2024
0cb5741
feat: revert on not yet set rate
MathisGD Feb 5, 2024
e382c16
chore: various improvements
MathisGD Feb 6, 2024
d446aed
docs: improve
MathisGD Feb 8, 2024
01e5d80
chore: update compiler version
MathisGD Feb 8, 2024
958fe16
test: fix hardhat config
MathisGD Feb 8, 2024
3d30b9e
chore: various improvements
MathisGD Feb 8, 2024
9609f74
chore: further improvements
MathisGD Feb 8, 2024
f801d3e
docs: minor update
MathisGD Feb 14, 2024
eb954af
docs: minor fix
MathisGD Feb 15, 2024
a824ce0
refactor: repo org
MathisGD Feb 19, 2024
2afb325
Merge branch 'feat/fixed-rate' into refactor/repo-org
MathisGD Feb 19, 2024
a2b57ce
Merge pull request #125 from morpho-org/refactor/repo-org
MathisGD Feb 19, 2024
7e17db2
chore: revert foundry toml changes
MathisGD Feb 19, 2024
bab3be0
Merge remote-tracking branch 'origin/feat/fixed-rate' into feat/fixed…
MathisGD Feb 19, 2024
23259f8
chore: reorder toml
MathisGD Feb 19, 2024
73f9975
docs: natspec in interface
MathisGD Feb 28, 2024
a0fa8f4
fix: bound rate
MathisGD Feb 28, 2024
1af2ddb
test: minor improvement
MathisGD Feb 28, 2024
995e08f
test: improve fuzzing efficiency
MathisGD Feb 28, 2024
cb9c58e
test: better test name
MathisGD Feb 29, 2024
038844e
docs: document rate too low issue
MathisGD Mar 1, 2024
3e435cd
chore: fmt
MathisGD Mar 1, 2024
9e1c932
Merge remote-tracking branch 'origin/docs/natspec-in-interface' into …
MathisGD Mar 4, 2024
f926397
Merge pull request #127 from morpho-org/docs/natspec-in-interface
MathisGD Mar 5, 2024
b2c9ba7
Merge pull request #128 from morpho-org/fix/bound-rate
MathisGD Mar 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/FixedRateIrm.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
MathisGD marked this conversation as resolved.
Show resolved Hide resolved

import {IIrm} from "../lib/morpho-blue/src/interfaces/IIrm.sol";
import {IFixedRateIrm} from "./interfaces/IFixedRateIrm.sol";

import {ErrorsLib} from "./libraries/ErrorsLib.sol";
import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";
import {Id, MarketParams, Market} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

/// @title FixedRateIrm
/// @author Morpho Labs
/// @custom:contact security@morpho.org
contract FixedRateIrm is IFixedRateIrm {
using MarketParamsLib for MarketParams;

/* EVENTS */

/// @notice Emitted when a borrow rate is set.
event SetBorrowRate(Id indexed id, uint256 newBorrowRate);

/* STORAGE */

/// @notice Borrow rates.
mapping(Id => uint256) public _borrowRate;
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
MathisGD marked this conversation as resolved.
Show resolved Hide resolved

/* SETTER */

/// @inheritdoc IFixedRateIrm
function setBorrowRate(Id id, uint256 newBorrowRate) external {
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
require(_borrowRate[id] == 0, ErrorsLib.RATE_ALREADY_SET);
require(newBorrowRate != 0, ErrorsLib.RATE_ZERO);
MathisGD marked this conversation as resolved.
Show resolved Hide resolved

MathisGD marked this conversation as resolved.
Show resolved Hide resolved
_borrowRate[id] = newBorrowRate;

emit SetBorrowRate(id, newBorrowRate);
}

/* BORROW RATES */

/// @inheritdoc IIrm
function borrowRateView(MarketParams memory marketParams, Market memory) external view returns (uint256) {
return _borrowRate[marketParams.id()];
}

/// @inheritdoc IIrm
function borrowRate(MarketParams memory marketParams, Market memory) external view returns (uint256) {
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
return _borrowRate[marketParams.id()];
}
}
15 changes: 15 additions & 0 deletions src/interfaces/IFixedRateIrm.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;

import {IIrm} from "../../lib/morpho-blue/src/interfaces/IIrm.sol";
import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

/// @title IAdaptiveCurveIrm
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
/// @author Morpho Labs
/// @custom:contact security@morpho.org
interface IFixedRateIrm is IIrm {
/// @notice Sets the borrow rate for a market.
/// @dev A rate can be set by anybody, but only once.
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
/// @dev The creator of a market with this IRM would typically batch the creation with the setting of the rate.
function setBorrowRate(Id id, uint256 newBorrowRate) external;
}
6 changes: 6 additions & 0 deletions src/libraries/ErrorsLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ library ErrorsLib {

/// @dev Thrown when the caller is not Morpho.
string internal constant NOT_MORPHO = "not Morpho";

MathisGD marked this conversation as resolved.
Show resolved Hide resolved
/// @dev Thrown when the rate is already set for this market.
string internal constant RATE_ALREADY_SET = "rate already set";

/// @dev Thrown when trying to set the rate at zero.
string internal constant RATE_ZERO = "rate zero";
}
60 changes: 60 additions & 0 deletions test/forge/FixedRateIrmTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../../src/FixedRateIrm.sol";

import "../../lib/forge-std/src/Test.sol";

contract FixedRateIrmTest is Test {
using MarketParamsLib for MarketParams;

event SetBorrowRate(Id indexed id, uint256 newBorrowRate);

FixedRateIrm public fixedRateIrm;

function setUp() external {
fixedRateIrm = new FixedRateIrm();
}

function testSetBorrowRate(Id id, uint256 newBorrowRate) external {
vm.assume(newBorrowRate != 0);

fixedRateIrm.setBorrowRate(id, newBorrowRate);
assertEq(fixedRateIrm._borrowRate(id), newBorrowRate);
}

function testSetBorrowRateEvent(Id id, uint256 newBorrowRate) external {
vm.assume(newBorrowRate != 0);

vm.expectEmit(true, true, true, true, address(fixedRateIrm));
emit SetBorrowRate(id, newBorrowRate);
fixedRateIrm.setBorrowRate(id, newBorrowRate);
}

function testSetBorrowRateAlreadySet(Id id, uint256 newBorrowRate1, uint256 newBorrowRate2) external {
vm.assume(newBorrowRate1 != 0);
vm.assume(newBorrowRate2 != 0);
fixedRateIrm.setBorrowRate(id, newBorrowRate1);
vm.expectRevert(bytes(ErrorsLib.RATE_ALREADY_SET));
fixedRateIrm.setBorrowRate(id, newBorrowRate2);
}

function testSetBorrowRateRateZero(Id id) external {
vm.expectRevert(bytes(ErrorsLib.RATE_ZERO));
fixedRateIrm.setBorrowRate(id, 0);
}

function testBorrowRate(MarketParams memory marketParams, Market memory market, uint256 newBorrowRate) external {
vm.assume(newBorrowRate != 0);
fixedRateIrm.setBorrowRate(marketParams.id(), newBorrowRate);
assertEq(fixedRateIrm.borrowRate(marketParams, market), newBorrowRate);
}

function testBorrowRateView(MarketParams memory marketParams, Market memory market, uint256 newBorrowRate)
external
{
vm.assume(newBorrowRate != 0);
fixedRateIrm.setBorrowRate(marketParams.id(), newBorrowRate);
assertEq(fixedRateIrm.borrowRateView(marketParams, market), newBorrowRate);
}
}
Loading