Skip to content

Commit

Permalink
Merge pull request #128 from morpho-org/fix/bound-rate
Browse files Browse the repository at this point in the history
bound (fixed) rate
  • Loading branch information
MathisGD authored Mar 5, 2024
2 parents f926397 + 9e1c932 commit b2c9ba7
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 6 deletions.
8 changes: 8 additions & 0 deletions src/fixed-rate-irm/FixedRateIrm.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@ string constant RATE_NOT_SET = "rate not set";
string constant RATE_SET = "rate set";
/// @dev Thrown when trying to set the rate at zero.
string constant RATE_ZERO = "rate zero";
/// @dev Thrown when trying to set a rate that is too high.
string constant RATE_TOO_HIGH = "rate too high";

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

/* CONSTANTS */

/// @inheritdoc IFixedRateIrm
uint256 public constant MAX_BORROW_RATE = 8.0 ether / uint256(365 days);

/* STORAGE */

/// @inheritdoc IFixedRateIrm
Expand All @@ -33,6 +40,7 @@ contract FixedRateIrm is IFixedRateIrm {
function setBorrowRate(Id id, uint256 newBorrowRate) external {
require(borrowRateStored[id] == 0, RATE_SET);
require(newBorrowRate != 0, RATE_ZERO);
require(newBorrowRate <= MAX_BORROW_RATE, RATE_TOO_HIGH);

borrowRateStored[id] = newBorrowRate;

Expand Down
5 changes: 5 additions & 0 deletions src/fixed-rate-irm/interfaces/IFixedRateIrm.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@ interface IFixedRateIrm is IIrm {

/* EXTERNAL */

/// @notice Max settable borrow rate (800%).
function MAX_BORROW_RATE() external returns (uint256);

/// @notice Borrow rates.
function borrowRateStored(Id id) external returns (uint256);

/// @notice Sets the borrow rate for a market.
/// @dev A rate can be set by anybody, but only once.
/// @dev `borrowRate` reverts on rate not set, so the rate needs to be set before the market creation.
/// @dev As interest are rounded down in Morpho, for markets with a low total borrow, setting a rate too low could
/// prevent interest from accruing if interactions are frequent.
function setBorrowRate(Id id, uint256 newBorrowRate) external;
}
19 changes: 13 additions & 6 deletions test/forge/FixedRateIrmTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,24 @@ contract FixedRateIrmTest is Test {
}

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

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

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

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);
newBorrowRate1 = bound(newBorrowRate1, 1, fixedRateIrm.MAX_BORROW_RATE());
newBorrowRate2 = bound(newBorrowRate2, 1, fixedRateIrm.MAX_BORROW_RATE());

fixedRateIrm.setBorrowRate(id, newBorrowRate1);
vm.expectRevert(bytes(RATE_SET));
fixedRateIrm.setBorrowRate(id, newBorrowRate2);
Expand All @@ -44,8 +45,14 @@ contract FixedRateIrmTest is Test {
fixedRateIrm.setBorrowRate(id, 0);
}

function testSetBorrowRateTooHigh(Id id, uint256 newBorrowRate) external {
newBorrowRate = bound(newBorrowRate, fixedRateIrm.MAX_BORROW_RATE() + 1, type(uint256).max);
vm.expectRevert(bytes(RATE_TOO_HIGH));
fixedRateIrm.setBorrowRate(id, newBorrowRate);
}

function testBorrowRate(MarketParams memory marketParams, Market memory market, uint256 newBorrowRate) external {
vm.assume(newBorrowRate != 0);
newBorrowRate = bound(newBorrowRate, 1, fixedRateIrm.MAX_BORROW_RATE());
fixedRateIrm.setBorrowRate(marketParams.id(), newBorrowRate);
assertEq(fixedRateIrm.borrowRate(marketParams, market), newBorrowRate);
}
Expand All @@ -58,7 +65,7 @@ contract FixedRateIrmTest is Test {
function testBorrowRateView(MarketParams memory marketParams, Market memory market, uint256 newBorrowRate)
external
{
vm.assume(newBorrowRate != 0);
newBorrowRate = bound(newBorrowRate, 1, fixedRateIrm.MAX_BORROW_RATE());
fixedRateIrm.setBorrowRate(marketParams.id(), newBorrowRate);
assertEq(fixedRateIrm.borrowRateView(marketParams, market), newBorrowRate);
}
Expand Down

0 comments on commit b2c9ba7

Please sign in to comment.