编译器
0.8.24+commit.e11b9ed9
文件 1 的 5:BaseFactory.sol
pragma solidity ^0.8.0;
import {IFactory} from "./interfaces/IFactory.sol";
abstract contract BaseFactory is IFactory {
mapping(address => DeploymentInfo) internal deploymentInfo;
address[] public deployments;
function getDeploymentInfo(address contractAddress) external view returns (address deployer, uint96 deployedAt) {
DeploymentInfo memory info = deploymentInfo[contractAddress];
return (info.deployer, info.deployedAt);
}
function isValidDeployment(address contractAddress) external view returns (bool) {
return deploymentInfo[contractAddress].deployedAt != 0;
}
function getDeploymentsListLength() external view returns (uint256) {
return deployments.length;
}
function getDeploymentsListSlice(uint256 start, uint256 end) external view returns (address[] memory list) {
if (end == type(uint256).max) end = deployments.length;
if (end < start || end > deployments.length) revert Factory_BadQuery();
list = new address[](end - start);
for (uint256 i; i < end - start; ++i) {
list[i] = deployments[start + i];
}
}
}
文件 2 的 5:EulerKinkIRMFactory.sol
pragma solidity ^0.8.0;
import {BaseFactory} from "../BaseFactory/BaseFactory.sol";
import {IRMLinearKink} from "evk/InterestRateModels/IRMLinearKink.sol";
contract EulerKinkIRMFactory is BaseFactory {
uint256 internal constant MAX_ALLOWED_INTEREST_RATE = 75986279153383989049;
error IRMFactory_ExcessiveInterestRate();
function deploy(uint256 baseRate, uint256 slope1, uint256 slope2, uint32 kink) external returns (address) {
IRMLinearKink irm = new IRMLinearKink(baseRate, slope1, slope2, kink);
irm.computeInterestRateView(address(0), type(uint32).max, 0);
irm.computeInterestRateView(address(0), type(uint32).max - kink, kink);
uint256 maxInterestRate = irm.computeInterestRateView(address(0), 0, type(uint32).max);
if (maxInterestRate > MAX_ALLOWED_INTEREST_RATE) revert IRMFactory_ExcessiveInterestRate();
deploymentInfo[address(irm)] = DeploymentInfo(msg.sender, uint96(block.timestamp));
deployments.push(address(irm));
emit ContractDeployed(address(irm), msg.sender, block.timestamp);
return address(irm);
}
}
文件 3 的 5:IFactory.sol
pragma solidity >=0.8.0;
interface IFactory {
struct DeploymentInfo {
address deployer;
uint96 deployedAt;
}
event ContractDeployed(address indexed deployedContract, address indexed deployer, uint256 deployedAt);
error Factory_BadQuery();
function getDeploymentInfo(address contractAddress) external view returns (address deployer, uint96 deployedAt);
function isValidDeployment(address contractAddress) external view returns (bool);
function getDeploymentsListLength() external view returns (uint256);
function getDeploymentsListSlice(uint256 start, uint256 end) external view returns (address[] memory list);
}
文件 4 的 5:IIRM.sol
pragma solidity >=0.8.0;
interface IIRM {
error E_IRMUpdateUnauthorized();
function computeInterestRate(address vault, uint256 cash, uint256 borrows) external returns (uint256);
function computeInterestRateView(address vault, uint256 cash, uint256 borrows) external view returns (uint256);
}
文件 5 的 5:IRMLinearKink.sol
pragma solidity ^0.8.0;
import "./IIRM.sol";
contract IRMLinearKink is IIRM {
uint256 public immutable baseRate;
uint256 public immutable slope1;
uint256 public immutable slope2;
uint256 public immutable kink;
constructor(uint256 baseRate_, uint256 slope1_, uint256 slope2_, uint32 kink_) {
baseRate = baseRate_;
slope1 = slope1_;
slope2 = slope2_;
kink = kink_;
}
function computeInterestRate(address vault, uint256 cash, uint256 borrows)
external
view
override
returns (uint256)
{
if (msg.sender != vault) revert E_IRMUpdateUnauthorized();
return computeInterestRateInternal(vault, cash, borrows);
}
function computeInterestRateView(address vault, uint256 cash, uint256 borrows)
external
view
override
returns (uint256)
{
return computeInterestRateInternal(vault, cash, borrows);
}
function computeInterestRateInternal(address, uint256 cash, uint256 borrows) internal view returns (uint256) {
uint256 totalAssets = cash + borrows;
uint32 utilization = totalAssets == 0
? 0
: uint32(borrows * type(uint32).max / totalAssets);
uint256 ir = baseRate;
if (utilization <= kink) {
ir += utilization * slope1;
} else {
ir += kink * slope1;
uint256 utilizationOverKink;
unchecked {
utilizationOverKink = utilization - kink;
}
ir += slope2 * utilizationOverKink;
}
return ir;
}
}
{
"compilationTarget": {
"src/IRMFactory/EulerKinkIRMFactory.sol": "EulerKinkIRMFactory"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 20000
},
"remappings": [
":@chainlink/=lib/euler-price-oracle/node_modules/@chainlink/",
":@eth-optimism/=lib/euler-price-oracle/node_modules/@eth-optimism/contracts/",
":@openzeppelin/contracts/utils/math/=lib/euler-price-oracle/lib/openzeppelin-contracts/contracts/utils/math/",
":@pyth/=lib/euler-price-oracle/lib/pyth-sdk-solidity/",
":@redstone-finance/=lib/euler-price-oracle/node_modules/@redstone-finance/",
":@redstone/evm-connector/=lib/euler-price-oracle/lib/redstone-oracles-monorepo/packages/evm-connector/contracts/",
":@solady/=lib/euler-price-oracle/lib/solady/src/",
":@uniswap/v3-core/=lib/euler-price-oracle/lib/v3-core/",
":@uniswap/v3-periphery/=lib/euler-price-oracle/lib/v3-periphery/",
":ds-test/=lib/fee-flow/lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
":ethereum-vault-connector/=lib/ethereum-vault-connector/src/",
":euler-price-oracle-test/=lib/euler-price-oracle/test/",
":euler-price-oracle/=lib/euler-price-oracle/src/",
":euler-vault-kit/=lib/euler-vault-kit/src/",
":evc/=lib/ethereum-vault-connector/src/",
":evk-test/=lib/euler-vault-kit/test/",
":evk/=lib/euler-vault-kit/src/",
":fee-flow/=lib/fee-flow/src/",
":forge-gas-snapshot/=lib/euler-vault-kit/lib/permit2/lib/forge-gas-snapshot/src/",
":forge-std/=lib/forge-std/src/",
":halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/",
":openzeppelin/=lib/ethereum-vault-connector/lib/openzeppelin-contracts/contracts/",
":permit2/=lib/euler-vault-kit/lib/permit2/",
":pyth-sdk-solidity/=lib/euler-price-oracle/lib/pyth-sdk-solidity/",
":redstone-oracles-monorepo/=lib/euler-price-oracle/lib/",
":reward-streams/=lib/reward-streams/src/",
":solady/=lib/euler-price-oracle/lib/solady/src/",
":solmate/=lib/fee-flow/lib/solmate/src/",
":v3-core/=lib/euler-price-oracle/lib/v3-core/contracts/",
":v3-periphery/=lib/euler-price-oracle/lib/v3-periphery/contracts/"
]
}
[{"inputs":[],"name":"Factory_BadQuery","type":"error"},{"inputs":[],"name":"IRMFactory_ExcessiveInterestRate","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"deployedContract","type":"address"},{"indexed":true,"internalType":"address","name":"deployer","type":"address"},{"indexed":false,"internalType":"uint256","name":"deployedAt","type":"uint256"}],"name":"ContractDeployed","type":"event"},{"inputs":[{"internalType":"uint256","name":"baseRate","type":"uint256"},{"internalType":"uint256","name":"slope1","type":"uint256"},{"internalType":"uint256","name":"slope2","type":"uint256"},{"internalType":"uint32","name":"kink","type":"uint32"}],"name":"deploy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deployments","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"getDeploymentInfo","outputs":[{"internalType":"address","name":"deployer","type":"address"},{"internalType":"uint96","name":"deployedAt","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDeploymentsListLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"getDeploymentsListSlice","outputs":[{"internalType":"address[]","name":"list","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"isValidDeployment","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]