Source Code
Overview
MON Balance
MON Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
VariableVaultFee
Compiler Version
v0.8.30+commit.73712a01
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
import { IVariableVaultFee } from "../interfaces/IVariableVaultFee.sol";
/**
* @title VariableVaultFee
* @author Bhavesh Praveen
* @notice A contract for managing variable fees on vault operations
* @dev This contract allows registration and management of assets with configurable fees.
* Supports both flat and percentage-based fees for deposits and withdrawals.
* Fees can be calculated on raw amounts (before fees) or total amounts (including fees).
*/
contract VariableVaultFee is Ownable, IVariableVaultFee {
using Math for uint256;
/// @notice Mapping to track which assets are registered
/// @dev asset address => registration status
mapping(address => bool) public isAssetRegistered;
/// @notice Mapping to store fee configuration for each registered asset
/// @dev asset address => AssetFeeConfig struct containing fee details
mapping(address => AssetFeeConfig) public assetFee;
/// @notice Denominator used for percentage fee calculations (1e18 = 100%)
uint256 internal constant FEE_DENOMINATOR = 1e18;
/// @notice Maximum allowed percentage fee (5e16 = 5%)
uint256 internal constant MAX_PERCENTAGE_FEE = 5e16; // 5%
// 1e18 => 100%
// 1e17 => 10%
// 1e16 => 1%
// 1e15 => 0.1%
/**
* @notice Initializes the contract with the specified owner
* @param owner The address that will be granted ownership of the contract
*/
constructor(address owner) Ownable(owner) { }
/**
* @notice Validates the asset fee configuration
* @dev Internal function to ensure fee configuration is valid before setting
* @param config The asset fee configuration to validate
* @custom:throws InvalidAssetConfig if fee recipient is zero address or percentage fees exceed maximum
*/
function _validateAssetConfig(AssetFeeConfig memory config) internal pure {
if (config.feeRecipient == address(0)) {
revert InvalidAssetConfig();
}
if (
(
config.depositFee.feeType == FeeType.PERCENTAGE
&& config.depositFee.feeAmount > MAX_PERCENTAGE_FEE
)
|| (
config.withdrawalFee.feeType == FeeType.PERCENTAGE
&& config.withdrawalFee.feeAmount > MAX_PERCENTAGE_FEE
)
|| (
config.instantWithdrawalFee.feeType == FeeType.PERCENTAGE
&& config.instantWithdrawalFee.feeAmount > MAX_PERCENTAGE_FEE
)
|| (
config.flashRedeemFee.feeType == FeeType.PERCENTAGE
&& config.flashRedeemFee.feeAmount > MAX_PERCENTAGE_FEE
)
) {
revert InvalidAssetConfig();
}
}
/**
* @notice Registers a new asset with fee configuration
* @dev Only callable by the contract owner. Asset must not be already registered.
* @param asset The address of the asset to register
* @param config The fee configuration for the asset including deposit/withdrawal fees and fee recipient
* @custom:throws InvalidAsset if asset address is zero
* @custom:throws AssetAlreadyRegistered if asset is already registered
* @custom:throws InvalidAssetConfig if configuration is invalid
* @custom:emits RegisterAsset
*/
function registerAsset(address asset, AssetFeeConfig memory config) public onlyOwner {
if (asset == address(0)) {
revert InvalidAsset();
}
if (isAssetRegistered[asset]) {
revert AssetAlreadyRegistered();
}
_validateAssetConfig(config);
isAssetRegistered[asset] = true;
assetFee[asset] = config;
emit RegisterAsset(_msgSender(), asset, config);
}
/**
* @notice Deregisters an asset and clears its fee configuration
* @dev Only callable by the contract owner. Resets all fee configuration to zero values.
* @param asset The address of the asset to deregister
* @custom:throws InvalidAsset if asset address is zero or asset is not registered
* @custom:emits DeregisterAsset
*/
function deregisterAsset(address asset) external onlyOwner {
if (asset == address(0) || !isAssetRegistered[asset]) {
revert InvalidAsset();
}
isAssetRegistered[asset] = false;
delete assetFee[asset];
emit DeregisterAsset(_msgSender(), asset);
}
/**
* @notice Updates the fee configuration for an existing registered asset
* @dev Only callable by the contract owner. Asset must be already registered.
* @param asset The address of the asset to update
* @param config The new fee configuration for the asset
* @custom:throws InvalidAsset if asset address is zero or asset is not registered
* @custom:throws InvalidAssetConfig if new configuration is invalid
* @custom:emits UpdateAssetFeeConfig
*/
function updateAssetFeeConfig(address asset, AssetFeeConfig memory config) external onlyOwner {
if (asset == address(0) || isAssetRegistered[asset] == false) {
revert InvalidAsset();
}
_validateAssetConfig(config);
AssetFeeConfig memory oldConfig = _getAssetConfig(asset);
assetFee[asset] = config;
emit UpdateAssetFeeConfig(_msgSender(), asset, oldConfig, config);
}
function _getAssetConfig(address asset) internal view returns (AssetFeeConfig memory) {
if (asset == address(0) || !isAssetRegistered[asset]) {
revert InvalidAsset();
}
return assetFee[asset];
}
/**
* @notice Retrieves the fee configuration for a specific operation on an asset
* @dev Internal function to get deposit or withdrawal fee configuration
* @param asset The asset address
* @param operation The type of operation (DEPOSIT or WITHDRAWAL)
* @return FeeConfig The fee configuration for the specified operation
*/
function _getFeeConfig(
address asset,
FeeOperation operation
)
internal
view
returns (FeeConfig memory)
{
AssetFeeConfig memory assetConfig = _getAssetConfig(asset);
if (operation == FeeOperation.DEPOSIT) {
return assetConfig.depositFee;
}
if (operation == FeeOperation.WITHDRAWAL) {
return assetConfig.withdrawalFee;
}
if (operation == FeeOperation.FLASH_REDEEM) {
return assetConfig.flashRedeemFee;
}
return assetConfig.instantWithdrawalFee;
}
function getFeeRecipient(address asset) external view returns (address) {
AssetFeeConfig memory assetConfig = _getAssetConfig(asset);
return assetConfig.feeRecipient;
}
/**
* @notice Calculates the fee to be added to a raw amount (amount without fees)
* @dev Responsibility of the calling contract to ensure that the user holds assets + fee.
* This method simply returns the fee for the asset amount, and does not revert if fee > amount
* @param asset The address of the asset
* @param amount The raw amount (without fees included)
* @param operation The type of operation (DEPOSIT or WITHDRAWAL)
* @return fee The fee amount to be added to the raw amount
* @custom:throws InvalidAsset if asset is zero address or not registered
* @custom:throws InsufficientAmount if amount is zero
*/
function feeOnRaw(
address asset,
uint256 amount,
FeeOperation operation
)
external
view
returns (uint256)
{
if (asset == address(0) || !isAssetRegistered[asset]) {
revert InvalidAsset();
}
if (amount == 0) {
revert ZeroAmount();
}
FeeConfig memory feeConfig = _getFeeConfig(asset, operation);
return _feeOnRaw(amount, feeConfig);
}
/**
* @notice Calculates the fee portion of a total amount (amount that includes fees)
* @dev Used when the total amount already includes fees and you need to extract the fee portion
* @param asset The address of the asset
* @param amount The total amount (including fees)
* @param operation The type of operation (DEPOSIT or WITHDRAWAL)
* @return fee The fee portion of the total amount
* @custom:throws InvalidAsset if asset is zero address or not registered
* @custom:throws InsufficientAmount if amount is zero or if flat fee amount exceeds total assets
*/
function feeOnTotal(
address asset,
uint256 amount,
FeeOperation operation
)
external
view
returns (uint256)
{
if (asset == address(0) || !isAssetRegistered[asset]) {
revert InvalidAsset();
}
if (amount == 0) {
revert ZeroAmount();
}
FeeConfig memory feeConfig = _getFeeConfig(asset, operation);
return _feeOnTotal(amount, feeConfig);
}
/**
* @notice Internal function to calculate fees on raw amounts
* @dev Calculates the fees that should be added to an amount `assets` that does not already include fees.
* Used in {IERC4626-mint} and {IERC4626-withdraw} operations.
* @param assets The raw asset amount
* @param feeConfig The fee configuration to apply
* @return fee The calculated fee amount
*/
function _feeOnRaw(
uint256 assets,
FeeConfig memory feeConfig
)
internal
pure
returns (uint256)
{
if (feeConfig.feeType == FeeType.FLAT) {
return feeConfig.feeAmount;
}
// assume everything after this section is applicable for when feeType == FeeType.PERCENTAGE
if (feeConfig.feeAmount == 0) {
return 0;
}
// fee is non-zero
return assets.mulDiv(feeConfig.feeAmount, FEE_DENOMINATOR, Math.Rounding.Ceil);
}
/**
* @notice Internal function to calculate fees on total amounts
* @dev Calculates the fee part of an amount `assets` that already includes fees.
* Used in {IERC4626-deposit} and {IERC4626-redeem} operations.
* @param assets The total asset amount (including fees)
* @param feeConfig The fee configuration to apply
* @return fee The calculated fee portion
* @custom:throws InsufficientAmount if flat fee amount exceeds total assets
*/
function _feeOnTotal(
uint256 assets,
FeeConfig memory feeConfig
)
internal
pure
returns (uint256)
{
if (feeConfig.feeType == FeeType.FLAT) {
if (feeConfig.feeAmount > assets) {
revert InsufficientAmount();
}
return feeConfig.feeAmount;
}
// assume everything after this section is applicable for when feeType == FeeType.PERCENTAGE
if (feeConfig.feeAmount == 0) {
return 0;
}
// fee is non-zero
return assets.mulDiv(
feeConfig.feeAmount, feeConfig.feeAmount + FEE_DENOMINATOR, Math.Rounding.Ceil
);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.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.
*
* The initial owner is set to the address provided by the deployer. 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 Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @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 {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @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 {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_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);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (utils/math/Math.sol)
pragma solidity ^0.8.20;
import {Panic} from "../Panic.sol";
import {SafeCast} from "./SafeCast.sol";
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Floor, // Toward negative infinity
Ceil, // Toward positive infinity
Trunc, // Toward zero
Expand // Away from zero
}
/**
* @dev Return the 512-bit addition of two uint256.
*
* The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.
*/
function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {
assembly ("memory-safe") {
low := add(a, b)
high := lt(low, a)
}
}
/**
* @dev Return the 512-bit multiplication of two uint256.
*
* The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.
*/
function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {
// 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use
// the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = high * 2²⁵⁶ + low.
assembly ("memory-safe") {
let mm := mulmod(a, b, not(0))
low := mul(a, b)
high := sub(sub(mm, low), lt(mm, low))
}
}
/**
* @dev Returns the addition of two unsigned integers, with a success flag (no overflow).
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
uint256 c = a + b;
success = c >= a;
result = c * SafeCast.toUint(success);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
uint256 c = a - b;
success = c <= a;
result = c * SafeCast.toUint(success);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
uint256 c = a * b;
assembly ("memory-safe") {
// Only true when the multiplication doesn't overflow
// (c / a == b) || (a == 0)
success := or(eq(div(c, a), b), iszero(a))
}
// equivalent to: success ? c : 0
result = c * SafeCast.toUint(success);
}
}
/**
* @dev Returns the division of two unsigned integers, with a success flag (no division by zero).
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
success = b > 0;
assembly ("memory-safe") {
// The `DIV` opcode returns zero when the denominator is 0.
result := div(a, b)
}
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
success = b > 0;
assembly ("memory-safe") {
// The `MOD` opcode returns zero when the denominator is 0.
result := mod(a, b)
}
}
}
/**
* @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.
*/
function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {
(bool success, uint256 result) = tryAdd(a, b);
return ternary(success, result, type(uint256).max);
}
/**
* @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.
*/
function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {
(, uint256 result) = trySub(a, b);
return result;
}
/**
* @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.
*/
function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {
(bool success, uint256 result) = tryMul(a, b);
return ternary(success, result, type(uint256).max);
}
/**
* @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.
*
* IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.
* However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute
* one branch when needed, making this function more expensive.
*/
function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {
unchecked {
// branchless ternary works because:
// b ^ (a ^ b) == a
// b ^ 0 == b
return b ^ ((a ^ b) * SafeCast.toUint(condition));
}
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return ternary(a > b, a, b);
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return ternary(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 towards infinity instead
* of rounding towards zero.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
// Guarantee the same behavior as in a regular Solidity division.
Panic.panic(Panic.DIVISION_BY_ZERO);
}
// The following calculation ensures accurate ceiling division without overflow.
// Since a is non-zero, (a - 1) / b will not overflow.
// The largest possible result occurs when (a - 1) / b is type(uint256).max,
// but the largest value we can obtain is type(uint256).max - 1, which happens
// when a = type(uint256).max and b = 1.
unchecked {
return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);
}
}
/**
* @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
* denominator == 0.
*
* 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 {
(uint256 high, uint256 low) = mul512(x, y);
// Handle non-overflow cases, 256 by 256 division.
if (high == 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 low / denominator;
}
// Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.
if (denominator <= high) {
Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));
}
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [high low].
uint256 remainder;
assembly ("memory-safe") {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
high := sub(high, gt(remainder, low))
low := sub(low, 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.
uint256 twos = denominator & (0 - denominator);
assembly ("memory-safe") {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [high low] by twos.
low := div(low, twos)
// Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from high into low.
low |= high * twos;
// Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such
// that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv ≡ 1 mod 2⁴.
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⁸
inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶
inverse *= 2 - denominator * inverse; // inverse mod 2³²
inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴
inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸
inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶
// 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²⁵⁶. Since the preconditions guarantee that the outcome is
// less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high
// is no longer required.
result = low * inverse;
return result;
}
}
/**
* @dev 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) {
return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);
}
/**
* @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.
*/
function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {
unchecked {
(uint256 high, uint256 low) = mul512(x, y);
if (high >= 1 << n) {
Panic.panic(Panic.UNDER_OVERFLOW);
}
return (high << (256 - n)) | (low >> n);
}
}
/**
* @dev Calculates x * y >> n with full precision, following the selected rounding direction.
*/
function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {
return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);
}
/**
* @dev Calculate the modular multiplicative inverse of a number in Z/nZ.
*
* If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.
* If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.
*
* If the input value is not inversible, 0 is returned.
*
* NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the
* inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.
*/
function invMod(uint256 a, uint256 n) internal pure returns (uint256) {
unchecked {
if (n == 0) return 0;
// The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)
// Used to compute integers x and y such that: ax + ny = gcd(a, n).
// When the gcd is 1, then the inverse of a modulo n exists and it's x.
// ax + ny = 1
// ax = 1 + (-y)n
// ax ≡ 1 (mod n) # x is the inverse of a modulo n
// If the remainder is 0 the gcd is n right away.
uint256 remainder = a % n;
uint256 gcd = n;
// Therefore the initial coefficients are:
// ax + ny = gcd(a, n) = n
// 0a + 1n = n
int256 x = 0;
int256 y = 1;
while (remainder != 0) {
uint256 quotient = gcd / remainder;
(gcd, remainder) = (
// The old remainder is the next gcd to try.
remainder,
// Compute the next remainder.
// Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd
// where gcd is at most n (capped to type(uint256).max)
gcd - remainder * quotient
);
(x, y) = (
// Increment the coefficient of a.
y,
// Decrement the coefficient of n.
// Can overflow, but the result is casted to uint256 so that the
// next value of y is "wrapped around" to a value between 0 and n - 1.
x - y * int256(quotient)
);
}
if (gcd != 1) return 0; // No inverse exists.
return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.
}
}
/**
* @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.
*
* From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is
* prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that
* `a**(p-2)` is the modular multiplicative inverse of a in Fp.
*
* NOTE: this function does NOT check that `p` is a prime greater than `2`.
*/
function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {
unchecked {
return Math.modExp(a, p - 2, p);
}
}
/**
* @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)
*
* Requirements:
* - modulus can't be zero
* - underlying staticcall to precompile must succeed
*
* IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make
* sure the chain you're using it on supports the precompiled contract for modular exponentiation
* at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,
* the underlying function will succeed given the lack of a revert, but the result may be incorrectly
* interpreted as 0.
*/
function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {
(bool success, uint256 result) = tryModExp(b, e, m);
if (!success) {
Panic.panic(Panic.DIVISION_BY_ZERO);
}
return result;
}
/**
* @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).
* It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying
* to operate modulo 0 or if the underlying precompile reverted.
*
* IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain
* you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in
* https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack
* of a revert, but the result may be incorrectly interpreted as 0.
*/
function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {
if (m == 0) return (false, 0);
assembly ("memory-safe") {
let ptr := mload(0x40)
// | Offset | Content | Content (Hex) |
// |-----------|------------|--------------------------------------------------------------------|
// | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 |
// | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 |
// | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 |
// | 0x60:0x7f | value of b | 0x<.............................................................b> |
// | 0x80:0x9f | value of e | 0x<.............................................................e> |
// | 0xa0:0xbf | value of m | 0x<.............................................................m> |
mstore(ptr, 0x20)
mstore(add(ptr, 0x20), 0x20)
mstore(add(ptr, 0x40), 0x20)
mstore(add(ptr, 0x60), b)
mstore(add(ptr, 0x80), e)
mstore(add(ptr, 0xa0), m)
// Given the result < m, it's guaranteed to fit in 32 bytes,
// so we can use the memory scratch space located at offset 0.
success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)
result := mload(0x00)
}
}
/**
* @dev Variant of {modExp} that supports inputs of arbitrary length.
*/
function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {
(bool success, bytes memory result) = tryModExp(b, e, m);
if (!success) {
Panic.panic(Panic.DIVISION_BY_ZERO);
}
return result;
}
/**
* @dev Variant of {tryModExp} that supports inputs of arbitrary length.
*/
function tryModExp(
bytes memory b,
bytes memory e,
bytes memory m
) internal view returns (bool success, bytes memory result) {
if (_zeroBytes(m)) return (false, new bytes(0));
uint256 mLen = m.length;
// Encode call args in result and move the free memory pointer
result = abi.encodePacked(b.length, e.length, mLen, b, e, m);
assembly ("memory-safe") {
let dataPtr := add(result, 0x20)
// Write result on top of args to avoid allocating extra memory.
success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)
// Overwrite the length.
// result.length > returndatasize() is guaranteed because returndatasize() == m.length
mstore(result, mLen)
// Set the memory pointer after the returned data.
mstore(0x40, add(dataPtr, mLen))
}
}
/**
* @dev Returns whether the provided byte array is zero.
*/
function _zeroBytes(bytes memory byteArray) private pure returns (bool) {
for (uint256 i = 0; i < byteArray.length; ++i) {
if (byteArray[i] != 0) {
return false;
}
}
return true;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
* towards zero.
*
* This method is based on Newton's method for computing square roots; the algorithm is restricted to only
* using integer operations.
*/
function sqrt(uint256 a) internal pure returns (uint256) {
unchecked {
// Take care of easy edge cases when a == 0 or a == 1
if (a <= 1) {
return a;
}
// In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a
// sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between
// the current value as `ε_n = | x_n - sqrt(a) |`.
//
// For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root
// of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is
// bigger than any uint256.
//
// By noticing that
// `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`
// we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar
// to the msb function.
uint256 aa = a;
uint256 xn = 1;
if (aa >= (1 << 128)) {
aa >>= 128;
xn <<= 64;
}
if (aa >= (1 << 64)) {
aa >>= 64;
xn <<= 32;
}
if (aa >= (1 << 32)) {
aa >>= 32;
xn <<= 16;
}
if (aa >= (1 << 16)) {
aa >>= 16;
xn <<= 8;
}
if (aa >= (1 << 8)) {
aa >>= 8;
xn <<= 4;
}
if (aa >= (1 << 4)) {
aa >>= 4;
xn <<= 2;
}
if (aa >= (1 << 2)) {
xn <<= 1;
}
// We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).
//
// We can refine our estimation by noticing that the middle of that interval minimizes the error.
// If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).
// This is going to be our x_0 (and ε_0)
xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)
// From here, Newton's method give us:
// x_{n+1} = (x_n + a / x_n) / 2
//
// One should note that:
// x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a
// = ((x_n² + a) / (2 * x_n))² - a
// = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a
// = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)
// = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)
// = (x_n² - a)² / (2 * x_n)²
// = ((x_n² - a) / (2 * x_n))²
// ≥ 0
// Which proves that for all n ≥ 1, sqrt(a) ≤ x_n
//
// This gives us the proof of quadratic convergence of the sequence:
// ε_{n+1} = | x_{n+1} - sqrt(a) |
// = | (x_n + a / x_n) / 2 - sqrt(a) |
// = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |
// = | (x_n - sqrt(a))² / (2 * x_n) |
// = | ε_n² / (2 * x_n) |
// = ε_n² / | (2 * x_n) |
//
// For the first iteration, we have a special case where x_0 is known:
// ε_1 = ε_0² / | (2 * x_0) |
// ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))
// ≤ 2**(2*e-4) / (3 * 2**(e-1))
// ≤ 2**(e-3) / 3
// ≤ 2**(e-3-log2(3))
// ≤ 2**(e-4.5)
//
// For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:
// ε_{n+1} = ε_n² / | (2 * x_n) |
// ≤ (2**(e-k))² / (2 * 2**(e-1))
// ≤ 2**(2*e-2*k) / 2**e
// ≤ 2**(e-2*k)
xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above
xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5
xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9
xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18
xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36
xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72
// Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision
// ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either
// sqrt(a) or sqrt(a) + 1.
return xn - SafeCast.toUint(xn > a / xn);
}
}
/**
* @dev 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);
}
}
/**
* @dev Return the log in base 2 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log2(uint256 x) internal pure returns (uint256 r) {
// If value has upper 128 bits set, log2 result is at least 128
r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;
// If upper 64 bits of 128-bit half set, add 64 to result
r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;
// If upper 32 bits of 64-bit half set, add 32 to result
r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;
// If upper 16 bits of 32-bit half set, add 16 to result
r |= SafeCast.toUint((x >> r) > 0xffff) << 4;
// If upper 8 bits of 16-bit half set, add 8 to result
r |= SafeCast.toUint((x >> r) > 0xff) << 3;
// If upper 4 bits of 8-bit half set, add 4 to result
r |= SafeCast.toUint((x >> r) > 0xf) << 2;
// Shifts value right by the current result and use it as an index into this lookup table:
//
// | x (4 bits) | index | table[index] = MSB position |
// |------------|---------|-----------------------------|
// | 0000 | 0 | table[0] = 0 |
// | 0001 | 1 | table[1] = 0 |
// | 0010 | 2 | table[2] = 1 |
// | 0011 | 3 | table[3] = 1 |
// | 0100 | 4 | table[4] = 2 |
// | 0101 | 5 | table[5] = 2 |
// | 0110 | 6 | table[6] = 2 |
// | 0111 | 7 | table[7] = 2 |
// | 1000 | 8 | table[8] = 3 |
// | 1001 | 9 | table[9] = 3 |
// | 1010 | 10 | table[10] = 3 |
// | 1011 | 11 | table[11] = 3 |
// | 1100 | 12 | table[12] = 3 |
// | 1101 | 13 | table[13] = 3 |
// | 1110 | 14 | table[14] = 3 |
// | 1111 | 15 | table[15] = 3 |
//
// The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the last 16 bytes.
assembly ("memory-safe") {
r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))
}
}
/**
* @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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);
}
}
/**
* @dev Return the log in base 10 of a positive value rounded towards zero.
* 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);
}
}
/**
* @dev Return the log in base 256 of a positive value rounded towards zero.
* 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 x) internal pure returns (uint256 r) {
// If value has upper 128 bits set, log2 result is at least 128
r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;
// If upper 64 bits of 128-bit half set, add 64 to result
r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;
// If upper 32 bits of 64-bit half set, add 32 to result
r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;
// If upper 16 bits of 32-bit half set, add 16 to result
r |= SafeCast.toUint((x >> r) > 0xffff) << 4;
// Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8
return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);
}
/**
* @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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);
}
}
/**
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
*/
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;
/**
* @title IVariableVaultFee
* @notice Interface for managing variable fees on vault operations
* @dev Supports both flat and percentage-based fees for deposits and withdrawals
*/
interface IVariableVaultFee {
// Enums
enum FeeType {
FLAT,
PERCENTAGE
}
enum FeeOperation {
DEPOSIT,
WITHDRAWAL,
INSTANT_WITHDRAWAL,
FLASH_REDEEM
}
// Structs
struct FeeConfig {
FeeType feeType;
uint256 feeAmount; // Either percentage (1e17 = 10%) or flat amount (e.g., 100e18)
}
struct AssetFeeConfig {
FeeConfig withdrawalFee;
FeeConfig depositFee;
FeeConfig instantWithdrawalFee;
FeeConfig flashRedeemFee;
address feeRecipient;
}
// Events
event RegisterAsset(address indexed user, address indexed asset, AssetFeeConfig config);
event DeregisterAsset(address indexed user, address indexed asset);
event UpdateAssetFeeConfig(
address indexed user,
address indexed asset,
AssetFeeConfig oldConfig,
AssetFeeConfig newConfig
);
// Errors
/// @notice Thrown when an invalid asset address is provided or asset is not registered
error InvalidAsset();
/// @notice Thrown when asset configuration parameters are invalid
error InvalidAssetConfig();
/// @notice Thrown when attempting to register an asset that is already registered
error AssetAlreadyRegistered();
/// @notice Thrown when amount is insufficient for the operation
error ZeroAmount();
/// @notice Thrown when amount is insufficient for the operation
error InsufficientAmount();
// View Functions
/**
* @notice Calculate fee on raw amount (amount without fees included)
* @param asset The asset address
* @param amount The raw amount
* @param operation The fee operation type (deposit/withdrawal)
* @return The fee amount to be added
*/
function feeOnRaw(
address asset,
uint256 amount,
FeeOperation operation
)
external
view
returns (uint256);
/**
* @notice Calculate fee on total amount (amount with fees already included)
* @param asset The asset address
* @param amount The total amount including fees
* @param operation The fee operation type (deposit/withdrawal)
* @return The fee portion of the total amount
*/
function feeOnTotal(
address asset,
uint256 amount,
FeeOperation operation
)
external
view
returns (uint256);
/**
* @notice Return the Fee Recipient
* @param asset The asset address
* @return The address to which the fee should be sent
*/
function getFeeRecipient(address asset) external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @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 Context {
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;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)
pragma solidity ^0.8.20;
/**
* @dev Helper library for emitting standardized panic codes.
*
* ```solidity
* contract Example {
* using Panic for uint256;
*
* // Use any of the declared internal constants
* function foo() { Panic.GENERIC.panic(); }
*
* // Alternatively
* function foo() { Panic.panic(Panic.GENERIC); }
* }
* ```
*
* Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].
*
* _Available since v5.1._
*/
// slither-disable-next-line unused-state
library Panic {
/// @dev generic / unspecified error
uint256 internal constant GENERIC = 0x00;
/// @dev used by the assert() builtin
uint256 internal constant ASSERT = 0x01;
/// @dev arithmetic underflow or overflow
uint256 internal constant UNDER_OVERFLOW = 0x11;
/// @dev division or modulo by zero
uint256 internal constant DIVISION_BY_ZERO = 0x12;
/// @dev enum conversion error
uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;
/// @dev invalid encoding in storage
uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;
/// @dev empty array pop
uint256 internal constant EMPTY_ARRAY_POP = 0x31;
/// @dev array out of bounds access
uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
/// @dev resource error (too large allocation or too large array)
uint256 internal constant RESOURCE_ERROR = 0x41;
/// @dev calling invalid internal function
uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;
/// @dev Reverts with a panic code. Recommended to use with
/// the internal constants with predefined codes.
function panic(uint256 code) internal pure {
assembly ("memory-safe") {
mstore(0x00, 0x4e487b71)
mstore(0x20, code)
revert(0x1c, 0x24)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.20;
/**
* @dev Wrappers over Solidity's uintXX/intXX/bool 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.
*/
library SafeCast {
/**
* @dev Value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
/**
* @dev An int value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedIntToUint(int256 value);
/**
* @dev Value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);
/**
* @dev An uint value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedUintToInt(uint256 value);
/**
* @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
*/
function toUint248(uint256 value) internal pure returns (uint248) {
if (value > type(uint248).max) {
revert SafeCastOverflowedUintDowncast(248, value);
}
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
*/
function toUint240(uint256 value) internal pure returns (uint240) {
if (value > type(uint240).max) {
revert SafeCastOverflowedUintDowncast(240, value);
}
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
*/
function toUint232(uint256 value) internal pure returns (uint232) {
if (value > type(uint232).max) {
revert SafeCastOverflowedUintDowncast(232, value);
}
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
*/
function toUint224(uint256 value) internal pure returns (uint224) {
if (value > type(uint224).max) {
revert SafeCastOverflowedUintDowncast(224, value);
}
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
*/
function toUint216(uint256 value) internal pure returns (uint216) {
if (value > type(uint216).max) {
revert SafeCastOverflowedUintDowncast(216, value);
}
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
*/
function toUint208(uint256 value) internal pure returns (uint208) {
if (value > type(uint208).max) {
revert SafeCastOverflowedUintDowncast(208, value);
}
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
*/
function toUint200(uint256 value) internal pure returns (uint200) {
if (value > type(uint200).max) {
revert SafeCastOverflowedUintDowncast(200, value);
}
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
*/
function toUint192(uint256 value) internal pure returns (uint192) {
if (value > type(uint192).max) {
revert SafeCastOverflowedUintDowncast(192, value);
}
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
*/
function toUint184(uint256 value) internal pure returns (uint184) {
if (value > type(uint184).max) {
revert SafeCastOverflowedUintDowncast(184, value);
}
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
*/
function toUint176(uint256 value) internal pure returns (uint176) {
if (value > type(uint176).max) {
revert SafeCastOverflowedUintDowncast(176, value);
}
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
*/
function toUint168(uint256 value) internal pure returns (uint168) {
if (value > type(uint168).max) {
revert SafeCastOverflowedUintDowncast(168, value);
}
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
*/
function toUint160(uint256 value) internal pure returns (uint160) {
if (value > type(uint160).max) {
revert SafeCastOverflowedUintDowncast(160, value);
}
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
*/
function toUint152(uint256 value) internal pure returns (uint152) {
if (value > type(uint152).max) {
revert SafeCastOverflowedUintDowncast(152, value);
}
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
*/
function toUint144(uint256 value) internal pure returns (uint144) {
if (value > type(uint144).max) {
revert SafeCastOverflowedUintDowncast(144, value);
}
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
*/
function toUint136(uint256 value) internal pure returns (uint136) {
if (value > type(uint136).max) {
revert SafeCastOverflowedUintDowncast(136, value);
}
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
*/
function toUint128(uint256 value) internal pure returns (uint128) {
if (value > type(uint128).max) {
revert SafeCastOverflowedUintDowncast(128, value);
}
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
*/
function toUint120(uint256 value) internal pure returns (uint120) {
if (value > type(uint120).max) {
revert SafeCastOverflowedUintDowncast(120, value);
}
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
*/
function toUint112(uint256 value) internal pure returns (uint112) {
if (value > type(uint112).max) {
revert SafeCastOverflowedUintDowncast(112, value);
}
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
*/
function toUint104(uint256 value) internal pure returns (uint104) {
if (value > type(uint104).max) {
revert SafeCastOverflowedUintDowncast(104, value);
}
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
*/
function toUint96(uint256 value) internal pure returns (uint96) {
if (value > type(uint96).max) {
revert SafeCastOverflowedUintDowncast(96, value);
}
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
*/
function toUint88(uint256 value) internal pure returns (uint88) {
if (value > type(uint88).max) {
revert SafeCastOverflowedUintDowncast(88, value);
}
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
*/
function toUint80(uint256 value) internal pure returns (uint80) {
if (value > type(uint80).max) {
revert SafeCastOverflowedUintDowncast(80, value);
}
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
*/
function toUint72(uint256 value) internal pure returns (uint72) {
if (value > type(uint72).max) {
revert SafeCastOverflowedUintDowncast(72, value);
}
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
*/
function toUint64(uint256 value) internal pure returns (uint64) {
if (value > type(uint64).max) {
revert SafeCastOverflowedUintDowncast(64, value);
}
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
*/
function toUint56(uint256 value) internal pure returns (uint56) {
if (value > type(uint56).max) {
revert SafeCastOverflowedUintDowncast(56, value);
}
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
*/
function toUint48(uint256 value) internal pure returns (uint48) {
if (value > type(uint48).max) {
revert SafeCastOverflowedUintDowncast(48, value);
}
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
*/
function toUint40(uint256 value) internal pure returns (uint40) {
if (value > type(uint40).max) {
revert SafeCastOverflowedUintDowncast(40, value);
}
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
*/
function toUint32(uint256 value) internal pure returns (uint32) {
if (value > type(uint32).max) {
revert SafeCastOverflowedUintDowncast(32, value);
}
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
*/
function toUint24(uint256 value) internal pure returns (uint24) {
if (value > type(uint24).max) {
revert SafeCastOverflowedUintDowncast(24, value);
}
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
*/
function toUint16(uint256 value) internal pure returns (uint16) {
if (value > type(uint16).max) {
revert SafeCastOverflowedUintDowncast(16, value);
}
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
*/
function toUint8(uint256 value) internal pure returns (uint8) {
if (value > type(uint8).max) {
revert SafeCastOverflowedUintDowncast(8, value);
}
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/
function toUint256(int256 value) internal pure returns (uint256) {
if (value < 0) {
revert SafeCastOverflowedIntToUint(value);
}
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
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(248, value);
}
}
/**
* @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
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(240, value);
}
}
/**
* @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
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(232, value);
}
}
/**
* @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
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(224, value);
}
}
/**
* @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
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(216, value);
}
}
/**
* @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
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(208, value);
}
}
/**
* @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
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(200, value);
}
}
/**
* @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
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(192, value);
}
}
/**
* @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
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(184, value);
}
}
/**
* @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
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(176, value);
}
}
/**
* @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
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(168, value);
}
}
/**
* @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
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(160, value);
}
}
/**
* @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
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(152, value);
}
}
/**
* @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
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(144, value);
}
}
/**
* @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
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(136, value);
}
}
/**
* @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
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(128, value);
}
}
/**
* @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
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(120, value);
}
}
/**
* @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
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(112, value);
}
}
/**
* @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
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(104, value);
}
}
/**
* @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
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(96, value);
}
}
/**
* @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
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(88, value);
}
}
/**
* @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
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(80, value);
}
}
/**
* @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
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(72, value);
}
}
/**
* @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
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(64, value);
}
}
/**
* @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
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(56, value);
}
}
/**
* @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
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(48, value);
}
}
/**
* @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
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(40, value);
}
}
/**
* @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
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(32, value);
}
}
/**
* @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
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(24, value);
}
}
/**
* @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
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(16, value);
}
}
/**
* @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
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(8, value);
}
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
if (value > uint256(type(int256).max)) {
revert SafeCastOverflowedUintToInt(value);
}
return int256(value);
}
/**
* @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.
*/
function toUint(bool b) internal pure returns (uint256 u) {
assembly ("memory-safe") {
u := iszero(iszero(b))
}
}
}{
"remappings": [
"@openzeppelin/contracts/=lib/multipli-vault/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/multipli-vault/lib/openzeppelin-contracts-upgradeable/contracts/",
"@solmate/=lib/multipli-vault/lib/solmate/src/",
"@multipli-vault/=lib/Multipli-Vault/",
"forge-std/=lib/multipli-vault/lib/forge-std/src/",
"Multipli-Vault/=lib/Multipli-Vault/",
"ds-test/=lib/Multipli-Vault/lib/solmate/lib/ds-test/src/",
"erc4626-tests/=lib/Multipli-Vault/lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"halmos-cheatcodes/=lib/Multipli-Vault/lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts-upgradeable/=lib/Multipli-Vault/lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/Multipli-Vault/lib/openzeppelin-contracts/",
"openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/",
"script/=lib/Multipli-Vault/script/",
"solmate/=lib/Multipli-Vault/lib/solmate/src/",
"test/=lib/Multipli-Vault/test/"
],
"optimizer": {
"enabled": true,
"runs": 8000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AssetAlreadyRegistered","type":"error"},{"inputs":[],"name":"InsufficientAmount","type":"error"},{"inputs":[],"name":"InvalidAsset","type":"error"},{"inputs":[],"name":"InvalidAssetConfig","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"}],"name":"DeregisterAsset","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"components":[{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"withdrawalFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"depositFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"instantWithdrawalFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"flashRedeemFee","type":"tuple"},{"internalType":"address","name":"feeRecipient","type":"address"}],"indexed":false,"internalType":"struct IVariableVaultFee.AssetFeeConfig","name":"config","type":"tuple"}],"name":"RegisterAsset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"components":[{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"withdrawalFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"depositFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"instantWithdrawalFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"flashRedeemFee","type":"tuple"},{"internalType":"address","name":"feeRecipient","type":"address"}],"indexed":false,"internalType":"struct IVariableVaultFee.AssetFeeConfig","name":"oldConfig","type":"tuple"},{"components":[{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"withdrawalFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"depositFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"instantWithdrawalFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"flashRedeemFee","type":"tuple"},{"internalType":"address","name":"feeRecipient","type":"address"}],"indexed":false,"internalType":"struct IVariableVaultFee.AssetFeeConfig","name":"newConfig","type":"tuple"}],"name":"UpdateAssetFeeConfig","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"assetFee","outputs":[{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"withdrawalFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"depositFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"instantWithdrawalFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"flashRedeemFee","type":"tuple"},{"internalType":"address","name":"feeRecipient","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"deregisterAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum IVariableVaultFee.FeeOperation","name":"operation","type":"uint8"}],"name":"feeOnRaw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum IVariableVaultFee.FeeOperation","name":"operation","type":"uint8"}],"name":"feeOnTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAssetRegistered","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"components":[{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"withdrawalFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"depositFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"instantWithdrawalFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"flashRedeemFee","type":"tuple"},{"internalType":"address","name":"feeRecipient","type":"address"}],"internalType":"struct IVariableVaultFee.AssetFeeConfig","name":"config","type":"tuple"}],"name":"registerAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"components":[{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"withdrawalFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"depositFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"instantWithdrawalFee","type":"tuple"},{"components":[{"internalType":"enum IVariableVaultFee.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"internalType":"struct IVariableVaultFee.FeeConfig","name":"flashRedeemFee","type":"tuple"},{"internalType":"address","name":"feeRecipient","type":"address"}],"internalType":"struct IVariableVaultFee.AssetFeeConfig","name":"config","type":"tuple"}],"name":"updateAssetFeeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6080604052348015600e575f5ffd5b506040516118b53803806118b5833981016040819052602b9160b4565b806001600160a01b038116605857604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b605f816065565b505060df565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f6020828403121560c3575f5ffd5b81516001600160a01b038116811460d8575f5ffd5b9392505050565b6117c9806100ec5f395ff3fe608060405234801561000f575f5ffd5b50600436106100c4575f3560e01c8063715018a61161007d578063987827121161005857806398782712146101cd578063ed529305146101e0578063f2fde38b146101f3575f5ffd5b8063715018a614610195578063717d59e31461019d5780638da5cb5b146101b0575f5ffd5b8063332b2ee0116100ad578063332b2ee01461010a5780634cfd82051461013c5780635d9c4f0f1461015d575f5ffd5b80630fa63fe4146100c857806317b41d5f146100f5575b5f5ffd5b6100db6100d63660046113b2565b610206565b6040516100ec95949392919061143c565b60405180910390f35b610108610103366004611518565b61036c565b005b61012c6101183660046113b2565b60016020525f908152604090205460ff1681565b60405190151581526020016100ec565b61014f61014a366004611614565b6105f0565b6040519081526020016100ec565b61017061016b3660046113b2565b6106cb565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ec565b6101086106e1565b6101086101ab3660046113b2565b6106f4565b5f5473ffffffffffffffffffffffffffffffffffffffff16610170565b6101086101db366004611518565b61084a565b61014f6101ee366004611614565b610a97565b6101086102013660046113b2565b610b67565b60026020525f908152604090819020815180830190925280549091908290829060ff16600181111561023a5761023a6113cb565b600181111561024b5761024b6113cb565b815260200160018201548152505090806002016040518060400160405290815f82015f9054906101000a900460ff16600181111561028b5761028b6113cb565b600181111561029c5761029c6113cb565b815260200160018201548152505090806004016040518060400160405290815f82015f9054906101000a900460ff1660018111156102dc576102dc6113cb565b60018111156102ed576102ed6113cb565b815260200160018201548152505090806006016040518060400160405290815f82015f9054906101000a900460ff16600181111561032d5761032d6113cb565b600181111561033e5761033e6113cb565b81526001919091015460209091015260089091015473ffffffffffffffffffffffffffffffffffffffff1685565b610374610bcf565b73ffffffffffffffffffffffffffffffffffffffff82166103c1576040517fc891add200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82165f9081526001602052604090205460ff1615610420576040517f4db515c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61042981610c21565b73ffffffffffffffffffffffffffffffffffffffff82165f908152600160208181526040808420805460ff19908116851790915560029092529092208351805182548695939492938593849290911690838181111561048a5761048a6113cb565b021790555060209182015160019182015590830151805160028401805492939092839160ff199091169083818111156104c5576104c56113cb565b0217905550602091909101516001918201556040830151805160048401805492939092839160ff19909116908381811115610502576105026113cb565b0217905550602091909101516001918201556060830151805160068401805492939092839160ff1990911690838181111561053f5761053f6113cb565b02179055506020919091015160019091015560809190910151600890910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92831617905582163373ffffffffffffffffffffffffffffffffffffffff167f98459ce3feca5172985de039c191fe370c95de424ce56b237efd6cda8bd237dc836040516105e491906116bc565b60405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff84161580610639575073ffffffffffffffffffffffffffffffffffffffff84165f9081526001602052604090205460ff16155b15610670576040517fc891add200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825f036106a9576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6106b48584610d85565b90506106c08482610e19565b9150505b9392505050565b5f5f6106d683610e6b565b608001519392505050565b6106e9610bcf565b6106f25f61108a565b565b6106fc610bcf565b73ffffffffffffffffffffffffffffffffffffffff81161580610744575073ffffffffffffffffffffffffffffffffffffffff81165f9081526001602052604090205460ff16155b1561077b576040517fc891add200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81165f818152600160208181526040808420805460ff1990811690915560029283905281852080548216815593840185905591830180548316905560038301849055600483018054831690556005830184905560068301805490921690915560078201839055600890910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555133917fbfbf0280c785768d1c77c418d7649f885c4d474b4c99dfbdc3ffe0fcfcee756a91a350565b610852610bcf565b73ffffffffffffffffffffffffffffffffffffffff8216158061089a575073ffffffffffffffffffffffffffffffffffffffff82165f9081526001602052604090205460ff16155b156108d1576040517fc891add200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108da81610c21565b5f6108e483610e6b565b73ffffffffffffffffffffffffffffffffffffffff84165f9081526002602052604090208351805182549394508593839190829060ff19166001838181111561092f5761092f6113cb565b021790555060209182015160019182015590830151805160028401805492939092839160ff1990911690838181111561096a5761096a6113cb565b0217905550602091909101516001918201556040830151805160048401805492939092839160ff199091169083818111156109a7576109a76113cb565b0217905550602091909101516001918201556060830151805160068401805492939092839160ff199091169083818111156109e4576109e46113cb565b02179055506020919091015160019091015560809190910151600890910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92831617905583163373ffffffffffffffffffffffffffffffffffffffff167ea9b0ebf447a1f58bbee947be638bc6cfb068032b246faae99ce098799adb658385604051610a8a9291906116cb565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff84161580610ae0575073ffffffffffffffffffffffffffffffffffffffff84165f9081526001602052604090205460ff16155b15610b17576040517fc891add200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825f03610b50576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610b5b8584610d85565b90506106c084826110fe565b610b6f610bcf565b73ffffffffffffffffffffffffffffffffffffffff8116610bc3576040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081525f60048201526024015b60405180910390fd5b610bcc8161108a565b50565b5f5473ffffffffffffffffffffffffffffffffffffffff1633146106f2576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610bba565b608081015173ffffffffffffffffffffffffffffffffffffffff16610c72576040517f37cc159400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020820151516001811115610c8b57610c8b6113cb565b148015610ca6575066b1a2bc2ec50000816020015160200151115b80610cda575060018151516001811115610cc257610cc26113cb565b148015610cda575080516020015166b1a2bc2ec50000105b80610d14575060016040820151516001811115610cf957610cf96113cb565b148015610d14575066b1a2bc2ec50000816040015160200151115b80610d4e575060016060820151516001811115610d3357610d336113cb565b148015610d4e575066b1a2bc2ec50000816060015160200151115b15610bcc576040517f37cc159400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091525f80825260208201525f610da284610e6b565b90505f836003811115610db757610db76113cb565b03610dc757602001519050610e13565b6001836003811115610ddb57610ddb6113cb565b03610de857519050610e13565b6003836003811115610dfc57610dfc6113cb565b03610e0c57606001519050610e13565b6040015190505b92915050565b5f8082516001811115610e2e57610e2e6113cb565b03610e3e57506020810151610e13565b81602001515f03610e5057505f610e13565b60208201516106c4908490670de0b6b3a76400006001611194565b610e73611307565b73ffffffffffffffffffffffffffffffffffffffff82161580610ebb575073ffffffffffffffffffffffffffffffffffffffff82165f9081526001602052604090205460ff16155b15610ef2576040517fc891add200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82165f9081526002602052604090819020815160e081019092528054829060a08201908390829060ff166001811115610f4257610f426113cb565b6001811115610f5357610f536113cb565b81526020016001820154815250508152602001600282016040518060400160405290815f82015f9054906101000a900460ff166001811115610f9757610f976113cb565b6001811115610fa857610fa86113cb565b81526020016001820154815250508152602001600482016040518060400160405290815f82015f9054906101000a900460ff166001811115610fec57610fec6113cb565b6001811115610ffd57610ffd6113cb565b81526020016001820154815250508152602001600682016040518060400160405290815f82015f9054906101000a900460ff166001811115611041576110416113cb565b6001811115611052576110526113cb565b8152600191909101546020918201529082526008929092015473ffffffffffffffffffffffffffffffffffffffff1691015292915050565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f8082516001811115611113576111136113cb565b03611161578282602001511115611156576040517f5945ea5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506020810151610e13565b81602001515f0361117357505f610e13565b60208201516106c49061118e670de0b6b3a7640000826116e8565b85919060015b5f6111c16111a1836111df565b80156111bc57505f84806111b7576111b7611720565b868809115b151590565b6111cc86868661120b565b6111d691906116e8565b95945050505050565b5f60028260038111156111f4576111f46113cb565b6111fe919061174d565b60ff166001149050919050565b5f5f5f61121886866112bb565b91509150815f0361123c5783818161123257611232611720565b04925050506106c4565b8184116112535761125360038515026011186112f6565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b5f807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b6040805160e081019091525f60a0820181815260c083019190915281908152602001611342604080518082019091525f808252602082015290565b8152602001611360604080518082019091525f808252602082015290565b815260200161137e604080518082019091525f808252602082015290565b81525f60209091015290565b803573ffffffffffffffffffffffffffffffffffffffff811681146113ad575f5ffd5b919050565b5f602082840312156113c2575f5ffd5b6106c48261138a565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b80516002811061142f577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b8252602090810151910152565b610120810161144b82886113f8565b61145860408301876113f8565b61146560808301866113f8565b61147260c08301856113f8565b73ffffffffffffffffffffffffffffffffffffffff83166101008301529695505050505050565b5f604082840312156114a9575f5ffd5b6040805190810167ffffffffffffffff811182821017156114f1577f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604052905080823560028110611505575f5ffd5b8152602092830135920191909152919050565b5f5f82840361014081121561152b575f5ffd5b6115348461138a565b92506101207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082011215611566575f5ffd5b5060405160a0810167ffffffffffffffff811182821017156115af577f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040526115bf8560208601611499565b81526115ce8560608601611499565b60208201526115e08560a08601611499565b60408201526115f28560e08601611499565b6060820152611604610120850161138a565b6080820152809150509250929050565b5f5f5f60608486031215611626575f5ffd5b61162f8461138a565b925060208401359150604084013560048110611649575f5ffd5b809150509250925092565b61165f8282516113f8565b602081015161167160408401826113f8565b50604081015161168460808401826113f8565b50606081015161169760c08401826113f8565b506080015173ffffffffffffffffffffffffffffffffffffffff166101009190910152565b6101208101610e138284611654565b61024081016116da8285611654565b6106c4610120830184611654565b80820180821115610e13577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f60ff831680611784577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b8060ff8416069150509291505056fea2646970667358221220a3c36c8233fee2b3b53c3b8d23fd719bb2bb80dcf1fc292b78b7f016d0c9494a64736f6c634300081e00330000000000000000000000008cfee31bf3a57ec2c86d9e0f476bd36aca611fa5
Deployed Bytecode
0x608060405234801561000f575f5ffd5b50600436106100c4575f3560e01c8063715018a61161007d578063987827121161005857806398782712146101cd578063ed529305146101e0578063f2fde38b146101f3575f5ffd5b8063715018a614610195578063717d59e31461019d5780638da5cb5b146101b0575f5ffd5b8063332b2ee0116100ad578063332b2ee01461010a5780634cfd82051461013c5780635d9c4f0f1461015d575f5ffd5b80630fa63fe4146100c857806317b41d5f146100f5575b5f5ffd5b6100db6100d63660046113b2565b610206565b6040516100ec95949392919061143c565b60405180910390f35b610108610103366004611518565b61036c565b005b61012c6101183660046113b2565b60016020525f908152604090205460ff1681565b60405190151581526020016100ec565b61014f61014a366004611614565b6105f0565b6040519081526020016100ec565b61017061016b3660046113b2565b6106cb565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ec565b6101086106e1565b6101086101ab3660046113b2565b6106f4565b5f5473ffffffffffffffffffffffffffffffffffffffff16610170565b6101086101db366004611518565b61084a565b61014f6101ee366004611614565b610a97565b6101086102013660046113b2565b610b67565b60026020525f908152604090819020815180830190925280549091908290829060ff16600181111561023a5761023a6113cb565b600181111561024b5761024b6113cb565b815260200160018201548152505090806002016040518060400160405290815f82015f9054906101000a900460ff16600181111561028b5761028b6113cb565b600181111561029c5761029c6113cb565b815260200160018201548152505090806004016040518060400160405290815f82015f9054906101000a900460ff1660018111156102dc576102dc6113cb565b60018111156102ed576102ed6113cb565b815260200160018201548152505090806006016040518060400160405290815f82015f9054906101000a900460ff16600181111561032d5761032d6113cb565b600181111561033e5761033e6113cb565b81526001919091015460209091015260089091015473ffffffffffffffffffffffffffffffffffffffff1685565b610374610bcf565b73ffffffffffffffffffffffffffffffffffffffff82166103c1576040517fc891add200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82165f9081526001602052604090205460ff1615610420576040517f4db515c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61042981610c21565b73ffffffffffffffffffffffffffffffffffffffff82165f908152600160208181526040808420805460ff19908116851790915560029092529092208351805182548695939492938593849290911690838181111561048a5761048a6113cb565b021790555060209182015160019182015590830151805160028401805492939092839160ff199091169083818111156104c5576104c56113cb565b0217905550602091909101516001918201556040830151805160048401805492939092839160ff19909116908381811115610502576105026113cb565b0217905550602091909101516001918201556060830151805160068401805492939092839160ff1990911690838181111561053f5761053f6113cb565b02179055506020919091015160019091015560809190910151600890910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92831617905582163373ffffffffffffffffffffffffffffffffffffffff167f98459ce3feca5172985de039c191fe370c95de424ce56b237efd6cda8bd237dc836040516105e491906116bc565b60405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff84161580610639575073ffffffffffffffffffffffffffffffffffffffff84165f9081526001602052604090205460ff16155b15610670576040517fc891add200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825f036106a9576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6106b48584610d85565b90506106c08482610e19565b9150505b9392505050565b5f5f6106d683610e6b565b608001519392505050565b6106e9610bcf565b6106f25f61108a565b565b6106fc610bcf565b73ffffffffffffffffffffffffffffffffffffffff81161580610744575073ffffffffffffffffffffffffffffffffffffffff81165f9081526001602052604090205460ff16155b1561077b576040517fc891add200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81165f818152600160208181526040808420805460ff1990811690915560029283905281852080548216815593840185905591830180548316905560038301849055600483018054831690556005830184905560068301805490921690915560078201839055600890910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555133917fbfbf0280c785768d1c77c418d7649f885c4d474b4c99dfbdc3ffe0fcfcee756a91a350565b610852610bcf565b73ffffffffffffffffffffffffffffffffffffffff8216158061089a575073ffffffffffffffffffffffffffffffffffffffff82165f9081526001602052604090205460ff16155b156108d1576040517fc891add200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108da81610c21565b5f6108e483610e6b565b73ffffffffffffffffffffffffffffffffffffffff84165f9081526002602052604090208351805182549394508593839190829060ff19166001838181111561092f5761092f6113cb565b021790555060209182015160019182015590830151805160028401805492939092839160ff1990911690838181111561096a5761096a6113cb565b0217905550602091909101516001918201556040830151805160048401805492939092839160ff199091169083818111156109a7576109a76113cb565b0217905550602091909101516001918201556060830151805160068401805492939092839160ff199091169083818111156109e4576109e46113cb565b02179055506020919091015160019091015560809190910151600890910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92831617905583163373ffffffffffffffffffffffffffffffffffffffff167ea9b0ebf447a1f58bbee947be638bc6cfb068032b246faae99ce098799adb658385604051610a8a9291906116cb565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff84161580610ae0575073ffffffffffffffffffffffffffffffffffffffff84165f9081526001602052604090205460ff16155b15610b17576040517fc891add200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825f03610b50576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610b5b8584610d85565b90506106c084826110fe565b610b6f610bcf565b73ffffffffffffffffffffffffffffffffffffffff8116610bc3576040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081525f60048201526024015b60405180910390fd5b610bcc8161108a565b50565b5f5473ffffffffffffffffffffffffffffffffffffffff1633146106f2576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610bba565b608081015173ffffffffffffffffffffffffffffffffffffffff16610c72576040517f37cc159400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020820151516001811115610c8b57610c8b6113cb565b148015610ca6575066b1a2bc2ec50000816020015160200151115b80610cda575060018151516001811115610cc257610cc26113cb565b148015610cda575080516020015166b1a2bc2ec50000105b80610d14575060016040820151516001811115610cf957610cf96113cb565b148015610d14575066b1a2bc2ec50000816040015160200151115b80610d4e575060016060820151516001811115610d3357610d336113cb565b148015610d4e575066b1a2bc2ec50000816060015160200151115b15610bcc576040517f37cc159400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091525f80825260208201525f610da284610e6b565b90505f836003811115610db757610db76113cb565b03610dc757602001519050610e13565b6001836003811115610ddb57610ddb6113cb565b03610de857519050610e13565b6003836003811115610dfc57610dfc6113cb565b03610e0c57606001519050610e13565b6040015190505b92915050565b5f8082516001811115610e2e57610e2e6113cb565b03610e3e57506020810151610e13565b81602001515f03610e5057505f610e13565b60208201516106c4908490670de0b6b3a76400006001611194565b610e73611307565b73ffffffffffffffffffffffffffffffffffffffff82161580610ebb575073ffffffffffffffffffffffffffffffffffffffff82165f9081526001602052604090205460ff16155b15610ef2576040517fc891add200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82165f9081526002602052604090819020815160e081019092528054829060a08201908390829060ff166001811115610f4257610f426113cb565b6001811115610f5357610f536113cb565b81526020016001820154815250508152602001600282016040518060400160405290815f82015f9054906101000a900460ff166001811115610f9757610f976113cb565b6001811115610fa857610fa86113cb565b81526020016001820154815250508152602001600482016040518060400160405290815f82015f9054906101000a900460ff166001811115610fec57610fec6113cb565b6001811115610ffd57610ffd6113cb565b81526020016001820154815250508152602001600682016040518060400160405290815f82015f9054906101000a900460ff166001811115611041576110416113cb565b6001811115611052576110526113cb565b8152600191909101546020918201529082526008929092015473ffffffffffffffffffffffffffffffffffffffff1691015292915050565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f8082516001811115611113576111136113cb565b03611161578282602001511115611156576040517f5945ea5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506020810151610e13565b81602001515f0361117357505f610e13565b60208201516106c49061118e670de0b6b3a7640000826116e8565b85919060015b5f6111c16111a1836111df565b80156111bc57505f84806111b7576111b7611720565b868809115b151590565b6111cc86868661120b565b6111d691906116e8565b95945050505050565b5f60028260038111156111f4576111f46113cb565b6111fe919061174d565b60ff166001149050919050565b5f5f5f61121886866112bb565b91509150815f0361123c5783818161123257611232611720565b04925050506106c4565b8184116112535761125360038515026011186112f6565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b5f807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b6040805160e081019091525f60a0820181815260c083019190915281908152602001611342604080518082019091525f808252602082015290565b8152602001611360604080518082019091525f808252602082015290565b815260200161137e604080518082019091525f808252602082015290565b81525f60209091015290565b803573ffffffffffffffffffffffffffffffffffffffff811681146113ad575f5ffd5b919050565b5f602082840312156113c2575f5ffd5b6106c48261138a565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b80516002811061142f577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b8252602090810151910152565b610120810161144b82886113f8565b61145860408301876113f8565b61146560808301866113f8565b61147260c08301856113f8565b73ffffffffffffffffffffffffffffffffffffffff83166101008301529695505050505050565b5f604082840312156114a9575f5ffd5b6040805190810167ffffffffffffffff811182821017156114f1577f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604052905080823560028110611505575f5ffd5b8152602092830135920191909152919050565b5f5f82840361014081121561152b575f5ffd5b6115348461138a565b92506101207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082011215611566575f5ffd5b5060405160a0810167ffffffffffffffff811182821017156115af577f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040526115bf8560208601611499565b81526115ce8560608601611499565b60208201526115e08560a08601611499565b60408201526115f28560e08601611499565b6060820152611604610120850161138a565b6080820152809150509250929050565b5f5f5f60608486031215611626575f5ffd5b61162f8461138a565b925060208401359150604084013560048110611649575f5ffd5b809150509250925092565b61165f8282516113f8565b602081015161167160408401826113f8565b50604081015161168460808401826113f8565b50606081015161169760c08401826113f8565b506080015173ffffffffffffffffffffffffffffffffffffffff166101009190910152565b6101208101610e138284611654565b61024081016116da8285611654565b6106c4610120830184611654565b80820180821115610e13577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f60ff831680611784577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b8060ff8416069150509291505056fea2646970667358221220a3c36c8233fee2b3b53c3b8d23fd719bb2bb80dcf1fc292b78b7f016d0c9494a64736f6c634300081e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000008cfee31bf3a57ec2c86d9e0f476bd36aca611fa5
-----Decoded View---------------
Arg [0] : owner (address): 0x8cFee31bf3A57EC2C86D9e0f476Bd36aCA611Fa5
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000008cfee31bf3a57ec2c86d9e0f476bd36aca611fa5
Deployed Bytecode Sourcemap
671:10728:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1081:50;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;3583:441;;;;;;:::i;:::-;;:::i;:::-;;873:49;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;3956:14:7;;3949:22;3931:41;;3919:2;3904:18;873:49:0;3791:187:7;7708:466:0;;;;;;:::i;:::-;;:::i;:::-;;;4600:25:7;;;4588:2;4573:18;7708:466:0;4454:177:7;6838:188:0;;;;;;:::i;:::-;;:::i;:::-;;;4812:42:7;4800:55;;;4782:74;;4770:2;4755:18;6838:188:0;4636:226:7;2293:101:2;;;:::i;4392:301:0:-;;;;;;:::i;:::-;;:::i;1638:85:2:-;1684:7;1710:6;;;1638:85;;5194:434:0;;;;;;:::i;:::-;;:::i;8790:470::-;;;;;;:::i;:::-;;:::i;2543:215:2:-;;;;;;:::i;:::-;;:::i;1081:50:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;:::o;3583:441::-;1531:13:2;:11;:13::i;:::-;3682:19:0::1;::::0;::::1;3678:71;;3724:14;;;;;;;;;;;;;;3678:71;3763:24;::::0;::::1;;::::0;;;:17:::1;:24;::::0;;;;;::::1;;3759:86;;;3810:24;;;;;;;;;;;;;;3759:86;3855:28;3876:6;3855:20;:28::i;:::-;3894:24;::::0;::::1;;::::0;;;3921:4:::1;3894:24;::::0;;;;;;;:31;;-1:-1:-1;;3894:31:0;;::::1;::::0;::::1;::::0;;;3935:8:::1;:15:::0;;;;;;:24;;;;;;3953:6;;3935:15;;:24;;:15;;;;:24;;::::1;::::0;;;;::::1;;;;;;:::i;:::-;;;::::0;;-1:-1:-1;3935:24:0::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;;3935:24:0;;::::1;::::0;;;;::::1;;;;;;:::i;:::-;;;::::0;;-1:-1:-1;3935:24:0::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;;3935:24:0;;::::1;::::0;;;;::::1;;;;;;:::i;:::-;;;::::0;;-1:-1:-1;3935:24:0::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;;3935:24:0;;::::1;::::0;;;;::::1;;;;;;:::i;:::-;;;::::0;;-1:-1:-1;3935:24:0::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;;::::0;;::::1;;::::0;;3975:42;::::1;735:10:3::0;3975:42:0::1;;;4010:6;3975:42;;;;;;:::i;:::-;;;;;;;;3583:441:::0;;:::o;7708:466::-;7858:7;7885:19;;;;;:48;;-1:-1:-1;7909:24:0;;;;;;;:17;:24;;;;;;;;7908:25;7885:48;7881:100;;;7956:14;;;;;;;;;;;;;;7881:100;7995:6;8005:1;7995:11;7991:61;;8029:12;;;;;;;;;;;;;;7991:61;8062:26;8091:31;8105:5;8112:9;8091:13;:31::i;:::-;8062:60;;8139:28;8149:6;8157:9;8139;:28::i;:::-;8132:35;;;7708:466;;;;;;:::o;6838:188::-;6901:7;6920:33;6956:22;6972:5;6956:15;:22::i;:::-;6995:24;;;;6838:188;-1:-1:-1;;;6838:188:0:o;2293:101:2:-;1531:13;:11;:13::i;:::-;2357:30:::1;2384:1;2357:18;:30::i;:::-;2293:101::o:0;4392:301:0:-;1531:13:2;:11;:13::i;:::-;4465:19:0::1;::::0;::::1;::::0;;:48:::1;;-1:-1:-1::0;4489:24:0::1;::::0;::::1;;::::0;;;:17:::1;:24;::::0;;;;;::::1;;4488:25;4465:48;4461:100;;;4536:14;;;;;;;;;;;;;;4461:100;4570:24;::::0;::::1;4597:5;4570:24:::0;;;:17:::1;:24;::::0;;;;;;;:32;;-1:-1:-1;;4570:32:0;;::::1;::::0;;;4620:8:::1;:15:::0;;;;;;;4613:22;;;::::1;::::0;;;;::::1;::::0;;;;;::::1;::::0;;;::::1;::::0;;;;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;;;;;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;4650:36;735:10:3;;4650:36:0::1;::::0;::::1;4392:301:::0;:::o;5194:434::-;1531:13:2;:11;:13::i;:::-;5302:19:0::1;::::0;::::1;::::0;;:56:::1;;-1:-1:-1::0;5325:24:0::1;::::0;::::1;;::::0;;;:17:::1;:24;::::0;;;;;::::1;;:33;5302:56;5298:108;;;5381:14;;;;;;;;;;;;;;5298:108;5416:28;5437:6;5416:20;:28::i;:::-;5455:31;5489:22;5505:5;5489:15;:22::i;:::-;5521:15;::::0;::::1;;::::0;;;:8:::1;:15;::::0;;;;:24;;;;;;5455:56;;-1:-1:-1;5539:6:0;;5521:15;;:24;:15;;-1:-1:-1;;5521:24:0::1;::::0;;;;::::1;;;;;;:::i;:::-;;;::::0;;-1:-1:-1;5521:24:0::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;;5521:24:0;;::::1;::::0;;;;::::1;;;;;;:::i;:::-;;;::::0;;-1:-1:-1;5521:24:0::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;;5521:24:0;;::::1;::::0;;;;::::1;;;;;;:::i;:::-;;;::::0;;-1:-1:-1;5521:24:0::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;;5521:24:0;;::::1;::::0;;;;::::1;;;;;;:::i;:::-;;;::::0;;-1:-1:-1;5521:24:0::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;;::::0;;::::1;;::::0;;5561:60;::::1;735:10:3::0;5561:60:0::1;;;5603:9;5614:6;5561:60;;;;;;;:::i;:::-;;;;;;;;5288:340;5194:434:::0;;:::o;8790:470::-;8942:7;8969:19;;;;;:48;;-1:-1:-1;8993:24:0;;;;;;;:17;:24;;;;;;;;8992:25;8969:48;8965:100;;;9040:14;;;;;;;;;;;;;;8965:100;9079:6;9089:1;9079:11;9075:61;;9113:12;;;;;;;;;;;;;;9075:61;9146:26;9175:31;9189:5;9196:9;9175:13;:31::i;:::-;9146:60;;9223:30;9235:6;9243:9;9223:11;:30::i;2543:215:2:-;1531:13;:11;:13::i;:::-;2627:22:::1;::::0;::::1;2623:91;;2672:31;::::0;::::1;::::0;;2700:1:::1;2672:31;::::0;::::1;4782:74:7::0;4755:18;;2672:31:2::1;;;;;;;;2623:91;2723:28;2742:8;2723:18;:28::i;:::-;2543:215:::0;:::o;1796:162::-;1684:7;1710:6;1855:23;1710:6;735:10:3;1855:23:2;1851:101;;1901:40;;;;;735:10:3;1901:40:2;;;4782:74:7;4755:18;;1901:40:2;4636:226:7;2004:1004:0;2092:19;;;;:33;;2088:91;;2148:20;;;;;;;;;;;;;;2088:91;2252:18;2223:17;;;;:25;:47;;;;;;;;:::i;:::-;;:119;;;;;1378:4;2294:6;:17;;;:27;;;:48;2223:119;2205:340;;;-1:-1:-1;2430:18:0;2398:20;;:28;:50;;;;;;;;:::i;:::-;;:129;;;;-1:-1:-1;2476:20:0;;:30;;;1378:4;-1:-1:-1;2398:129:0;2205:543;;;-1:-1:-1;2626:18:0;2587:27;;;;:35;:57;;;;;;;;:::i;:::-;;:143;;;;;1378:4;2672:6;:27;;;:37;;;:58;2587:143;2205:734;;;-1:-1:-1;2823:18:0;2790:21;;;;:29;:51;;;;;;;;:::i;:::-;;:131;;;;;1378:4;2869:6;:21;;;:31;;;:52;2790:131;2188:814;;;2971:20;;;;;;;;;;;;;;6234:598;-1:-1:-1;;;;;;;;;;;;;;;;;6397:33:0;6433:22;6449:5;6433:15;:22::i;:::-;6397:58;-1:-1:-1;6482:20:0;6469:9;:33;;;;;;;;:::i;:::-;;6465:93;;6525:22;;;;-1:-1:-1;6518:29:0;;6465:93;6584:23;6571:9;:36;;;;;;;;:::i;:::-;;6567:99;;6630:25;;-1:-1:-1;6623:32:0;;6567:99;6692:25;6679:9;:38;;;;;;;;:::i;:::-;;6675:102;;6740:26;;;;-1:-1:-1;6733:33:0;;6675:102;6793:32;;;;-1:-1:-1;6234:598:0;;;;;:::o;9673:540::-;9805:7;;9832:17;;:33;;;;;;;;:::i;:::-;;9828:90;;-1:-1:-1;9888:19:0;;;;9881:26;;9828:90;10033:9;:19;;;10056:1;10033:24;10029:63;;-1:-1:-1;10080:1:0;10073:8;;10029:63;10149:19;;;;10135:71;;:6;;1261:4;10187:18;10135:13;:71::i;5634:234::-;5697:21;;:::i;:::-;5734:19;;;;;:48;;-1:-1:-1;5758:24:0;;;;;;;:17;:24;;;;;;;;5757:25;5734:48;5730:100;;;5805:14;;;;;;;;;;;;;;5730:100;5846:15;;;;;;;:8;:15;;;;;;;5839:22;;;;;;;;;;;;;;;;5846:15;;5839:22;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5634:234;-1:-1:-1;;5634:234:0:o;2912:187:2:-;2985:16;3004:6;;;3020:17;;;;;;;;;;3052:40;;3004:6;;;;;;;3052:40;;2985:16;3052:40;2975:124;2912:187;:::o;10705:692:0:-;10839:7;;10866:17;;:33;;;;;;;;:::i;:::-;;10862:197;;10941:6;10919:9;:19;;;:28;10915:94;;;10974:20;;;;;;;;;;;;;;10915:94;-1:-1:-1;11029:19:0;;;;11022:26;;10862:197;11173:9;:19;;;11196:1;11173:24;11169:63;;-1:-1:-1;11220:1:0;11213:8;;11169:63;11302:19;;;;11275:115;;11323:37;1261:4;11302:19;11323:37;:::i;:::-;11275:6;;:115;11362:18;11054:238:5;11155:7;11209:76;11225:26;11242:8;11225:16;:26::i;:::-;:59;;;;;11283:1;11268:11;11255:25;;;;;:::i;:::-;11265:1;11262;11255:25;:29;11225:59;34914:9:6;34907:17;;34795:145;11209:76:5;11181:25;11188:1;11191;11194:11;11181:6;:25::i;:::-;:104;;;;:::i;:::-;11174:111;11054:238;-1:-1:-1;;;;;11054:238:5:o;32020:122::-;32088:4;32129:1;32117:8;32111:15;;;;;;;;:::i;:::-;:19;;;;:::i;:::-;:24;;32134:1;32111:24;32104:31;;32020:122;;;:::o;7242:3683::-;7324:14;7375:12;7389:11;7404:12;7411:1;7414;7404:6;:12::i;:::-;7374:42;;;;7498:4;7506:1;7498:9;7494:365;;7833:11;7827:3;:17;;;;;:::i;:::-;;7820:24;;;;;;7494:365;7984:4;7969:11;:19;7965:142;;8008:84;5312:5;8028:16;;5311:36;940:4:4;5306:42:5;8008:11;:84::i;:::-;8359:17;8510:11;8507:1;8504;8497:25;8902:12;8932:15;;;8917:31;;9067:22;;;;;9800:1;9781;:15;;9780:21;;10033;;;10029:25;;10018:36;10103:21;;;10099:25;;10088:36;10175:21;;;10171:25;;10160:36;10246:21;;;10242:25;;10231:36;10319:21;;;10315:25;;10304:36;10393:21;;;10389:25;;;10378:36;9309:12;;;;9305:23;;;9330:1;9301:31;8622:18;;;8612:29;;;9416:11;;;;8665:19;;;;9160:14;;;;9409:18;;;;10868:13;;-1:-1:-1;;7242:3683:5;;;;;:::o;1027:550::-;1088:12;;1474:6;1471:1;1468;1461:20;1501:9;;;;1549:11;;;1535:12;;;;1531:30;;;;;1027:550;-1:-1:-1;;1027:550:5:o;1776:194:4:-;1881:10;1875:4;1868:24;1918:4;1912;1905:18;1949:4;1943;1936:18;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:196:7:-;82:20;;142:42;131:54;;121:65;;111:93;;200:1;197;190:12;111:93;14:196;;;:::o;215:186::-;274:6;327:2;315:9;306:7;302:23;298:32;295:52;;;343:1;340;333:12;295:52;366:29;385:9;366:29;:::i;406:184::-;458:77;455:1;448:88;555:4;552:1;545:15;579:4;576:1;569:15;595:377;674:5;668:12;706:1;702:2;699:9;689:197;;742:77;739:1;732:88;843:4;840:1;833:15;871:4;868:1;861:15;689:197;895:15;;959:4;948:16;;;942:23;926:14;;919:47;595:377::o;977:806::-;1431:3;1416:19;;1444:46;1420:9;1472:6;1444:46;:::i;:::-;1499:55;1550:2;1539:9;1535:18;1527:6;1499:55;:::i;:::-;1563:56;1614:3;1603:9;1599:19;1591:6;1563:56;:::i;:::-;1628;1679:3;1668:9;1664:19;1656:6;1628:56;:::i;:::-;1733:42;1725:6;1721:55;1715:3;1704:9;1700:19;1693:84;977:806;;;;;;;;:::o;1788:786::-;1844:5;1892:4;1880:9;1875:3;1871:19;1867:30;1864:50;;;1910:1;1907;1900:12;1864:50;1963:4;1957:11;;;1995:17;;2042:18;2027:34;;2063:22;;;2024:62;2021:242;;;2119:77;2116:1;2109:88;2220:4;2217:1;2210:15;2248:4;2245:1;2238:15;2021:242;2279:4;2272:24;2314:6;-1:-1:-1;2314:6:7;2344:23;;2398:1;2386:14;;2376:42;;2414:1;2411;2404:12;2376:42;2427:23;;2523:2;2508:18;;;2495:32;2543:15;;2536:32;;;;1788:786;;-1:-1:-1;1788:786:7:o;2579:1207::-;2678:6;2686;2730:9;2721:7;2717:23;2760:3;2756:2;2752:12;2749:32;;;2777:1;2774;2767:12;2749:32;2800:29;2819:9;2800:29;:::i;:::-;2790:39;;2922:6;2853:66;2849:2;2845:75;2841:88;2838:108;;;2942:1;2939;2932:12;2838:108;-1:-1:-1;2995:2:7;2989:9;3037:4;3025:17;;3072:18;3057:34;;3093:22;;;3054:62;3051:242;;;3149:77;3146:1;3139:88;3250:4;3247:1;3240:15;3278:4;3275:1;3268:15;3051:242;3309:2;3302:22;3348:56;3396:7;3391:2;3376:18;;3348:56;:::i;:::-;3340:6;3333:72;3438:56;3486:7;3481:2;3470:9;3466:18;3438:56;:::i;:::-;3433:2;3425:6;3421:15;3414:81;3528:58;3578:7;3571:4;3560:9;3556:20;3528:58;:::i;:::-;3523:2;3515:6;3511:15;3504:83;3620:57;3669:7;3663:3;3652:9;3648:19;3620:57;:::i;:::-;3615:2;3607:6;3603:15;3596:82;3712:42;3746:6;3735:9;3731:22;3712:42;:::i;:::-;3706:3;3698:6;3694:16;3687:68;3774:6;3764:16;;;2579:1207;;;;;:::o;3983:466::-;4076:6;4084;4092;4145:2;4133:9;4124:7;4120:23;4116:32;4113:52;;;4161:1;4158;4151:12;4113:52;4184:29;4203:9;4184:29;:::i;:::-;4174:39;-1:-1:-1;4282:2:7;4267:18;;4254:32;;-1:-1:-1;4362:2:7;4347:18;;4334:32;4397:1;4385:14;;4375:42;;4413:1;4410;4403:12;4375:42;4436:7;4426:17;;;3983:466;;;;;:::o;4867:589::-;4935:46;4977:3;4969:5;4963:12;4935:46;:::i;:::-;5027:4;5020:5;5016:16;5010:23;5042:57;5093:4;5088:3;5084:14;5070:12;5042:57;:::i;:::-;;5147:4;5140:5;5136:16;5130:23;5162:59;5215:4;5210:3;5206:14;5190;5162:59;:::i;:::-;;5269:4;5262:5;5258:16;5252:23;5284:59;5337:4;5332:3;5328:14;5312;5284:59;:::i;:::-;-1:-1:-1;5398:4:7;5387:16;5381:23;5406:42;5377:72;5368:6;5359:16;;;;5352:98;4867:589::o;5461:266::-;5657:3;5642:19;;5670:51;5646:9;5703:6;5670:51;:::i;5732:426::-;6018:3;6003:19;;6031:51;6007:9;6064:6;6031:51;:::i;:::-;6091:61;6147:3;6136:9;6132:19;6124:6;6091:61;:::i;6163:279::-;6228:9;;;6249:10;;;6246:190;;;6292:77;6289:1;6282:88;6393:4;6390:1;6383:15;6421:4;6418:1;6411:15;6447:184;6499:77;6496:1;6489:88;6596:4;6593:1;6586:15;6620:4;6617:1;6610:15;6636:311;6666:1;6700:4;6697:1;6693:12;6724:3;6714:191;;6761:77;6758:1;6751:88;6862:4;6859:1;6852:15;6890:4;6887:1;6880:15;6714:191;6937:3;6930:4;6927:1;6923:12;6919:22;6914:27;;;6636:311;;;;:::o
Swarm Source
ipfs://a3c36c8233fee2b3b53c3b8d23fd719bb2bb80dcf1fc292b78b7f016d0c9494a
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$199.98
Net Worth in MON
Token Allocations
USDC
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| AVAX | 100.00% | $0.999886 | 200 | $199.98 |
Loading...
Loading
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.