Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 26 additions & 0 deletions script/DeployEarnerRateModel.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.23;

import { Script, console2 } from "../lib/forge-std/src/Script.sol";
import { EarnerRateModel } from "../src/rateModels/EarnerRateModel.sol";

contract DeployEarnerRateModel is Script {
// NOTE: Ensure this is the correct MinterGateway testnet/mainnet address.
address internal constant _MINTER_GATEWAY = 0xf7f9638cb444D65e5A40bF5ff98ebE4ff319F04E; //mainnet
// address internal constant _MINTER_GATEWAY = 0x4eDfcfB5F9e55962EF1A2eEf0b56A8FaDbaBA289; // sepolia

function run() external {
address deployer_ = vm.rememberKey(vm.envUint("PRIVATE_KEY"));

console2.log("Deployer:", deployer_);

vm.startBroadcast(deployer_);

address earnerRateModel_ = address(new EarnerRateModel(_MINTER_GATEWAY));

vm.stopBroadcast();

console2.log("Earner Rate Model address:", earnerRateModel_);
}
}
23 changes: 14 additions & 9 deletions src/rateModels/EarnerRateModel.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { IEarnerRateModel } from "./interfaces/IEarnerRateModel.sol";

/**
* @title Earner Rate Model contract set in TTG (Two Token Governance) Registrar and accessed by MToken.
* @author M^0 Labs
* @author M0 Labs
*/
contract EarnerRateModel is IEarnerRateModel {
/* ============ Variables ============ */
Expand Down Expand Up @@ -64,15 +64,20 @@ contract EarnerRateModel is IEarnerRateModel {

/// @inheritdoc IRateModel
function rate() external view returns (uint256) {
uint256 earnerRate_ = maxRate();
uint32 minterRate_ = IMinterGateway(minterGateway).minterRate();
uint240 totalActiveOwedM_ = IMinterGateway(minterGateway).totalActiveOwedM();
uint240 totalEarningSupply_ = IMToken(mToken).totalEarningSupply();

// If there are no active minters or minter rate is zero, do not accrue yield to earners.
if (totalActiveOwedM_ == 0 || minterRate_ == 0) return 0;

// NOTE: If `earnerRate` <= `minterRate` and there are no deactivated minters in the system,
// it is safe to return `earnerRate` as the effective rate.
if (earnerRate_ <= minterRate_ && totalActiveOwedM_ >= totalEarningSupply_) return earnerRate_;

return
UIntMath.min256(
maxRate(),
getExtraSafeEarnerRate(
IMinterGateway(minterGateway).totalActiveOwedM(),
IMToken(mToken).totalEarningSupply(),
IMinterGateway(minterGateway).minterRate()
)
);
UIntMath.min256(earnerRate_, getExtraSafeEarnerRate(totalActiveOwedM_, totalEarningSupply_, minterRate_));
}

/// @inheritdoc IEarnerRateModel
Expand Down