Description:
Proxy contract enabling upgradeable smart contract patterns. Delegates calls to an implementation contract.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"src/twyne/IRMTwyneCurve.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;
import {IIRM} from "euler-vault-kit/InterestRateModels/IIRM.sol";
import {SECONDS_PER_YEAR} from "euler-vault-kit/EVault/shared/Constants.sol";
/// @title IRMLinearKink
/// @notice To contact the team regarding security matters, visit https://twyne.xyz/security
/// @notice Implementation of a curved interest rate model
/// @notice interest rate grows linearly with utilization and increases faster after reaching a kink
contract IRMTwyneCurve is IIRM {
/// @notice Approx interest rate at linearKinkUtilizationRate
uint public immutable idealKinkInterestRate; // 0.6e4 = 60%
/// @notice Utilization rate value used in calculating IRM parameters
/// @notice beyond this utilization rate, the polynomial term dominates (this value must be greater than nonlinearPoint)
/// @notice while this is a utilization rate that would have 1e18 decimals, it is ONLY used to derive curve params so use 1e4
uint public immutable linearKinkUtilizationRate; // 0.8e4 = 80%
/// @notice Max interest rate applied at 100% utilization
uint public immutable maxInterestRate; // 5e4 = 500%
/// @notice When utilization rate is less than nonlinearPoint, assume linear model (polynomial term is not significant)
uint public immutable nonlinearPoint; // 5e17 = 50%
/// @notice Curve parameters
uint public immutable linearParameter;
uint public immutable polynomialParameter;
/// @notice LTV values have 1e4 decimals
uint internal constant MAXFACTOR = 1e4;
constructor(uint16 idealKinkInterestRate_, uint16 linearKinkUtilizationRate_, uint16 maxInterestRate_, uint nonlinearPoint_) {
if (
idealKinkInterestRate_ > maxInterestRate_
|| linearKinkUtilizationRate_ > MAXFACTOR
// || idealKinkInterestRate_ == 0
|| linearKinkUtilizationRate_ == 0
|| maxInterestRate_ == 0
|| nonlinearPoint_ == 0
|| nonlinearPoint_ >= 1e14 * uint(linearKinkUtilizationRate_) // 1e14 is to align decimals
) revert E_IRMUpdateUnauthorized();
idealKinkInterestRate = idealKinkInterestRate_;
linearKinkUtilizationRate = linearKinkUtilizationRate_;
maxInterestRate = maxInterestRate_;
nonlinearPoint = nonlinearPoint_;
linearParameter = idealKinkInterestRate * MAXFACTOR / linearKinkUtilizationRate_;
polynomialParameter = maxInterestRate_ - linearParameter;
}
/// @inheritdoc IIRM
function computeInterestRate(address vault, uint cash, uint borrows)
external
view
override
returns (uint)
{
if (msg.sender != vault) revert E_IRMUpdateUnauthorized();
return computeInterestRateInternal(vault, cash, borrows);
}
/// @inheritdoc IIRM
function computeInterestRateView(address vault, uint cash, uint borrows)
external
view
override
returns (uint)
{
return computeInterestRateInternal(vault, cash, borrows);
}
function computeInterestRateInternal(address, uint cash, uint borrows) internal view returns (uint ir) {
uint totalAssets = cash + borrows;
// utilization has decimals of 1e18, where 1e18 = 100%
uint utilization = totalAssets == 0
? 0 // prevent divide by zero case by returning zero
: borrows * 1e18 / totalAssets;
ir = linearParameter * utilization;
if (utilization > nonlinearPoint) {
// Use gamma of 12
// utilization^2
uint utilTemp4 = (utilization * utilization) / 1e18;
// utilization^4
utilTemp4 = (utilTemp4 * utilTemp4) / 1e18;
// utilization^8
uint utilpow = (utilTemp4 * utilTemp4) / 1e18;
// utilization^12
utilpow = (utilpow * utilTemp4) / 1e18;
ir += polynomialParameter * utilpow;
}
ir = (ir * (1e9 / MAXFACTOR)) / SECONDS_PER_YEAR; // has 1e27 decimals
}
}"
},
"lib/euler-vault-kit/src/InterestRateModels/IIRM.sol": {
"content": "// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.8.0;
/// @title IIRM
/// @custom:security-contact security@euler.xyz
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice Interface of the interest rate model contracts used by EVault
interface IIRM {
error E_IRMUpdateUnauthorized();
/// @notice Perform potentially state mutating computation of the new interest rate
/// @param vault Address of the vault to compute the new interest rate for
/// @param cash Amount of assets held directly by the vault
/// @param borrows Amount of assets lent out to borrowers by the vault
/// @return Then new interest rate in second percent yield (SPY), scaled by 1e27
function computeInterestRate(address vault, uint256 cash, uint256 borrows) external returns (uint256);
/// @notice Perform computation of the new interest rate without mutating state
/// @param vault Address of the vault to compute the new interest rate for
/// @param cash Amount of assets held directly by the vault
/// @param borrows Amount of assets lent out to borrowers by the vault
/// @return Then new interest rate in second percent yield (SPY), scaled by 1e27
function computeInterestRateView(address vault, uint256 cash, uint256 borrows) external view returns (uint256);
}
"
},
"lib/euler-vault-kit/src/EVault/shared/Constants.sol": {
"content": "// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
// Implementation internals
// asset amounts are shifted left by this number of bits for increased precision of debt tracking.
uint256 constant INTERNAL_DEBT_PRECISION_SHIFT = 31;
// max amount for Assets and Shares custom types based on a uint112.
uint256 constant MAX_SANE_AMOUNT = type(uint112).max;
// max debt amount fits in uint144 (112 + 31 bits).
// Last 31 bits are zeros to ensure max debt rounded up equals max sane amount.
uint256 constant MAX_SANE_DEBT_AMOUNT = uint256(MAX_SANE_AMOUNT) << INTERNAL_DEBT_PRECISION_SHIFT;
// proxy trailing calldata length in bytes.
// Three addresses, 20 bytes each: vault underlying asset, oracle and unit of account + 4 empty bytes.
uint256 constant PROXY_METADATA_LENGTH = 64;
// gregorian calendar
uint256 constant SECONDS_PER_YEAR = 365.2425 * 86400;
// max interest rate accepted from IRM. 1,000,000% APY: floor(((1000000 / 100 + 1)**(1/(86400*365.2425)) - 1) * 1e27)
uint256 constant MAX_ALLOWED_INTEREST_RATE = 291867278914945094175;
// max valid value of the ConfigAmount custom type, signifying 100%
uint16 constant CONFIG_SCALE = 1e4;
// Account status checks special values
// no account status checks should be scheduled
address constant CHECKACCOUNT_NONE = address(0);
// account status check should be scheduled for the authenticated account
address constant CHECKACCOUNT_CALLER = address(1);
// Operations
uint32 constant OP_DEPOSIT = 1 << 0;
uint32 constant OP_MINT = 1 << 1;
uint32 constant OP_WITHDRAW = 1 << 2;
uint32 constant OP_REDEEM = 1 << 3;
uint32 constant OP_TRANSFER = 1 << 4;
uint32 constant OP_SKIM = 1 << 5;
uint32 constant OP_BORROW = 1 << 6;
uint32 constant OP_REPAY = 1 << 7;
uint32 constant OP_REPAY_WITH_SHARES = 1 << 8;
uint32 constant OP_PULL_DEBT = 1 << 9;
uint32 constant OP_CONVERT_FEES = 1 << 10;
uint32 constant OP_LIQUIDATE = 1 << 11;
uint32 constant OP_FLASHLOAN = 1 << 12;
uint32 constant OP_TOUCH = 1 << 13;
uint32 constant OP_VAULT_STATUS_CHECK = 1 << 14;
// Delimiter of possible operations
uint32 constant OP_MAX_VALUE = 1 << 15;
// Config Flags
// When flag is set, debt socialization during liquidation is disabled
uint32 constant CFG_DONT_SOCIALIZE_DEBT = 1 << 0;
// When flag is set, asset is considered to be compatible with EVC sub-accounts and protections
// against sending assets to sub-accounts are disabled
uint32 constant CFG_EVC_COMPATIBLE_ASSET = 1 << 1;
// Delimiter of possible config flags
uint32 constant CFG_MAX_VALUE = 1 << 2;
// EVC authentication
// in order to perform these operations, the account doesn't need to have the vault installed as a controller
uint32 constant CONTROLLER_NEUTRAL_OPS = OP_DEPOSIT | OP_MINT | OP_WITHDRAW | OP_REDEEM | OP_TRANSFER | OP_SKIM
| OP_REPAY | OP_REPAY_WITH_SHARES | OP_CONVERT_FEES | OP_FLASHLOAN | OP_TOUCH | OP_VAULT_STATUS_CHECK;
"
}
},
"settings": {
"remappings": [
"ethereum-vault-connector/=lib/euler-vault-kit/lib/ethereum-vault-connector/src/",
"euler-vault-kit/=lib/euler-vault-kit/src/",
"euler-price-oracle/=lib/euler-price-oracle/",
"permit2/=lib/euler-vault-kit/lib/permit2/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
"openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts/=lib/euler-vault-kit/lib/openzeppelin-contracts/contracts/",
"@pendle/core-v2/=lib/euler-price-oracle/lib/pendle-core-v2-public/contracts/",
"@pyth/=lib/euler-price-oracle/lib/pyth-sdk-solidity/",
"@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/forge-safe/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"forge-gas-snapshot/=lib/euler-vault-kit/lib/permit2/lib/forge-gas-snapshot/src/",
"forge-safe/=lib/forge-safe/",
"halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"morpho-blue/=lib/morpho-blue/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin/=lib/euler-price-oracle/lib/openzeppelin-contracts/contracts/",
"pendle-core-v2-public/=lib/euler-price-oracle/lib/pendle-core-v2-public/contracts/",
"pyth-sdk-solidity/=lib/euler-price-oracle/lib/pyth-sdk-solidity/",
"redstone-oracles-monorepo/=lib/euler-price-oracle/lib/",
"solady/=lib/euler-price-oracle/lib/solady/src/",
"solidity-stringutils/=lib/forge-safe/lib/surl/lib/solidity-stringutils/",
"solmate/=lib/forge-safe/lib/solmate/src/",
"surl/=lib/forge-safe/lib/surl/",
"v3-core/=lib/euler-price-oracle/lib/v3-core/contracts/",
"v3-periphery/=lib/euler-price-oracle/lib/v3-periphery/contracts/"
],
"optimizer": {
"enabled": true,
"runs": 20000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": false
}
}}
Submitted on: 2025-09-17 12:30:15
Comments
Log in to comment.
No comments yet.