Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 19662307 | 166 days ago | IN | 0 ETH | 0.02377997 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
FeePolicy
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 750 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.20; import { IFeePolicy } from "./_interfaces/IFeePolicy.sol"; import { SubscriptionParams } from "./_interfaces/CommonTypes.sol"; import { InvalidPerc, InvalidTargetSRBounds, InvalidDRBounds, InvalidSigmoidAsymptotes } from "./_interfaces/ProtocolErrors.sol"; import { MathUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol"; import { SafeCastUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import { Sigmoid } from "./_utils/Sigmoid.sol"; /** * @title FeePolicy * * @notice This contract determines fees for interacting with the perp and vault systems. * * The fee policy attempts to balance the demand for holding perp tokens with * the demand for holding vault tokens; such that the total collateral in the vault * supports rolling over all mature collateral backing perps. * * Fees are computed based on the deviation between the system's current subscription ratio * and the target subscription ratio. * - `subscriptionRatio` = (vaultTVL * seniorTR) / (perpTVL * 1-seniorTR) * - `deviationRatio` (dr) = subscriptionRatio / targetSubscriptionRatio * * When the system is "under-subscribed" (dr <= 1): * - Rollover fees flow from perp holders to vault note holders. * - Fees are charged for minting new perps. * - No fees are charged for redeeming perps. * * When the system is "over-subscribed" (dr > 1): * - Rollover fees flow from vault note holders to perp holders. * - No fees are charged for minting new perps. * - Fees are charged for redeeming perps. * * Regardless of the `deviationRatio`, the system charges a fixed percentage fee * for minting and redeeming vault notes. * * * The rollover fees are signed and can flow in either direction based on the `deviationRatio`. * The fee is a percentage is computed through a sigmoid function. * The slope and asymptotes are set by the owner. * * CRITICAL: The rollover fee percentage is NOT annualized, the fee percentage is applied per rollover. * The number of rollovers per year changes based on the duration of perp's minting bond. * * We consider a `deviationRatio` of greater than 1.0 healthy (or "over-subscribed"). * In general, the system favors an elastic perp supply and an inelastic vault note supply. * * */ contract FeePolicy is IFeePolicy, OwnableUpgradeable { // Libraries using MathUpgradeable for uint256; using SafeCastUpgradeable for uint256; // Replicating value used here: // https://github.com/buttonwood-protocol/tranche/blob/main/contracts/BondController.sol uint256 private constant TRANCHE_RATIO_GRANULARITY = 1000; /// @notice The returned fee percentages are fixed point numbers with {DECIMALS} places. /// @dev The decimals should line up with value expected by consumer (perp, vault). /// NOTE: 10**DECIMALS => 100% or 1.0 uint8 public constant DECIMALS = 8; /// @notice Fixed point representation of 1.0 or 100%. uint256 public constant ONE = (1 * 10 ** DECIMALS); /// @notice Sigmoid asymptote bound. /// @dev Set to 0.05 or 5%, i.e) the rollover fee can be at most 5% on either direction. uint256 public constant SIGMOID_BOUND = ONE / 20; /// @notice Target subscription ratio lower bound, 0.75 or 75%. uint256 public constant TARGET_SR_LOWER_BOUND = (ONE * 75) / 100; /// @notice Target subscription ratio higher bound, 2.0 or 200%. uint256 public constant TARGET_SR_UPPER_BOUND = 2 * ONE; //----------------------------------------------------------------------------- /// @notice The target subscription ratio i.e) the normalization factor. /// @dev The ratio under which the system is considered "under-subscribed". /// Adds a safety buffer to ensure that rollovers are better sustained. uint256 public targetSubscriptionRatio; /// @notice The lower bound of deviation ratio, below which some operations (which decrease the dr) are disabled. uint256 public deviationRatioBoundLower; /// @notice The upper bound of deviation ratio, above which some operations (which increase the dr) are disabled. uint256 public deviationRatioBoundUpper; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Perp fee parameters /// @notice The percentage fee charged on minting perp tokens. uint256 public perpMintFeePerc; /// @notice The percentage fee charged on burning perp tokens. uint256 public perpBurnFeePerc; struct RolloverFeeSigmoidParams { /// @notice Lower asymptote int256 lower; /// @notice Upper asymptote int256 upper; /// @notice sigmoid slope int256 growth; } /// @notice Parameters which control the asymptotes and the slope of the perp token's rollover fee. RolloverFeeSigmoidParams public perpRolloverFee; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Vault fee parameters /// @notice The percentage fee charged on minting vault notes. uint256 public vaultMintFeePerc; /// @notice The percentage fee charged on burning vault notes. uint256 public vaultBurnFeePerc; /// @notice The percentage fee charged by the vault to swap underlying tokens for perp tokens. uint256 public vaultUnderlyingToPerpSwapFeePerc; /// @notice The percentage fee charged by the vault to swap perp tokens for underlying tokens. uint256 public vaultPerpToUnderlyingSwapFeePerc; //----------------------------------------------------------------------------- /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } /// @notice Contract initializer. function init() external initializer { __Ownable_init(); // initializing mint/burn fees to zero perpMintFeePerc = 0; perpBurnFeePerc = 0; vaultMintFeePerc = 0; vaultBurnFeePerc = 0; // initializing swap fees to 100%, to disable swapping initially vaultUnderlyingToPerpSwapFeePerc = ONE; vaultPerpToUnderlyingSwapFeePerc = ONE; // NOTE: With the current bond length of 28 days, rollover rate is annualized by dividing by: 365/28 ~= 13 perpRolloverFee.lower = -int256(ONE) / (30 * 13); // -0.033/13 = -0.00253 (3.3% annualized) perpRolloverFee.upper = int256(ONE) / (10 * 13); // 0.1/13 = 0.00769 (10% annualized) perpRolloverFee.growth = 5 * int256(ONE); // 5.0 targetSubscriptionRatio = (ONE * 133) / 100; // 1.33 deviationRatioBoundLower = (ONE * 75) / 100; // 0.75 deviationRatioBoundUpper = 2 * ONE; // 2.0 } //----------------------------------------------------------------------------- // Owner only /// @notice Updates the target subscription ratio. /// @param targetSubscriptionRatio_ The new target subscription ratio as a fixed point number with {DECIMALS} places. function updateTargetSubscriptionRatio(uint256 targetSubscriptionRatio_) external onlyOwner { if (targetSubscriptionRatio_ < TARGET_SR_LOWER_BOUND || targetSubscriptionRatio_ > TARGET_SR_UPPER_BOUND) { revert InvalidTargetSRBounds(); } targetSubscriptionRatio = targetSubscriptionRatio_; } /// @notice Updates the deviation ratio bounds. /// @param deviationRatioBoundLower_ The new lower deviation ratio bound as fixed point number with {DECIMALS} places. /// @param deviationRatioBoundUpper_ The new upper deviation ratio bound as fixed point number with {DECIMALS} places. function updateDeviationRatioBounds( uint256 deviationRatioBoundLower_, uint256 deviationRatioBoundUpper_ ) external onlyOwner { if (deviationRatioBoundLower_ > ONE || deviationRatioBoundUpper_ < ONE) { revert InvalidDRBounds(); } deviationRatioBoundLower = deviationRatioBoundLower_; deviationRatioBoundUpper = deviationRatioBoundUpper_; } /// @notice Updates the perp mint fee parameters. /// @param perpMintFeePerc_ The new perp mint fee ceiling percentage /// as a fixed point number with {DECIMALS} places. function updatePerpMintFees(uint256 perpMintFeePerc_) external onlyOwner { if (perpMintFeePerc_ > ONE) { revert InvalidPerc(); } perpMintFeePerc = perpMintFeePerc_; } /// @notice Updates the perp burn fee parameters. /// @param perpBurnFeePerc_ The new perp burn fee ceiling percentage /// as a fixed point number with {DECIMALS} places. function updatePerpBurnFees(uint256 perpBurnFeePerc_) external onlyOwner { if (perpBurnFeePerc_ > ONE) { revert InvalidPerc(); } perpBurnFeePerc = perpBurnFeePerc_; } /// @notice Update the parameters determining the slope and asymptotes of the sigmoid fee curve. /// @param p Lower, Upper and Growth sigmoid paramters are fixed point numbers with {DECIMALS} places. function updatePerpRolloverFees(RolloverFeeSigmoidParams calldata p) external onlyOwner { // If the bond duration is 28 days and 13 rollovers happen per year, // perp can be inflated or enriched up to ~65% annually. if (p.lower < -int256(SIGMOID_BOUND) || p.upper > int256(SIGMOID_BOUND) || p.lower > p.upper) { revert InvalidSigmoidAsymptotes(); } perpRolloverFee.lower = p.lower; perpRolloverFee.upper = p.upper; perpRolloverFee.growth = p.growth; } /// @notice Updates the vault mint fee parameters. /// @param vaultMintFeePerc_ The new vault mint fee ceiling percentage /// as a fixed point number with {DECIMALS} places. function updateVaultMintFees(uint256 vaultMintFeePerc_) external onlyOwner { if (vaultMintFeePerc_ > ONE) { revert InvalidPerc(); } vaultMintFeePerc = vaultMintFeePerc_; } /// @notice Updates the vault burn fee parameters. /// @param vaultBurnFeePerc_ The new vault burn fee ceiling percentage /// as a fixed point number with {DECIMALS} places. function updateVaultBurnFees(uint256 vaultBurnFeePerc_) external onlyOwner { if (vaultBurnFeePerc_ > ONE) { revert InvalidPerc(); } vaultBurnFeePerc = vaultBurnFeePerc_; } /// @notice Updates the vault's share of the underlying to perp swap fee. /// @param feePerc The new fee percentage. function updateVaultUnderlyingToPerpSwapFeePerc(uint256 feePerc) external onlyOwner { if (feePerc > ONE) { revert InvalidPerc(); } vaultUnderlyingToPerpSwapFeePerc = feePerc; } /// @notice Updates the vault's share of the perp to underlying swap fee. /// @param feePerc The new fee percentage. function updateVaultPerpToUnderlyingSwapFeePerc(uint256 feePerc) external onlyOwner { if (feePerc > ONE) { revert InvalidPerc(); } vaultPerpToUnderlyingSwapFeePerc = feePerc; } //----------------------------------------------------------------------------- // Public methods /// @inheritdoc IFeePolicy /// @dev Minting perps reduces system dr, i.e) drPost < drPre. function computePerpMintFeePerc() public view override returns (uint256) { return perpMintFeePerc; } /// @inheritdoc IFeePolicy /// @dev Burning perps increases system dr, i.e) drPost > drPre. function computePerpBurnFeePerc() public view override returns (uint256) { return perpBurnFeePerc; } /// @inheritdoc IFeePolicy function computePerpRolloverFeePerc(uint256 dr) external view override returns (int256) { return Sigmoid.compute( dr.toInt256(), perpRolloverFee.lower, perpRolloverFee.upper, perpRolloverFee.growth, ONE.toInt256() ); } /// @inheritdoc IFeePolicy /// @dev Minting vault notes increases system dr, i.e) drPost > drPre. function computeVaultMintFeePerc() external view override returns (uint256) { return vaultMintFeePerc; } /// @inheritdoc IFeePolicy function computeVaultBurnFeePerc() external view override returns (uint256) { return vaultBurnFeePerc; } /// @inheritdoc IFeePolicy /// @dev Swapping by minting perps reduces system dr, i.e) drPost < drPre. function computeUnderlyingToPerpVaultSwapFeePerc( uint256 /*drPre*/, uint256 drPost ) external view override returns (uint256) { // When the after op deviation ratio is below the bound, // swapping is disabled. (fees are set to 100%) return (drPost < deviationRatioBoundLower ? ONE : vaultUnderlyingToPerpSwapFeePerc); } /// @inheritdoc IFeePolicy /// @dev Swapping by burning perps increases system dr, i.e) drPost > drPre. function computePerpToUnderlyingVaultSwapFeePerc( uint256 /*drPre*/, uint256 drPost ) external view override returns (uint256) { // When the after op deviation ratio is above the bound, // swapping is disabled. (fees are set to 100%) return (drPost > deviationRatioBoundUpper ? ONE : vaultPerpToUnderlyingSwapFeePerc); } /// @inheritdoc IFeePolicy function decimals() external pure override returns (uint8) { return DECIMALS; } /// @inheritdoc IFeePolicy function computeDeviationRatio(SubscriptionParams memory s) public view returns (uint256) { // NOTE: We assume that perp's TVL and vault's TVL values have the same base denomination. uint256 juniorTR = TRANCHE_RATIO_GRANULARITY - s.seniorTR; return (s.vaultTVL * s.seniorTR).mulDiv(ONE, (s.perpTVL * juniorTR)).mulDiv(ONE, targetSubscriptionRatio); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCastUpgradeable { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMathUpgradeable { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; struct TokenAmount { /// @notice The asset token redeemed. IERC20Upgradeable token; /// @notice The amount redeemed. uint256 amount; } /// @notice The system subscription parameters. struct SubscriptionParams { /// @notice The current TVL of perp denominated in the underlying. uint256 perpTVL; /// @notice The current TVL of the vault denominated in the underlying. uint256 vaultTVL; /// @notice The tranche ratio of seniors accepted by perp. uint256 seniorTR; } struct RolloverData { /// @notice The amount of tokens rolled out. uint256 tokenOutAmt; /// @notice The amount of trancheIn tokens rolled in. uint256 trancheInAmt; }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; import { SubscriptionParams } from "./CommonTypes.sol"; interface IFeePolicy { /// @return The percentage of the mint perp tokens to be charged as fees, /// as a fixed-point number with {DECIMALS} decimal places. function computePerpMintFeePerc() external view returns (uint256); /// @return The percentage of the burnt perp tokens to be charged as fees, /// as a fixed-point number with {DECIMALS} decimal places. function computePerpBurnFeePerc() external view returns (uint256); /// @param dr The current system deviation ratio. /// @return The applied exchange rate adjustment between tranches into perp and /// tokens out of perp during a rollover, /// as a fixed-point number with {DECIMALS} decimal places. /// @dev - A fee of 0%, implies the rollover exchange rate is unaltered. /// example) 100 tranchesIn for 100 tranchesOut /// - A fee of 1%, implies the exchange rate is adjusted in favor of tranchesIn. /// example) 100 tranchesIn for 99 tranchesOut; i.e) perp enrichment /// - A fee of -1%, implies the exchange rate is adjusted in favor of tranchesOut. /// example) 99 tranchesIn for 100 tranchesOut function computePerpRolloverFeePerc(uint256 dr) external view returns (int256); /// @return The percentage of the mint vault note amount to be charged as fees, /// as a fixed-point number with {DECIMALS} decimal places. function computeVaultMintFeePerc() external view returns (uint256); /// @return The percentage of the burnt vault note amount to be charged as fees, /// as a fixed-point number with {DECIMALS} decimal places. function computeVaultBurnFeePerc() external view returns (uint256); /// @param dr The current system deviation ratio. /// @param dr_ The deviation ratio of the system after the operation is complete. /// @return The percentage of perp tokens out to be charged as swap fees by the vault, /// as a fixed-point numbers with {DECIMALS} decimal places. function computeUnderlyingToPerpVaultSwapFeePerc(uint256 dr, uint256 dr_) external view returns (uint256); /// @param dr The current system deviation ratio. /// @param dr_ The deviation ratio of the system after the operation is complete. /// @return The percentage of underlying tokens out to be charged as swap fees by the vault, /// as a fixed-point numbers with {DECIMALS} decimal places. function computePerpToUnderlyingVaultSwapFeePerc(uint256 dr, uint256 dr_) external view returns (uint256); /// @return Number of decimals representing a multiplier of 1.0. So, 100% = 1*10**decimals. function decimals() external view returns (uint8); /// @param s The subscription parameters of both the perp and vault systems. /// @return The deviation ratio given the system subscription parameters. function computeDeviationRatio(SubscriptionParams memory s) external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.20; //------------------------------------------------------------------------- // Generic /// @notice Expected contract call to be triggered by authorized caller. error UnauthorizedCall(); /// @notice Expected transfer out asset to not be a reserve asset. error UnauthorizedTransferOut(); /// @notice Expected contract reference to not be `address(0)`. error UnacceptableReference(); /// @notice Expected interface contract to return a fixed point with a different number of decimals. error UnexpectedDecimals(); /// @notice Expected asset to be a valid reserve/vault asset. error UnexpectedAsset(); /// @notice Expected to mint a non-zero amount of notes. error UnacceptableDeposit(); /// @notice Expected to redeem a non-zero amount of notes. error UnacceptableRedemption(); /// @notice Updated parameters violate defined constraints. error UnacceptableParams(); /// @notice Storage array access out of bounds. error OutOfBounds(); /// @notice Expected the number of reserve assets to be under the limit. error ReserveCountOverLimit(); //------------------------------------------------------------------------- // Perp /// @notice Expected rollover to be acceptable. error UnacceptableRollover(); /// @notice Expected supply to be lower than the defined max supply. error ExceededMaxSupply(); /// @notice Expected the total mint amount per tranche to be lower than the limit. error ExceededMaxMintPerTranche(); //------------------------------------------------------------------------- // Vault /// @notice Expected more underlying token liquidity to perform operation. error InsufficientLiquidity(); /// @notice Expected to swap non-zero assets. error UnacceptableSwap(); /// @notice Expected more assets to be deployed. error InsufficientDeployment(); /// @notice Expected the number of vault assets deployed to be under the limit. error DeployedCountOverLimit(); /// @notice Expected parent bond to have only 2 children tranches. error UnacceptableTrancheLength(); //------------------------------------------------------------------------- // Fee Policy /// @notice Expected perc value to be at most (1 * 10**DECIMALS), i.e) 1.0 or 100%. error InvalidPerc(); /// @notice Expected target subscription ratio to be within defined bounds. error InvalidTargetSRBounds(); /// @notice Expected deviation ratio bounds to be valid. error InvalidDRBounds(); /// @notice Expected sigmoid asymptotes to be within defined bounds. error InvalidSigmoidAsymptotes();
// SPDX-License-Identifier: GPL-3.0-or-later // https://github.com/ampleforth/ampleforth-contracts/blob/master/contracts/UFragmentsPolicy.sol pragma solidity ^0.8.20; import { SignedMathUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.sol"; import { SafeCastUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; /// @notice Expected exponent to be at most 100. error ExpTooLarge(); /** * @title Sigmoid * * @notice Library with helper functions to compute y = sigmoid(x). * */ library Sigmoid { using SignedMathUpgradeable for int256; using SafeCastUpgradeable for uint256; /// @notice Computes 2^exp with limited precision where -100 <= exp <= 100 * one /// @param exp The power to raise 2 to -100 <= exp <= 100 * one /// @param one 1.0 represented in the same fixed point number format as exp /// @return 2^exp represented with same number of decimals after the point as one function twoPower(int256 exp, int256 one) internal pure returns (int256) { bool reciprocal = false; if (exp < 0) { reciprocal = true; exp = exp.abs().toInt256(); } // Precomputed values for 2^(1/2^i) in 18 decimals fixed point numbers int256[5] memory ks = [ int256(1414213562373095049), 1189207115002721067, 1090507732665257659, 1044273782427413840, 1021897148654116678 ]; int256 whole = exp / one; if (whole > 100) { revert ExpTooLarge(); } int256 result = int256(uint256(1) << uint256(whole)) * one; int256 remaining = exp - (whole * one); int256 current = one / 2; for (uint256 i = 0; i < 5; ++i) { if (remaining >= current) { remaining = remaining - current; result = (result * ks[i]) / 10 ** 18; // 10**18 to match hardcoded ks values } current = current / 2; } if (reciprocal) { result = (one * one) / result; } return result; } /// @notice Given number x and sigmoid parameters all represented as fixed-point number with /// the same number of decimals, it computes y = sigmoid(x). /// @param x The sigmoid function input value. /// @param lower The lower asymptote. /// @param upper The upper asymptote. /// @param growth The growth parameter. /// @param one 1.0 as a fixed-point. /// @return The computed value of sigmoid(x) as fixed-point number. function compute(int256 x, int256 lower, int256 upper, int256 growth, int256 one) internal pure returns (int256) { int256 delta; delta = x - one; // Compute: (Upper-Lower)/(1-(Upper/Lower)/2^(Growth*delta))) + Lower int256 exponent = (growth * delta) / one; // Cap exponent to guarantee it is not too big for twoPower if (exponent > one * 100) { exponent = one * 100; } if (exponent < one * -100) { exponent = one * -100; } int256 pow = twoPower(exponent, one); // 2^(Growth*Delta) if (pow == 0) { return lower; } int256 numerator = upper - lower; //(Upper-Lower) int256 intermediate = (upper * one) / lower; intermediate = (intermediate * one) / pow; int256 denominator = one - intermediate; // (1-(Upper/Lower)/2^(Growth*delta))) int256 y = ((numerator * one) / denominator) + lower; return y; } }
{ "optimizer": { "enabled": true, "runs": 750 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ExpTooLarge","type":"error"},{"inputs":[],"name":"InvalidDRBounds","type":"error"},{"inputs":[],"name":"InvalidPerc","type":"error"},{"inputs":[],"name":"InvalidSigmoidAsymptotes","type":"error"},{"inputs":[],"name":"InvalidTargetSRBounds","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGMOID_BOUND","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TARGET_SR_LOWER_BOUND","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TARGET_SR_UPPER_BOUND","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"perpTVL","type":"uint256"},{"internalType":"uint256","name":"vaultTVL","type":"uint256"},{"internalType":"uint256","name":"seniorTR","type":"uint256"}],"internalType":"struct SubscriptionParams","name":"s","type":"tuple"}],"name":"computeDeviationRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"computePerpBurnFeePerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"computePerpMintFeePerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"dr","type":"uint256"}],"name":"computePerpRolloverFeePerc","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"drPost","type":"uint256"}],"name":"computePerpToUnderlyingVaultSwapFeePerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"drPost","type":"uint256"}],"name":"computeUnderlyingToPerpVaultSwapFeePerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"computeVaultBurnFeePerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"computeVaultMintFeePerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"deviationRatioBoundLower","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deviationRatioBoundUpper","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"perpBurnFeePerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"perpMintFeePerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"perpRolloverFee","outputs":[{"internalType":"int256","name":"lower","type":"int256"},{"internalType":"int256","name":"upper","type":"int256"},{"internalType":"int256","name":"growth","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"targetSubscriptionRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"deviationRatioBoundLower_","type":"uint256"},{"internalType":"uint256","name":"deviationRatioBoundUpper_","type":"uint256"}],"name":"updateDeviationRatioBounds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"perpBurnFeePerc_","type":"uint256"}],"name":"updatePerpBurnFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"perpMintFeePerc_","type":"uint256"}],"name":"updatePerpMintFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"int256","name":"lower","type":"int256"},{"internalType":"int256","name":"upper","type":"int256"},{"internalType":"int256","name":"growth","type":"int256"}],"internalType":"struct FeePolicy.RolloverFeeSigmoidParams","name":"p","type":"tuple"}],"name":"updatePerpRolloverFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"targetSubscriptionRatio_","type":"uint256"}],"name":"updateTargetSubscriptionRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultBurnFeePerc_","type":"uint256"}],"name":"updateVaultBurnFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultMintFeePerc_","type":"uint256"}],"name":"updateVaultMintFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"feePerc","type":"uint256"}],"name":"updateVaultPerpToUnderlyingSwapFeePerc","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"feePerc","type":"uint256"}],"name":"updateVaultUnderlyingToPerpSwapFeePerc","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultBurnFeePerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultMintFeePerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultPerpToUnderlyingSwapFeePerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultUnderlyingToPerpSwapFeePerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061001961001e565b6100dd565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100db576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61158c806100ec6000396000f3fe608060405234801561001057600080fd5b50600436106102775760003560e01c806380f4071d11610160578063bf39d3db116100d8578063cb28e6161161008c578063e1c7392a11610071578063e1c7392a14610481578063f2fde38b14610489578063febadc331461049c57600080fd5b8063cb28e61614610465578063d65f9c1b1461046e57600080fd5b8063c456c98d116100bd578063c456c98d14610441578063c845119f14610454578063ca9cbcbe1461045d57600080fd5b8063bf39d3db14610426578063c2ee3a081461043957600080fd5b8063916b7ed71161012f578063a7cd3cae11610114578063a7cd3cae146103f7578063b7b3d6ab1461040a578063bbff6d601461041d57600080fd5b8063916b7ed7146103e6578063a43c02c2146103ee57600080fd5b806380f4071d1461039d5780638b83535b146103b05780638c8c479f146103c35780638da5cb5b146103cb57600080fd5b80633ecdab70116101f35780636978ed06116101c2578063715018a6116101a7578063715018a6146103845780637a6af7091461038c578063807e43a41461039457600080fd5b80636978ed06146103695780636afaaaad1461037c57600080fd5b80633ecdab701461031857806346ebcf23146103455780634cc7933a1461034d5780635a3445f41461035657600080fd5b806323430e821161024a578063313ce5671161022f578063313ce567146102f55780633b20fe20146102fc5780633d2cf35c1461030f57600080fd5b806323430e82146102d25780632e0f2625146102db57600080fd5b806301356c8c1461027c5780630a98b70d146102a25780630e14d481146102aa57806316bb8c46146102bf575b600080fd5b61028f61028a36600461121b565b6104a5565b6040519081526020015b60405180910390f35b60685461028f565b6102bd6102b8366004611285565b610522565b005b6102bd6102cd3660046112a7565b61058c565b61028f606d5481565b6102e3600881565b60405160ff9091168152602001610299565b60086102e3565b6102bd61030a3660046112a7565b6105d0565b61028f60665481565b606a54606b54606c5461032a92919083565b60408051938452602084019290925290820152606001610299565b606d5461028f565b61028f60675481565b6102bd6103643660046112c0565b610614565b61028f610377366004611285565b6106be565b61028f6106f1565b6102bd610716565b61028f61072a565b61028f60695481565b6102bd6103ab3660046112a7565b610758565b61028f6103be3660046112a7565b61079c565b61028f6107d7565b6033546040516001600160a01b039091168152602001610299565b606e5461028f565b61028f606e5481565b6102bd6104053660046112a7565b6107f0565b6102bd6104183660046112a7565b610834565b61028f606f5481565b61028f610434366004611285565b610878565b61028f61088b565b6102bd61044f3660046112a7565b6108a2565b61028f60705481565b60695461028f565b61028f60655481565b6102bd61047c3660046112a7565b6108e6565b6102bd61096c565b6102bd6104973660046112d8565b610bdb565b61028f60685481565b60008082604001516103e86104ba9190611317565b905061051b6104cb6008600a61140e565b6104d690600161141d565b6065546105146104e86008600a61140e565b6104f390600161141d565b875161050090879061141d565b88604001518960200151610514919061141d565b9190610c51565b9392505050565b61052a610d42565b6105366008600a61140e565b61054190600161141d565b82118061056357506105556008600a61140e565b61056090600161141d565b81105b156105815760405163ca520b2d60e01b815260040160405180910390fd5b606691909155606755565b610594610d42565b6105a06008600a61140e565b6105ab90600161141d565b8111156105cb576040516366e3134960e11b815260040160405180910390fd5b606955565b6105d8610d42565b6105e46008600a61140e565b6105ef90600161141d565b81111561060f576040516366e3134960e11b815260040160405180910390fd5b606e55565b61061c610d42565b601461062a6008600a61140e565b61063590600161141d565b61063f919061144a565b6106489061145e565b8135128061067b5750601461065f6008600a61140e565b61066a90600161141d565b610674919061144a565b8160200135135b8061068a575060208101358135135b156106a8576040516382a7157760e01b815260040160405180910390fd5b8035606a556020810135606b5560400135606c55565b600060665482106106d157606f546106e8565b6106dd6008600a61140e565b6106e890600161141d565b90505b92915050565b6106fd6008600a61140e565b61070890600161141d565b61071390600261141d565b81565b61071e610d42565b6107286000610d9c565b565b60646107386008600a61140e565b61074390600161141d565b61074e90604b61141d565b610713919061144a565b610760610d42565b61076c6008600a61140e565b61077790600161141d565b811115610797576040516366e3134960e11b815260040160405180910390fd5b606f55565b60006106eb6107aa83610e06565b606a54606b54606c546107d26107c26008600a61140e565b6107cd90600161141d565b610e06565b610ea2565b60146107e56008600a61140e565b61074e90600161141d565b6107f8610d42565b6108046008600a61140e565b61080f90600161141d565b81111561082f576040516366e3134960e11b815260040160405180910390fd5b606855565b61083c610d42565b6108486008600a61140e565b61085390600161141d565b811115610873576040516366e3134960e11b815260040160405180910390fd5b606d55565b600060675482116106d1576070546106e8565b6108976008600a61140e565b61071390600161141d565b6108aa610d42565b6108b66008600a61140e565b6108c190600161141d565b8111156108e1576040516366e3134960e11b815260040160405180910390fd5b607055565b6108ee610d42565b60646108fc6008600a61140e565b61090790600161141d565b61091290604b61141d565b61091c919061144a565b81108061094957506109306008600a61140e565b61093b90600161141d565b61094690600261141d565b81115b156109675760405163d442f13960e01b815260040160405180910390fd5b606555565b600054610100900460ff161580801561098c5750600054600160ff909116105b806109a65750303b1580156109a6575060005460ff166001145b610a1d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b6000805460ff191660011790558015610a40576000805461ff0019166101001790555b610a48610fae565b600060688190556069819055606d819055606e55610a686008600a61140e565b610a7390600161141d565b606f55610a826008600a61140e565b610a8d90600161141d565b607055610186610a9f6008600a61140e565b610aaa90600161141d565b610ab39061145e565b610abd919061147a565b606a556082610ace6008600a61140e565b610ad990600161141d565b610ae3919061147a565b606b55610af26008600a61140e565b610afd90600161141d565b610b089060056114a8565b606c556064610b196008600a61140e565b610b2490600161141d565b610b2f90608561141d565b610b39919061144a565b6065556064610b4a6008600a61140e565b610b5590600161141d565b610b6090604b61141d565b610b6a919061144a565b606655610b796008600a61140e565b610b8490600161141d565b610b8f90600261141d565b6067558015610bd8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b610be3610d42565b6001600160a01b038116610c485760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a14565b610bd881610d9c565b6000808060001985870985870292508281108382030391505080600003610c8b57838281610c8157610c81611434565b049250505061051b565b808411610cda5760405162461bcd60e51b815260206004820152601560248201527f4d6174683a206d756c446976206f766572666c6f7700000000000000000000006044820152606401610a14565b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6033546001600160a01b031633146107285760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a14565b603380546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821115610e9e5760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e206160448201527f6e20696e743235360000000000000000000000000000000000000000000000006064820152608401610a14565b5090565b600080610eaf83886114d8565b9050600083610ebe83876114a8565b610ec8919061147a565b9050610ed58460646114a8565b811315610eea57610ee78460646114a8565b90505b610ef6846063196114a8565b811215610f0c57610f09846063196114a8565b90505b6000610f188286611021565b905080600003610f2d57879350505050610fa5565b6000610f3989896114d8565b9050600089610f48888b6114a8565b610f52919061147a565b905082610f5f88836114a8565b610f69919061147a565b90506000610f7782896114d8565b905060008b82610f878b876114a8565b610f91919061147a565b610f9b91906114ff565b9750505050505050505b95945050505050565b600054610100900460ff166110195760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610a14565b610728611194565b6000808084121561103e5750600161103b6107cd85611208565b93505b6040805160a0810182526713a04bbdfdc9be898152671080e992061ab32b6020820152670f2243014e544ebb91810191909152670e7e0178e9d6ed506060820152670e2e820ade835f4660808201526000611099858761147a565b905060648113156110bd57604051638fb5dec560e01b815260040160405180910390fd5b60006110cc866001841b6114a8565b905060006110da87846114a8565b6110e490896114d8565b905060006110f360028961147a565b905060005b60058110156111685781831261114b5761111282846114d8565b9250670de0b6b3a764000086826005811061112f5761112f611527565b602002015161113e90866114a8565b611148919061147a565b93505b61115660028361147a565b91506111618161153d565b90506110f8565b508515611187578261117a89806114a8565b611184919061147a565b92505b5090979650505050505050565b600054610100900460ff166111ff5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610a14565b61072833610d9c565b600080821215610e9e57816000036106eb565b60006060828403121561122d57600080fd5b6040516060810181811067ffffffffffffffff8211171561125e57634e487b7160e01b600052604160045260246000fd5b80604052508235815260208301356020820152604083013560408201528091505092915050565b6000806040838503121561129857600080fd5b50508035926020909101359150565b6000602082840312156112b957600080fd5b5035919050565b6000606082840312156112d257600080fd5b50919050565b6000602082840312156112ea57600080fd5b81356001600160a01b038116811461051b57600080fd5b634e487b7160e01b600052601160045260246000fd5b818103818111156106eb576106eb611301565b600181815b8085111561136557816000190482111561134b5761134b611301565b8085161561135857918102915b93841c939080029061132f565b509250929050565b60008261137c575060016106eb565b81611389575060006106eb565b816001811461139f57600281146113a9576113c5565b60019150506106eb565b60ff8411156113ba576113ba611301565b50506001821b6106eb565b5060208310610133831016604e8410600b84101617156113e8575081810a6106eb565b6113f2838361132a565b806000190482111561140657611406611301565b029392505050565b60006106e860ff84168361136d565b80820281158282048414176106eb576106eb611301565b634e487b7160e01b600052601260045260246000fd5b60008261145957611459611434565b500490565b6000600160ff1b820161147357611473611301565b5060000390565b60008261148957611489611434565b600160ff1b8214600019841416156114a3576114a3611301565b500590565b80820260008212600160ff1b841416156114c4576114c4611301565b81810583148215176106eb576106eb611301565b81810360008312801583831316838312821617156114f8576114f8611301565b5092915050565b808201828112600083128015821682158216171561151f5761151f611301565b505092915050565b634e487b7160e01b600052603260045260246000fd5b60006001820161154f5761154f611301565b506001019056fea264697066735822122090f5ceaeff5e505f86e0d9f4916b48f4833864f88f1f36f0dc6c50e9ac5f8c1d64736f6c63430008140033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102775760003560e01c806380f4071d11610160578063bf39d3db116100d8578063cb28e6161161008c578063e1c7392a11610071578063e1c7392a14610481578063f2fde38b14610489578063febadc331461049c57600080fd5b8063cb28e61614610465578063d65f9c1b1461046e57600080fd5b8063c456c98d116100bd578063c456c98d14610441578063c845119f14610454578063ca9cbcbe1461045d57600080fd5b8063bf39d3db14610426578063c2ee3a081461043957600080fd5b8063916b7ed71161012f578063a7cd3cae11610114578063a7cd3cae146103f7578063b7b3d6ab1461040a578063bbff6d601461041d57600080fd5b8063916b7ed7146103e6578063a43c02c2146103ee57600080fd5b806380f4071d1461039d5780638b83535b146103b05780638c8c479f146103c35780638da5cb5b146103cb57600080fd5b80633ecdab70116101f35780636978ed06116101c2578063715018a6116101a7578063715018a6146103845780637a6af7091461038c578063807e43a41461039457600080fd5b80636978ed06146103695780636afaaaad1461037c57600080fd5b80633ecdab701461031857806346ebcf23146103455780634cc7933a1461034d5780635a3445f41461035657600080fd5b806323430e821161024a578063313ce5671161022f578063313ce567146102f55780633b20fe20146102fc5780633d2cf35c1461030f57600080fd5b806323430e82146102d25780632e0f2625146102db57600080fd5b806301356c8c1461027c5780630a98b70d146102a25780630e14d481146102aa57806316bb8c46146102bf575b600080fd5b61028f61028a36600461121b565b6104a5565b6040519081526020015b60405180910390f35b60685461028f565b6102bd6102b8366004611285565b610522565b005b6102bd6102cd3660046112a7565b61058c565b61028f606d5481565b6102e3600881565b60405160ff9091168152602001610299565b60086102e3565b6102bd61030a3660046112a7565b6105d0565b61028f60665481565b606a54606b54606c5461032a92919083565b60408051938452602084019290925290820152606001610299565b606d5461028f565b61028f60675481565b6102bd6103643660046112c0565b610614565b61028f610377366004611285565b6106be565b61028f6106f1565b6102bd610716565b61028f61072a565b61028f60695481565b6102bd6103ab3660046112a7565b610758565b61028f6103be3660046112a7565b61079c565b61028f6107d7565b6033546040516001600160a01b039091168152602001610299565b606e5461028f565b61028f606e5481565b6102bd6104053660046112a7565b6107f0565b6102bd6104183660046112a7565b610834565b61028f606f5481565b61028f610434366004611285565b610878565b61028f61088b565b6102bd61044f3660046112a7565b6108a2565b61028f60705481565b60695461028f565b61028f60655481565b6102bd61047c3660046112a7565b6108e6565b6102bd61096c565b6102bd6104973660046112d8565b610bdb565b61028f60685481565b60008082604001516103e86104ba9190611317565b905061051b6104cb6008600a61140e565b6104d690600161141d565b6065546105146104e86008600a61140e565b6104f390600161141d565b875161050090879061141d565b88604001518960200151610514919061141d565b9190610c51565b9392505050565b61052a610d42565b6105366008600a61140e565b61054190600161141d565b82118061056357506105556008600a61140e565b61056090600161141d565b81105b156105815760405163ca520b2d60e01b815260040160405180910390fd5b606691909155606755565b610594610d42565b6105a06008600a61140e565b6105ab90600161141d565b8111156105cb576040516366e3134960e11b815260040160405180910390fd5b606955565b6105d8610d42565b6105e46008600a61140e565b6105ef90600161141d565b81111561060f576040516366e3134960e11b815260040160405180910390fd5b606e55565b61061c610d42565b601461062a6008600a61140e565b61063590600161141d565b61063f919061144a565b6106489061145e565b8135128061067b5750601461065f6008600a61140e565b61066a90600161141d565b610674919061144a565b8160200135135b8061068a575060208101358135135b156106a8576040516382a7157760e01b815260040160405180910390fd5b8035606a556020810135606b5560400135606c55565b600060665482106106d157606f546106e8565b6106dd6008600a61140e565b6106e890600161141d565b90505b92915050565b6106fd6008600a61140e565b61070890600161141d565b61071390600261141d565b81565b61071e610d42565b6107286000610d9c565b565b60646107386008600a61140e565b61074390600161141d565b61074e90604b61141d565b610713919061144a565b610760610d42565b61076c6008600a61140e565b61077790600161141d565b811115610797576040516366e3134960e11b815260040160405180910390fd5b606f55565b60006106eb6107aa83610e06565b606a54606b54606c546107d26107c26008600a61140e565b6107cd90600161141d565b610e06565b610ea2565b60146107e56008600a61140e565b61074e90600161141d565b6107f8610d42565b6108046008600a61140e565b61080f90600161141d565b81111561082f576040516366e3134960e11b815260040160405180910390fd5b606855565b61083c610d42565b6108486008600a61140e565b61085390600161141d565b811115610873576040516366e3134960e11b815260040160405180910390fd5b606d55565b600060675482116106d1576070546106e8565b6108976008600a61140e565b61071390600161141d565b6108aa610d42565b6108b66008600a61140e565b6108c190600161141d565b8111156108e1576040516366e3134960e11b815260040160405180910390fd5b607055565b6108ee610d42565b60646108fc6008600a61140e565b61090790600161141d565b61091290604b61141d565b61091c919061144a565b81108061094957506109306008600a61140e565b61093b90600161141d565b61094690600261141d565b81115b156109675760405163d442f13960e01b815260040160405180910390fd5b606555565b600054610100900460ff161580801561098c5750600054600160ff909116105b806109a65750303b1580156109a6575060005460ff166001145b610a1d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b6000805460ff191660011790558015610a40576000805461ff0019166101001790555b610a48610fae565b600060688190556069819055606d819055606e55610a686008600a61140e565b610a7390600161141d565b606f55610a826008600a61140e565b610a8d90600161141d565b607055610186610a9f6008600a61140e565b610aaa90600161141d565b610ab39061145e565b610abd919061147a565b606a556082610ace6008600a61140e565b610ad990600161141d565b610ae3919061147a565b606b55610af26008600a61140e565b610afd90600161141d565b610b089060056114a8565b606c556064610b196008600a61140e565b610b2490600161141d565b610b2f90608561141d565b610b39919061144a565b6065556064610b4a6008600a61140e565b610b5590600161141d565b610b6090604b61141d565b610b6a919061144a565b606655610b796008600a61140e565b610b8490600161141d565b610b8f90600261141d565b6067558015610bd8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b610be3610d42565b6001600160a01b038116610c485760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a14565b610bd881610d9c565b6000808060001985870985870292508281108382030391505080600003610c8b57838281610c8157610c81611434565b049250505061051b565b808411610cda5760405162461bcd60e51b815260206004820152601560248201527f4d6174683a206d756c446976206f766572666c6f7700000000000000000000006044820152606401610a14565b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6033546001600160a01b031633146107285760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a14565b603380546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821115610e9e5760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e206160448201527f6e20696e743235360000000000000000000000000000000000000000000000006064820152608401610a14565b5090565b600080610eaf83886114d8565b9050600083610ebe83876114a8565b610ec8919061147a565b9050610ed58460646114a8565b811315610eea57610ee78460646114a8565b90505b610ef6846063196114a8565b811215610f0c57610f09846063196114a8565b90505b6000610f188286611021565b905080600003610f2d57879350505050610fa5565b6000610f3989896114d8565b9050600089610f48888b6114a8565b610f52919061147a565b905082610f5f88836114a8565b610f69919061147a565b90506000610f7782896114d8565b905060008b82610f878b876114a8565b610f91919061147a565b610f9b91906114ff565b9750505050505050505b95945050505050565b600054610100900460ff166110195760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610a14565b610728611194565b6000808084121561103e5750600161103b6107cd85611208565b93505b6040805160a0810182526713a04bbdfdc9be898152671080e992061ab32b6020820152670f2243014e544ebb91810191909152670e7e0178e9d6ed506060820152670e2e820ade835f4660808201526000611099858761147a565b905060648113156110bd57604051638fb5dec560e01b815260040160405180910390fd5b60006110cc866001841b6114a8565b905060006110da87846114a8565b6110e490896114d8565b905060006110f360028961147a565b905060005b60058110156111685781831261114b5761111282846114d8565b9250670de0b6b3a764000086826005811061112f5761112f611527565b602002015161113e90866114a8565b611148919061147a565b93505b61115660028361147a565b91506111618161153d565b90506110f8565b508515611187578261117a89806114a8565b611184919061147a565b92505b5090979650505050505050565b600054610100900460ff166111ff5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610a14565b61072833610d9c565b600080821215610e9e57816000036106eb565b60006060828403121561122d57600080fd5b6040516060810181811067ffffffffffffffff8211171561125e57634e487b7160e01b600052604160045260246000fd5b80604052508235815260208301356020820152604083013560408201528091505092915050565b6000806040838503121561129857600080fd5b50508035926020909101359150565b6000602082840312156112b957600080fd5b5035919050565b6000606082840312156112d257600080fd5b50919050565b6000602082840312156112ea57600080fd5b81356001600160a01b038116811461051b57600080fd5b634e487b7160e01b600052601160045260246000fd5b818103818111156106eb576106eb611301565b600181815b8085111561136557816000190482111561134b5761134b611301565b8085161561135857918102915b93841c939080029061132f565b509250929050565b60008261137c575060016106eb565b81611389575060006106eb565b816001811461139f57600281146113a9576113c5565b60019150506106eb565b60ff8411156113ba576113ba611301565b50506001821b6106eb565b5060208310610133831016604e8410600b84101617156113e8575081810a6106eb565b6113f2838361132a565b806000190482111561140657611406611301565b029392505050565b60006106e860ff84168361136d565b80820281158282048414176106eb576106eb611301565b634e487b7160e01b600052601260045260246000fd5b60008261145957611459611434565b500490565b6000600160ff1b820161147357611473611301565b5060000390565b60008261148957611489611434565b600160ff1b8214600019841416156114a3576114a3611301565b500590565b80820260008212600160ff1b841416156114c4576114c4611301565b81810583148215176106eb576106eb611301565b81810360008312801583831316838312821617156114f8576114f8611301565b5092915050565b808201828112600083128015821682158216171561151f5761151f611301565b505092915050565b634e487b7160e01b600052603260045260246000fd5b60006001820161154f5761154f611301565b506001019056fea264697066735822122090f5ceaeff5e505f86e0d9f4916b48f4833864f88f1f36f0dc6c50e9ac5f8c1d64736f6c63430008140033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.