Source Code
Overview
MON Balance
MON Value
$0.00| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 7 internal transactions
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
NativeVaultPositionManager
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity)
/**
*Submitted for verification at monadscan.com on 2025-11-25
*/
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.28;
// contracts/libraries/ConstantsLib.sol
/// @dev Scalar for math. `WAD` * `WAD`.
uint256 constant WAD_SQUARED = 1e36;
/// @dev Scalar for math. `WAD` * `WAD` / `BPS`.
/// 1e18 * 1e18 / 1e4
uint256 constant WAD_SQUARED_BPS_OFFSET = 1e32;
/// @dev Scalar for math. Increased precision when WAD is insufficient
/// but WAD_SQUARED runs the risk of overflow.
uint256 constant RAY = 1e27;
/// @dev Scalar for math. `WAD` * `BPS`.
uint256 constant WAD_BPS = 1e22;
/// @dev Scalar for math. Base precision matching ether.
uint256 constant WAD = 1e18;
/// @dev Scalar for math. Represents basis points typically used in TradFi.
uint256 constant BPS = 1e4;
/// @dev Return value indicating no price returned at all.
uint256 constant BAD_SOURCE = 2;
/// @dev Return value indicating price divergence or a missing price feed.
uint256 constant CAUTION = 1;
/// @dev Return value indicating no price error.
uint256 constant NO_ERROR = 0;
/// @dev Extra time added to top end Oracle feed heartbeat incase of
/// transaction congestion delaying an update.
uint256 constant HEARTBEAT_GRACE_PERIOD = 120;
/// @dev Unix time has 31,536,000 seconds per year.
/// All my homies hate leap seconds and leap years.
uint256 constant SECONDS_PER_YEAR = 31_536_000;
// contracts/libraries/external/FixedPointMathLib.sol
/// @notice Arithmetic library with operations for fixed-point numbers.
/// @dev Reduced function scope from full FixedPointMathLib library to only what is needed for Curvance.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
library FixedPointMathLib {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.
error MulDivFailed();
/// @dev The full precision multiply-divide operation failed, either due
/// to the result being larger than 256 bits, or a division by a zero.
error FullMulDivFailed();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* GENERAL NUMBER UTILITIES */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Calculates `floor(x * y / d)` with full precision.
/// Throws if result overflows a uint256 or when `d` is zero.
/// Credit to Remco Bloemen under MIT license: https://2π.com/21/muldiv
function fullMulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
for {} 1 {} {
// 512-bit multiply `[p1 p0] = x * y`.
// Compute the product mod `2**256` and mod `2**256 - 1`
// then use the Chinese Remainder Theorem to reconstruct
// the 512 bit result. The result is stored in two 256
// variables such that `product = p1 * 2**256 + p0`.
// Least significant 256 bits of the product.
result := mul(x, y) // Temporarily use `result` as `p0` to save gas.
let mm := mulmod(x, y, not(0))
// Most significant 256 bits of the product.
let p1 := sub(mm, add(result, lt(mm, result)))
// Handle non-overflow cases, 256 by 256 division.
if iszero(p1) {
if iszero(d) {
mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.
revert(0x1c, 0x04)
}
result := div(result, d)
break
}
// Make sure the result is less than `2**256`. Also prevents `d == 0`.
if iszero(gt(d, p1)) {
mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.
revert(0x1c, 0x04)
}
/*------------------- 512 by 256 division --------------------*/
// Make division exact by subtracting the remainder from `[p1 p0]`.
// Compute remainder using mulmod.
let r := mulmod(x, y, d)
// `t` is the least significant bit of `d`.
// Always greater or equal to 1.
let t := and(d, sub(0, d))
// Divide `d` by `t`, which is a power of two.
d := div(d, t)
// Invert `d mod 2**256`
// Now that `d` is an odd number, it has an inverse
// modulo `2**256` such that `d * inv = 1 mod 2**256`.
// Compute the inverse by starting with a seed that is correct
// correct for four bits. That is, `d * inv = 1 mod 2**4`.
let inv := xor(2, mul(3, d))
// Now use 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.
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**8
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**16
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**32
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**64
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**128
result :=
mul(
// Divide [p1 p0] by the factors of two.
// Shift in bits from `p1` into `p0`. For this we need
// to flip `t` such that it is `2**256 / t`.
or(
mul(sub(p1, gt(r, result)), add(div(sub(0, t), t), 1)),
div(sub(result, r), t)
),
// inverse mod 2**256
mul(inv, sub(2, mul(d, inv)))
)
break
}
}
}
/// @dev Calculates `floor(x * y / d)` with full precision, rounded up.
/// Throws if result overflows a uint256 or when `d` is zero.
/// Credit to Uniswap-v3-core under MIT license:
/// https://github.com/Uniswap/v3-core/blob/contracts/libraries/FullMath.sol
function fullMulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 result) {
result = fullMulDiv(x, y, d);
/// @solidity memory-safe-assembly
assembly {
if mulmod(x, y, d) {
result := add(result, 1)
if iszero(result) {
mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.
revert(0x1c, 0x04)
}
}
}
}
/// @dev Returns `floor(x * y / d)`.
/// Reverts if `x * y` overflows, or `d` is zero.
function mulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to require(d != 0 && (y == 0 || x <= type(uint256).max / y))
if iszero(mul(d, iszero(mul(y, gt(x, div(not(0), y)))))) {
mstore(0x00, 0xad251c27) // `MulDivFailed()`.
revert(0x1c, 0x04)
}
z := div(mul(x, y), d)
}
}
/// @dev Returns `ceil(x * y / d)`.
/// Reverts if `x * y` overflows, or `d` is zero.
function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to require(d != 0 && (y == 0 || x <= type(uint256).max / y))
if iszero(mul(d, iszero(mul(y, gt(x, div(not(0), y)))))) {
mstore(0x00, 0xad251c27) // `MulDivFailed()`.
revert(0x1c, 0x04)
}
z := add(iszero(iszero(mod(mul(x, y), d))), div(mul(x, y), d))
}
}
/// @dev Returns the square root of `x`.
function sqrt(uint256 x) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// `floor(sqrt(2**15)) = 181`. `sqrt(2**15) - 181 = 2.84`.
z := 181 // The "correct" value is 1, but this saves a multiplication later.
// This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
// start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.
// Let `y = x / 2**r`. We check `y >= 2**(k + 8)`
// but shift right by `k` bits to ensure that if `x >= 256`, then `y >= 256`.
let r := shl(7, lt(0xffffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffffff, shr(r, x))))
z := shl(shr(1, r), z)
// Goal was to get `z*z*y` within a small factor of `x`. More iterations could
// get y in a tighter range. Currently, we will have y in `[256, 256*(2**16))`.
// We ensured `y >= 256` so that the relative difference between `y` and `y+1` is small.
// That's not possible if `x < 256` but we can just verify those cases exhaustively.
// Now, `z*z*y <= x < z*z*(y+1)`, and `y <= 2**(16+8)`, and either `y >= 256`, or `x < 256`.
// Correctness can be checked exhaustively for `x < 256`, so we assume `y >= 256`.
// Then `z*sqrt(y)` is within `sqrt(257)/sqrt(256)` of `sqrt(x)`, or about 20bps.
// For `s` in the range `[1/256, 256]`, the estimate `f(s) = (181/1024) * (s+1)`
// is in the range `(1/2.84 * sqrt(s), 2.84 * sqrt(s))`,
// with largest error when `s = 1` and when `s = 256` or `1/256`.
// Since `y` is in `[256, 256*(2**16))`, let `a = y/65536`, so that `a` is in `[1/256, 256)`.
// Then we can estimate `sqrt(y)` using
// `sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2**18`.
// There is no overflow risk here since `y < 2**136` after the first branch above.
z := shr(18, mul(z, add(shr(r, x), 65536))) // A `mul()` is saved from starting `z` at 181.
// Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
// If `x+1` is a perfect square, the Babylonian method cycles between
// `floor(sqrt(x))` and `ceil(sqrt(x))`. This statement ensures we return floor.
// See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
z := sub(z, lt(div(x, z), z))
}
}
}
// contracts/interfaces/ICentralRegistry.sol
/// TYPES ///
/// @notice Configuration data for a separately supported blockchain.
/// @param isSupported Whether the chain is supported or not.
/// @param messagingChainId Messaging Chain ID where this address authorized.
/// @param domain Domain for the chain.
/// @param messagingHub Messaging Hub address on the chain.
/// @param votingHub Voting Hub address on the chain.
/// @param cveAddress CVE address on the chain.
/// @param feeTokenAddress Fee token address on the chain.
/// @param crosschainRelayer Crosschain relayer address on the chain.
struct ChainConfig {
bool isSupported;
uint16 messagingChainId;
uint32 domain;
address messagingHub;
address votingHub;
address cveAddress;
address feeTokenAddress;
address crosschainRelayer;
}
interface ICentralRegistry {
/// @notice The length of one protocol epoch, in seconds.
function EPOCH_DURATION() external view returns (uint256);
/// @notice Sequencer uptime oracle on this chain (for L2s).
function SEQUENCER_ORACLE() external view returns (address);
/// @notice Returns Genesis Epoch Timestamp of Curvance.
function genesisEpoch() external view returns (uint256);
/// @notice Returns Protocol DAO address.
function daoAddress() external view returns (address);
/// @notice Returns Protocol Emergency Council address.
function emergencyCouncil() external view returns (address);
/// @notice Indicates if address has DAO permissions or not.
function hasDaoPermissions(
address addressToCheck
) external view returns (bool);
/// @notice Indicates if address has elevated DAO permissions or not.
function hasElevatedPermissions(
address addressToCheck
) external view returns (bool);
/// @notice Indicates if address has lock creation permissions or not.
function hasLockingPermissions(
address addressToCheck
) external view returns (bool);
/// @notice Indicates if address has auction permissions or not.
function hasAuctionPermissions(
address addressToCheck
) external view returns (bool);
/// @notice Indicates if address has market permissions or not.
function hasMarketPermissions(
address addressToCheck
) external view returns (bool);
/// @notice Indicates if address has harvest permissions or not.
function hasHarvestPermissions(
address addressToCheck
) external view returns (bool);
/// @notice Returns Reward Manager address.
function rewardManager() external view returns (address);
/// @notice Returns Gauge Manager address.
function gaugeManager() external view returns (address);
/// @notice Returns CVE address.
function cve() external view returns (address);
/// @notice Returns veCVE address.
function veCVE() external view returns (address);
/// @notice Returns Voting Hub address.
function votingHub() external view returns (address);
/// @notice Returns Messaging Hub address.
function messagingHub() external view returns (address);
/// @notice Returns Oracle Manager address.
function oracleManager() external view returns (address);
/// @notice Returns Fee Manager address.
function feeManager() external view returns (address);
/// @notice Returns Fee Token address.
function feeToken() external view returns (address);
/// @notice Returns Crosschain Core contract address.
function crosschainCore() external view returns (address);
/// @notice Returns Crosschain Relayer contract address.
function crosschainRelayer() external view returns (address);
/// @notice Returns Token Messenger contract address.
function tokenMessager() external view returns (address);
/// @notice Returns Messenger Transmitter contract address.
function messageTransmitter() external view returns (address);
/// @notice Returns domain value.
function domain() external view returns (uint32);
/// @notice Returns protocol gas fee on harvest, in `BPS`.
function protocolCompoundFee() external view returns (uint256);
/// @notice Returns protocol yield fee on strategy harvest, in `BPS`.
function protocolYieldFee() external view returns (uint256);
/// @notice Returns protocol yield + gas fee on strategy harvest,
/// in `BPS`.
function protocolHarvestFee() external view returns (uint256);
/// @notice Returns protocol fee on leverage actions, in `BPS`.
function protocolLeverageFee() external view returns (uint256);
/// @notice Returns default fee on interest generated from active loans,
/// in `BPS`.
function defaultProtocolInterestFee() external view returns (uint256);
/// @notice Returns earlyUnlockPenaltyMultiplier value, in `BPS`.
function earlyUnlockPenaltyMultiplier() external view returns (uint256);
/// @notice Returns voteBoostMultiplier value, in `BPS`.
function voteBoostMultiplier() external view returns (uint256);
/// @notice Returns lockBoostMultiplier value, in `BPS`.
function lockBoostMultiplier() external view returns (uint256);
/// @notice Returns swap slippage limit, in `BPS`.
function slippageLimit() external view returns (uint256);
/// @notice Returns an array of Chain IDs recorded in the Crosschain
/// Protocol's Chain ID format.
function foreignChainIds() external view returns (uint256[] memory);
/// @notice Returns an array of Curvance markets on this chain.
function marketManagers() external view returns (address[] memory);
/// @notice Increments a caller's approval index.
/// @dev By incrementing their approval index, a user's delegates will all
/// have their delegation authority revoked across all Curvance
/// contracts.
/// Emits an {ApprovalIndexIncremented} event.
function incrementApprovalIndex() external;
/// @notice Returns `user`'s approval index.
/// @param user The user to check approval index for.
function userApprovalIndex(address user) external view returns (uint256);
/// @notice Returns whether a user has delegation disabled.
/// @param user The user to check delegation status for.
function checkNewDelegationDisabled(
address user
) external view returns (bool);
/// @notice Returns whether a particular GETH chainId is supported.
/// ChainId => messagingHub address, 2 = supported; 1 = unsupported.
function chainConfig(
uint256 chainId
) external view returns (ChainConfig memory);
/// @notice Returns the GETH chainId corresponding chainId corresponding
/// to Crosschain Messaging Protocol's `chainId`.
/// @param chainId The Crosschain Messaging Protocol's chainId.
/// @return The GETH chainId corresponding chainId corresponding to
/// Crosschain Messaging Protocol's `chainId`.
function messagingToGETHChainId(
uint16 chainId
) external view returns (uint256);
/// @notice Returns the Crosschain Messaging Protocol's ChainId
/// corresponding to the GETH `chainId`.
/// @param chainId The GETH chainId.
/// @return The Crosschain Messaging Protocol's ChainId
/// corresponding to the GETH `chainId`.
function GETHToMessagingChainId(
uint256 chainId
) external view returns (uint256);
/// @notice Indicates if an address is a market manager or not.
function isMarketManager(
address addressToCheck
) external view returns (bool);
/// @notice Maps an intent target address to the contract that will
/// inspect provided external calldata.
function externalCalldataChecker(
address addressToCheck
) external view returns (address);
/// @notice Maps a Multicall target address to the contract that will
/// inspect provided multicall calldata.
function multicallChecker(
address addressToCheck
) external view returns (address);
/// @notice Indicates the amount of token rewards allocated on this chain,
/// for an epoch.
function emissionsAllocatedByEpoch(
uint256 epoch
) external view returns (uint256);
/// @notice Indicates the amount of token rewards allocated across all
/// chains, for an era. An era is a particular period in time in
/// which rewards are constant, before a halvening event moves the
/// protocol to a new era.
function targetEmissionAllocationByEra(
uint256 era
) external view returns (uint256);
/// @notice Unlocks a market to process auction-based liquidations.
/// @param marketToUnlock The address of the market manager to unlock
/// auction-based liquidations with a specific
/// liquidation bonus.
function unlockAuctionForMarket(address marketToUnlock) external;
/// @notice Checks if a market is unlocked for auction operations.
/// @return Whether the caller is an unlocked market, approved for
/// auction-based liquidations.
function isMarketUnlocked() external view returns (bool);
/// @notice Sets the amount of token rewards allocated on this chain,
/// for an epoch.
/// @dev Only callable by the Voting Hub.
/// @param epoch The epoch having its token emission values set.
/// @param emissionsAllocated The amount of token rewards allocated on
/// this chain, for an epoch.
function setEmissionsAllocatedByEpoch(
uint256 epoch,
uint256 emissionsAllocated
) external;
/// @notice Checks whether `user` has transferability enabled or disabled
/// for their tokens.
/// @dev This is inherited from ActionRegistry portion of centralRegistry.
/// @param user The address to check whether transferability is enabled or
/// disabled for.
/// @return result Indicates whether `user` has transferability disabled
/// or not, true = disabled, false = not disabled.
function checkTransfersDisabled(
address user
) external view returns (bool result);
}
// contracts/interfaces/IDynamicIRM.sol
interface IDynamicIRM {
/// @notice Returns the interval at which interest rates are adjusted.
/// @notice The interval at which interest rates are adjusted,
/// in seconds.
function ADJUSTMENT_RATE() external view returns (uint256);
/// @notice The borrowable token linked to this interest rate model
/// contract.
function linkedToken() external view returns (address);
/// @notice Calculates the current borrow rate, per second.
/// @dev This function's intention is for frontend data querying and
/// should not be used for onchain execution.
/// @param assetsHeld The amount of underlying assets held in the pool.
/// @param debt The amount of outstanding debt in the pool.
/// @return result The borrow interest rate percentage, per second,
/// in `WAD`.
function borrowRate(
uint256 assetsHeld,
uint256 debt
) external view returns (uint256 result);
/// @notice Calculates the current borrow rate per second,
/// with updated vertex multiplier applied.
/// @param assetsHeld The amount of underlying assets held in the pool.
/// @param debt The amount of outstanding debt in the pool.
/// @return result The borrow rate percentage per second, in `WAD`.
function predictedBorrowRate(
uint256 assetsHeld,
uint256 debt
) external view returns (uint256 result);
/// @notice Calculates the current supply rate, per second.
/// @dev This function's intention is for frontend data querying and
/// should not be used for onchain execution.
/// @param assetsHeld The amount of underlying assets held in the pool.
/// @param debt The amount of outstanding debt in the pool.
/// @param interestFee The current interest rate protocol fee
/// for the market token.
/// @return result The supply interest rate percentage, per second,
/// in `WAD`.
function supplyRate(
uint256 assetsHeld,
uint256 debt,
uint256 interestFee
) external view returns (uint256 result);
/// @notice Calculates the interest rate paid per second by borrowers,
/// in percentage paid, per second, in `WAD`, and updates
/// `vertexMultiplier` if necessary.
/// @param assetsHeld The amount of underlying assets held in the pool.
/// @param debt The amount of outstanding debt in the pool.
/// @return ratePerSecond The interest rate paid per second by borrowers,
/// in percentage paid, per second, in `WAD`.
/// @return adjustmentRate The period of time at which interest rates are
/// adjusted, in seconds.
function adjustedBorrowRate(
uint256 assetsHeld,
uint256 debt
) external returns (uint256 ratePerSecond, uint256 adjustmentRate);
/// @notice Calculates the borrow utilization rate of the market.
/// @param assetsHeld The amount of underlying assets held in the pool.
/// @param outstandingDebt The amount of outstanding debt in the pool.
/// @return The utilization rate between [0, WAD].
function utilizationRate(
uint256 assetsHeld,
uint256 outstandingDebt
) external view returns (uint256);
}
// contracts/interfaces/IERC165.sol
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(
bytes4 interfaceId
) external view returns (bool);
}
// contracts/interfaces/IERC20.sol
// @dev Interface of the ERC20 standard
interface IERC20 {
// @dev Returns the name of the token.
function name() external view returns (string memory);
// @dev Returns the symbol of the token.
function symbol() external view returns (string memory);
// @dev Returns the decimals of the token.
function decimals() external view returns (uint8);
// @dev Emitted when `value` tokens are moved from one account (`from`) to
// another (`to`).
// Note that `value` may be zero.
event Transfer(address indexed from, address indexed to, uint256 value);
// @dev Emitted when the allowance of a `spender` for an `owner` is set by
// a call to {approve}. `value` is the new allowance.
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
// @dev Returns the amount of tokens in existence.
function totalSupply() external view returns (uint256);
// @dev Returns the amount of tokens owned by `account`.
function balanceOf(address account) external view returns (uint256);
// @dev Moves `amount` tokens from the caller's account to `to`.
// Returns a boolean value indicating whether the operation succeeded.
// Emits a {Transfer} event.
function transfer(address to, uint256 amount) external returns (bool);
// @dev Moves `amount` tokens from `from` to `to` using the
// allowance mechanism. `amount` is then deducted from the caller's
// allowance.
// Returns a boolean value indicating whether the operation succeeded.
// Emits a {Transfer} event.
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
// @dev Returns the remaining number of tokens that `spender` will be
// allowed to spend on behalf of `owner` through {transferFrom}. This
// is zero by default.
function allowance(
address owner,
address spender
) external view returns (uint256);
// @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
// Returns a boolean value indicating whether the operation succeeded.
// IMPORTANT: Beware that changing an allowance with this method brings the risk
// that someone may use both the old and the new allowance by unfortunate
// transaction ordering. One possible solution to mitigate this race
// condition is to first reduce the spender's allowance to 0 and set the
// desired value afterwards:
// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
// Emits an {Approval} event.
function approve(address spender, uint256 amount) external returns (bool);
}
// contracts/interfaces/IMarketManager.sol
interface IMarketManager {
/// TYPES ///
/// @notice Data structure passed communicating the intended liquidation
/// scenario to review based on current liquidity levels.
/// @param collateralToken The token which was used as collateral
/// by `account` and may be seized.
/// @param debtToken The token to potentially repay which has
/// outstanding debt by `account`.
/// @param numAccounts The number of accounts to be, potentially,
/// liquidated.
/// @param liquidateExact Whether the liquidator desires a specific
/// liquidation amount.
/// @param liquidatedShares Empty variable slot to store how much
/// `collateralToken` will be seized as
/// part of a particular liquidation.
/// @param debtRepaid Empty variable slot to store how much
/// `debtToken` will be repaid as part of a
/// particular liquidation.
/// @param badDebt Empty variable slot to store how much bad debt will
/// be realized by lenders as part of a particular
/// liquidation.
struct LiqAction {
address collateralToken;
address debtToken;
uint256 numAccounts;
bool liquidateExact;
uint256 liquidatedShares;
uint256 debtRepaid;
uint256 badDebt;
}
/// @notice Data structure returned communicating outcome of a liquidity
/// scenario review based on current liquidity levels.
/// @param liquidatedShares An array containing the collateral amounts to
/// liquidate from accounts, in shares.
/// @param debtRepaid The total amount of debt to repay from accounts,
/// in assets.
/// @param badDebtRealized The total amount of debt to realize as losses
/// for lenders, in assets.
struct LiqResult {
uint256[] liquidatedShares;
uint256 debtRepaid;
uint256 badDebtRealized;
}
/// @notice Returns whether minting, collateralization, borrowing of
/// `cToken` is paused.
/// @param cToken The address of the Curvance token to return
/// action statuses of.
/// @return bool Whether minting `cToken` is paused or not.
/// @return bool Whether collateralization `cToken` is paused or not.
/// @return bool Whether borrowing `cToken` is paused or not.
function actionsPaused(
address cToken
) external view returns (bool, bool, bool);
/// @notice Returns the current collateralization configuration
/// of `cToken`.
/// @param cToken The address of the Curvance token to return
/// collateralization configuration of.
/// @return The ratio at which this token can be borrowed against
/// when collateralized.
/// @return The collateral requirement where dipping below this
/// will cause a soft liquidation.
/// @return The collateral requirement where dipping below
/// this will cause a hard liquidation.
function collConfig(address cToken) external view returns (
uint256, uint256, uint256
);
/// @notice Returns the current liquidation configuration
/// of `cToken`.
/// @param cToken The address of the Curvance token to return
/// liquidation configuration of.
/// @return The base ratio at which this token will be
/// compensated on soft liquidation.
/// @return The liquidation incentive curve length between soft
/// liquidation to hard liquidation, in `WAD`. e.g. 5% base
/// incentive with 8% curve length results in 13% liquidation
/// incentive on hard liquidation.
/// @return The minimum possible liquidation incentive for during an
/// auction, in `WAD`.
/// @return The maximum possible liquidation incentive for during an
/// auction, in `WAD`.
/// @return Maximum % that a liquidator can repay when soft
/// liquidating an account, in `WAD`.
/// @return Curve length between soft liquidation and hard liquidation,
/// should be equal to 100% - `closeFactorBase`, in `WAD`.
/// @return The minimum possible close factor for during an auction,
/// in `WAD`.
/// @return The maximum possible close factor for during an auction,
/// in `WAD`.
function liquidationConfig(address cToken) external view returns (
uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256
);
/// @notice Enables an auction-based liquidation, potentially with a dynamic
/// close factor and liquidation penalty values in transient storage.
/// @dev Transient storage enforces any liquidator outside auction-based
/// liquidations uses the default risk parameters.
/// @param cToken The Curvance token to configure liquidations for during
/// an auction-based liquidation.
/// @param incentive The auction liquidation incentive value, in `BPS`.
/// @param closeFactor The auction close factor value, in `BPS`.
function setTransientLiquidationConfig(
address cToken,
uint256 incentive,
uint256 closeFactor
) external;
/// @notice Called from the AuctionManager as a post hook after liquidations
/// are tried to enable all collateral to be liquidated outside
/// an Auction tx.
/// @notice Resets the liquidation risk parameters in transient storage to
/// zero.
/// @dev This is redundant since the transient values will be reset after
/// the liquidation transaction, but can be useful during meta calls
/// with multiple liquidations during a single transaction.
function resetTransientLiquidationConfig() external;
/// @notice Checks if the account should be allowed to mint tokens
/// in the given market.
/// @param cToken The token to verify mints against.
function canMint(address cToken) external;
/// @notice Checks if the account should be allowed to collateralize
/// their shares of the given market.
/// Prunes unused positions in `account` data.
/// @dev May emit a {PositionUpdated} event.
/// @param cToken The token to verify collateralization of.
/// @param account The account which would collateralize the asset.
/// @param newNetCollateral The amount of shares that would be
/// collateralized in total if allowed.
function canCollateralize(
address cToken,
address account,
uint256 newNetCollateral
) external;
/// @notice Checks if the account should be allowed to redeem tokens
/// in the given market, and then redeems.
/// @dev This can only be called by the cToken itself.
/// @param cToken The token to verify the redemption against.
/// @param shares The number of cToken shares to redeem for the
/// underlying asset in the market.
/// @param account The account which would redeem `shares`.
/// @param balanceOf The current cToken share balance of `account`.
/// @param collateralPosted The current cToken shares posted as
/// collateral by `account`.
/// @param forceRedeemCollateral Whether the collateral should be always
/// reduced.
function canRedeemWithCollateralRemoval(
address cToken,
uint256 shares,
address account,
uint256 balanceOf,
uint256 collateralPosted,
bool forceRedeemCollateral
) external returns (uint256);
/// @notice Checks if the account should be allowed to borrow
/// the underlying asset of the given market.
/// Prunes unused positions in `account` data.
/// @dev May emit a {PositionUpdated} event.
/// @param cToken The token to verify borrowability of.
/// @param assets The amount of underlying assets `account` would borrow.
/// @param account The account which would borrow the asset.
/// @param newNetDebt The amount of assets that would be
/// outstanding debt in total if allowed.
function canBorrow(
address cToken,
uint256 assets,
address account,
uint256 newNetDebt
) external;
/// @notice Checks if the account should be allowed to borrow
/// the underlying asset of the given market,
/// and notifies the market of the borrow.
/// @dev This can only be called by the market itself.
/// @param cToken The market to verify the borrow against.
/// @param assets The amount of underlying assets `account` would borrow.
/// @param account The account which would borrow the asset.
/// @param newNetDebt The amount of assets that would be
/// outstanding debt in total if allowed.
function canBorrowWithNotify(
address cToken,
uint256 assets,
address account,
uint256 newNetDebt
) external;
/// @notice Checks if the account should be allowed to repay a borrow
/// in the given market, may clean up positions.
/// @param cToken The Curvance token to verify the repayment of.
/// @param newNetDebt The new debt amount owed by `account` after
/// repayment.
/// @param debtAsset The debt asset being repaid to `cToken`.
/// @param decimals The decimals that `debtToken` is measured in.
/// @param account The account who will have their loan repaid.
function canRepayWithReview(
address cToken,
uint256 newNetDebt,
address debtAsset,
uint256 decimals,
address account
) external;
/// @notice Checks if the liquidation should be allowed to occur,
/// and returns how many collateralized shares should be seized
/// on liquidation.
/// @param debtAmounts The amounts of outstanding debt the liquidator
/// wishes to repay, in underlying assets, empty if
/// intention is to liquidate maximum amount possible
/// for each account.
/// @param liquidator The address of the account trying to liquidate
/// `accounts`.
/// @param accounts The addresses of the accounts to be liquidated.
/// @param action A LiqAction struct containing:
/// collateralToken The token which is used as collateral
/// by `account` and may be seized.
/// debtToken The token to potentially repay which has
/// outstanding debt by `account`.
/// numAccounts The number of accounts to be, potentially,
/// liquidated.
/// liquidateExact Whether the liquidator desires a
/// specific liquidation amount.
/// collateralLiquidated Empty variable slot to store how
/// much `collateralToken` will be
/// seized as part of a particular
/// liquidation.
/// debtRepaid Empty variable slot to store how much
/// `debtToken` will be repaid as part of a
/// particular liquidation.
/// badDebt Empty variable slot to store how much bad debt
/// will be realized as part of a particular
/// liquidation.
/// @return result A LiqResult struct containing:
/// liquidatedShares An array containing the collateral
/// amounts to liquidate from
/// `accounts`.
/// debtRepaid The total amount of debt to repay from
/// `accounts`.
/// badDebtRealized The total amount of debt to realize as
/// losses for lenders inside this market.
/// @return An array containing the debt amounts to repay from
/// `accounts`, in assets.
function canLiquidate(
uint256[] memory debtAmounts,
address liquidator,
address[] calldata accounts,
IMarketManager.LiqAction memory action
) external returns (LiqResult memory, uint256[] memory);
/// @notice Checks if the seizing of `collateralToken` by repayment of
/// `debtToken` should be allowed.
/// @param collateralToken The Curvance token which was used as collateral
/// and will be seized.
/// @param debtToken The Curvance token which has outstanding debt to and
/// would be repaid during `collateralToken` seizure.
function canSeize(address collateralToken, address debtToken) external;
/// @notice Checks if the account should be allowed to transfer collateral
/// tokens in the given market.
/// @param cToken The Curvance token to verify the transfer of.
/// @param shares The amount of `cToken` to transfer.
/// @param account The account which will transfer `shares`.
/// @param balanceOf The current balance that `account` has of `cToken`
/// shares.
/// @param collateralPosted The amount of `cToken` shares posted as
/// collateral by `account`.
/// @param isCollateral Boolean indicating whether the token is currently
/// being used as collateral.
function canTransfer(
address cToken,
uint256 shares,
address account,
uint256 balanceOf,
uint256 collateralPosted,
bool isCollateral
) external returns (uint256);
/// @notice Updates `account` cooldownTimestamp to the current block
/// timestamp.
/// @dev The caller must be a listed cToken in the `markets` mapping.
/// @param cToken The address of the token that the account is borrowing.
/// @param account The address of the account that has just borrowed.
function notifyBorrow(address cToken, address account) external;
/// @notice A list of all tokens inside this market for
/// offchain querying.
function queryTokensListed() external view returns (address[] memory);
/// @notice Returns whether `cToken` is listed in the lending market.
/// @param cToken market token address.
function isListed(address cToken) external view returns (bool);
/// @notice The total amount of `cToken` that can be posted as collateral,
/// in shares.
function collateralCaps(address cToken) external view returns (uint256);
/// @notice The total amount of `cToken` underlying that can be borrowed,
/// in assets.
function debtCaps(address cToken) external view returns (uint256);
/// @notice Returns whether `addressToCheck` is an approved position
/// manager or not.
/// @param addressToCheck Address to check for position management
/// authority.
function isPositionManager(
address addressToCheck
) external view returns (bool);
/// @notice Returns the assets an account has entered.
/// @param account The address of the account to pull assets for.
/// @return A dynamic list with the assets `account` has entered.
function assetsOf(
address account
) external view returns (address[] memory);
/// @notice Determine `account`'s current status between collateral,
/// debt, and additional liquidity.
/// @param account The account to determine liquidity for.
/// @return The current total collateral amount of `account`.
/// @return The maximum debt amount of `account` can take out with
/// their current collateral.
/// @return The current total borrow amount of `account`.
function statusOf(
address account
) external returns (uint256, uint256, uint256);
}
// contracts/interfaces/IMulticallChecker.sol
interface IMulticallChecker {
function checkCalldata(
address caller,
address target,
bytes memory data
) external;
}
// contracts/interfaces/IPluginDelegable.sol
interface IPluginDelegable {
/// @notice Returns whether a user or contract has the ability to act
/// on behalf of an account.
/// @param user The address to check whether `delegate` has delegation
/// permissions.
/// @param delegate The address that will be approved or restricted
/// from delegated actions on behalf of the caller.
/// @return result Indicates whether `delegate` is an approved delegate or
/// not of `user`, true = disabled, false = not disabled.
function isDelegate(
address user,
address delegate
) external view returns (bool result);
/// @notice Approves or restricts `delegate`'s authority to operate
/// on the caller's behalf.
/// @dev NOTE: Be careful who you approve here!
/// They can delay actions such as asset redemption through repeated
/// denial of service.
/// Emits a {DelegateApproval} event.
/// @param delegate The address that will be approved or restricted
/// from delegated actions on behalf of the caller.
/// @param isApproved Whether `delegate` is being approved or restricted
/// of authority to operate on behalf of caller.
function setDelegateApproval(address delegate, bool isApproved) external;
}
// contracts/interfaces/IWETH.sol
interface IWETH {
function balanceOf(address user) external view returns (uint256);
function deposit() external payable;
function withdraw(uint256 amount) external;
}
// contracts/libraries/LowLevelCallsHelper.sol
library LowLevelCallsHelper {
/// ERRORS ///
error LowLevelCallsHelper__InsufficientBalance();
error LowLevelCallsHelper__CallFailed();
/// INTERNAL FUNCTIONS ///
/// @notice Executes a low level .call() and validates that execution
/// was safely performed.
/// @dev Bubbles up errors and reverts if anything along the execution
/// path failed or was a red flag.
/// @param target The target contract address to execute .call() at.
/// @param data The bytecode data to attach to the .call() execution
/// including the function signature hash and function call
/// parameters.
function _call(
address target,
bytes memory data
) internal returns (bytes memory) {
(bool success, bytes memory returnData) = target.call{value: 0}(data);
return _verifyResult(target, success, returnData);
}
/// @notice Executes a low level .call(), with attached native token
/// and validates that execution was safely performed.
/// @dev Bubbles up errors and reverts if anything along the execution
/// path failed or was a red flag.
/// @param target The target contract address to execute .call() at.
/// @param data The bytecode data to attach to the .call() execution
/// including the function signature hash and function call
/// parameters.
/// @param value The amount of native token to attach to the low level
/// call.
function _callWithNative(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
if (address(this).balance < value) {
revert LowLevelCallsHelper__InsufficientBalance();
}
(bool success, bytes memory returnData) = target.call{
value: value
}(data);
return _verifyResult(target, success, returnData);
}
/// @notice Executes a low level .delegatecall() and validates that
/// execution was safely performed.
/// @dev Bubbles up errors and reverts if anything along the execution
/// path failed or was a red flag.
/// @param target The target contract address to execute .delegatecall()
/// at.
/// @param data The bytecode data to attach to the .call() execution
/// including the function signature hash and function call
/// parameters.
function _delegateCall(
address target,
bytes memory data
) internal returns (bytes memory) {
(bool success, bytes memory returnData) = target.delegatecall(data);
return _verifyResult(target, success, returnData);
}
/// @dev Validates whether the low level call or delegate call was
/// successful and reverts in cases of bubbled up revert messages
/// or if `target` was not actually a contract.
function _verifyResult(
address target,
bool success,
bytes memory returnData
) internal view returns (bytes memory) {
_propagateError(success, returnData);
// If the call was successful but there was no return data we need
// to make sure a contract was actually called as expected.
if (returnData.length == 0 && target.code.length == 0) {
revert LowLevelCallsHelper__CallFailed();
}
return returnData;
}
/// @dev Propagates an error message, if necessary.
/// @param success If transaction was successful.
/// @param resultData The transaction result data.
function _propagateError(
bool success,
bytes memory resultData
) internal pure {
if (!success) {
if (resultData.length == 0) {
revert LowLevelCallsHelper__CallFailed();
}
// Bubble up error if there was one given.
assembly {
revert(add(32, resultData), mload(resultData))
}
}
}
}
// contracts/libraries/ReentrancyGuardTransient.sol
/// @notice Reentrancy guard mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ReentrancyGuardTransient.sol)
/// @dev Mai: Edited to always use transient storage.
abstract contract ReentrancyGuard {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Unauthorized reentrant call.
error Reentrancy();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STORAGE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Equivalent to: `uint32(bytes4(keccak256("Reentrancy()"))) | 1 << 71`.
/// 9 bytes is large enough to avoid collisions in practice,
/// but not too large to result in excessive bytecode bloat.
uint256 private constant _REENTRANCY_GUARD_SLOT = 0x8000000000ab143c06;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* REENTRANCY GUARD */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Guards a function from reentrancy.
modifier nonReentrant() virtual {
/// @solidity memory-safe-assembly
assembly {
if tload(_REENTRANCY_GUARD_SLOT) {
mstore(0x00, 0xab143c06) // `Reentrancy()`.
revert(0x1c, 0x04)
}
tstore(_REENTRANCY_GUARD_SLOT, address())
}
_;
/// @solidity memory-safe-assembly
assembly {
tstore(_REENTRANCY_GUARD_SLOT, 0)
}
}
/// @dev Guards a view function from read-only reentrancy.
modifier nonReadReentrant() virtual {
/// @solidity memory-safe-assembly
assembly {
if tload(_REENTRANCY_GUARD_SLOT) {
mstore(0x00, 0xab143c06) // `Reentrancy()`.
revert(0x1c, 0x04)
}
}
_;
}
}
// contracts/libraries/external/SafeTransferLib.sol
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
///
/// @dev Note:
/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection.
/// - For ERC20s, this implementation won't check that a token has code,
/// responsibility is delegated to the caller.
library SafeTransferLib {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The ETH transfer has failed.
error ETHTransferFailed();
/// @dev The ERC20 `transferFrom` has failed.
error TransferFromFailed();
/// @dev The ERC20 `transfer` has failed.
error TransferFailed();
/// @dev The ERC20 `approve` has failed.
error ApproveFailed();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CONSTANTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes.
uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;
/// @dev Suggested gas stipend for contract receiving ETH to perform a few
/// storage reads and writes, but low enough to prevent griefing.
uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ETH OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
// If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.
//
// The regular variants:
// - Forwards all remaining gas to the target.
// - Reverts if the target reverts.
// - Reverts if the current contract has insufficient balance.
//
// The force variants:
// - Forwards with an optional gas stipend
// (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).
// - If the target reverts, or if the gas stipend is exhausted,
// creates a temporary contract to force send the ETH via `SELFDESTRUCT`.
// Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.
// - Reverts if the current contract has insufficient balance.
//
// The try variants:
// - Forwards with a mandatory gas stipend.
// - Instead of reverting, returns whether the transfer succeeded.
/// @dev Sends `amount` (in wei) ETH to `to`.
function safeTransferETH(address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
}
}
/// @dev Sends all the ETH in the current contract to `to`.
function safeTransferAllETH(address to) internal {
/// @solidity memory-safe-assembly
assembly {
// Transfer all the ETH and check if it succeeded or not.
if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
}
}
/// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
/// @solidity memory-safe-assembly
assembly {
if lt(selfbalance(), amount) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to) // Store the address in scratch space.
mstore8(0x0b, 0x73) // Opcode `PUSH20`.
mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
}
}
}
/// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.
function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {
/// @solidity memory-safe-assembly
assembly {
if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to) // Store the address in scratch space.
mstore8(0x0b, 0x73) // Opcode `PUSH20`.
mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
}
}
}
/// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.
function forceSafeTransferETH(address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
if lt(selfbalance(), amount) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to) // Store the address in scratch space.
mstore8(0x0b, 0x73) // Opcode `PUSH20`.
mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
}
}
}
/// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.
function forceSafeTransferAllETH(address to) internal {
/// @solidity memory-safe-assembly
assembly {
// forgefmt: disable-next-item
if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to) // Store the address in scratch space.
mstore8(0x0b, 0x73) // Opcode `PUSH20`.
mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
}
}
}
/// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
internal
returns (bool success)
{
/// @solidity memory-safe-assembly
assembly {
success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)
}
}
/// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.
function trySafeTransferAllETH(address to, uint256 gasStipend)
internal
returns (bool success)
{
/// @solidity memory-safe-assembly
assembly {
success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ERC20 OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
/// Reverts upon failure.
///
/// The `from` account must have at least `amount` approved for
/// the current contract to manage.
function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40) // Cache the free memory pointer.
mstore(0x60, amount) // Store the `amount` argument.
mstore(0x40, to) // Store the `to` argument.
mstore(0x2c, shl(96, from)) // Store the `from` argument.
mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
// Perform the transfer, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
)
) {
mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
revert(0x1c, 0x04)
}
mstore(0x60, 0) // Restore the zero slot to zero.
mstore(0x40, m) // Restore the free memory pointer.
}
}
/// @dev Sends all of ERC20 `token` from `from` to `to`.
/// Reverts upon failure.
///
/// The `from` account must have their entire balance approved for
/// the current contract to manage.
function safeTransferAllFrom(address token, address from, address to)
internal
returns (uint256 amount)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40) // Cache the free memory pointer.
mstore(0x40, to) // Store the `to` argument.
mstore(0x2c, shl(96, from)) // Store the `from` argument.
mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
// Read the balance, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x1f), // At least 32 bytes returned.
staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
)
) {
mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
revert(0x1c, 0x04)
}
mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.
amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.
// Perform the transfer, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
)
) {
mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
revert(0x1c, 0x04)
}
mstore(0x60, 0) // Restore the zero slot to zero.
mstore(0x40, m) // Restore the free memory pointer.
}
}
/// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
/// Reverts upon failure.
function safeTransfer(address token, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
// Perform the transfer, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
revert(0x1c, 0x04)
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Sends all of ERC20 `token` from the current contract to `to`.
/// Reverts upon failure.
function safeTransferAll(address token, address to) internal returns (uint256 amount) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
mstore(0x20, address()) // Store the address of the current contract.
// Read the balance, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x1f), // At least 32 bytes returned.
staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
)
) {
mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
revert(0x1c, 0x04)
}
mstore(0x14, to) // Store the `to` argument.
amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.
mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
// Perform the transfer, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
revert(0x1c, 0x04)
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
/// Reverts upon failure.
function safeApprove(address token, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
// Perform the approval, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
revert(0x1c, 0x04)
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
/// If the initial attempt to approve fails, attempts to reset the approved amount to zero,
/// then retries the approval again (some tokens, e.g. USDT, requires this).
/// Reverts upon failure.
function safeApproveWithRetry(address token, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
// Perform the approval, retrying upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x34, 0) // Store 0 for the `amount`.
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00)) // Reset the approval.
mstore(0x34, amount) // Store back the original `amount`.
// Retry the approval, reverting upon failure.
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Returns the amount of ERC20 `token` owned by `account`.
/// Returns zero if the `token` does not exist.
function balanceOf(address token, address account) internal view returns (uint256 amount) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, account) // Store the `account` argument.
mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
amount :=
mul(
mload(0x20),
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x1f), // At least 32 bytes returned.
staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
)
)
}
}
}
// contracts/libraries/external/ERC165.sol
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(
bytes4 interfaceId
) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// contracts/libraries/external/ERC165Checker.sol
// @author Modified from OpenZeppelin Contracts (utils/introspection/ERC165Checker.sol)
/**
* @dev Library used to query support of an interface declared via {IERC165}.
*
* Note that these functions return the actual result of the query: they do not
* `revert` if an interface is not supported. It is up to the caller to decide
* what to do in these cases.
*/
library ERC165Checker {
// As per the EIP-165 spec, no interface should ever match 0xffffffff
bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;
/**
* @dev Returns true if `account` supports the {IERC165} interface.
*/
function supportsERC165(address account) internal view returns (bool) {
// Any contract that implements ERC165 must explicitly indicate support of
// InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
return
supportsERC165InterfaceUnchecked(
account,
type(IERC165).interfaceId
) &&
!supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID);
}
/**
* @dev Returns true if `account` supports the interface defined by
* `interfaceId`. Support for {IERC165} itself is queried automatically.
*
* See {IERC165-supportsInterface}.
*/
function supportsInterface(
address account,
bytes4 interfaceId
) internal view returns (bool) {
// query support of both ERC165 as per the spec and support of _interfaceId
return
supportsERC165(account) &&
supportsERC165InterfaceUnchecked(account, interfaceId);
}
/**
* @notice Query if a contract implements an interface, does not check ERC165 support
* @param account The address of the contract to query for support of an interface
* @param interfaceId The interface identifier, as specified in ERC-165
* @return true if the contract at account indicates support of the interface with
* identifier interfaceId, false otherwise
* @dev Assumes that account contains a contract that supports ERC165, otherwise
* the behavior of this method is undefined. This precondition can be checked
* with {supportsERC165}.
*
* Some precompiled contracts will falsely indicate support for a given interface, so caution
* should be exercised when using this function.
*
* Interface identification is specified in ERC-165.
*/
function supportsERC165InterfaceUnchecked(
address account,
bytes4 interfaceId
) internal view returns (bool) {
// prepare call
bytes memory encodedParams = abi.encodeCall(
IERC165.supportsInterface,
(interfaceId)
);
// perform static call
bool success;
uint256 returnSize;
uint256 returnValue;
assembly {
success := staticcall(
30000,
account,
add(encodedParams, 0x20),
mload(encodedParams),
0x00,
0x20
)
returnSize := returndatasize()
returnValue := mload(0x00)
}
return success && returnSize >= 0x20 && returnValue > 0;
}
}
// contracts/interfaces/IVault.sol
interface IVault {
function deposit(
uint256 assets,
address receiver
) external payable returns (uint256 shares);
function redeem(
uint256 shares,
address receiver,
address owner
) external returns (uint256 assets);
function previewDeposit(
uint256 assets
) external returns (uint256 shares);
function previewRedeem(
uint256 shares
) external returns (uint256 assets);
function asset() external view returns (IERC20);
}
// contracts/libraries/CentralRegistryLib.sol
/// @title Curvance Central Registry Validation Library
/// @notice For validating that Central Registry is configured properly
/// on launch.
library CentralRegistryLib {
/// ERRORS ///
error CentralRegistryLib__InvalidCentralRegistry();
/// INTERNAL FUNCTIONS ///
/// @notice Validates that `cr` is the Protocol Central Registry.
/// @param cr The proposed Protocol Central Registry.
function _isCentralRegistry(ICentralRegistry cr) internal view {
if (
!ERC165Checker.supportsInterface(
address(cr),
type(ICentralRegistry).interfaceId
)
) {
revert CentralRegistryLib__InvalidCentralRegistry();
}
}
}
// contracts/libraries/Multicall.sol
/// @title Curvance Multicall helper.
/// @notice Multicall implementation to support pull based oracles and
/// other chained actions within Curvance.
abstract contract Multicall {
/// TYPES ///
/// @notice Struct containing information on the desired
/// multicall action to execute.
/// @param target The address of the target contract to execute the call at.
/// @param isPriceUpdate Boolean indicating if the call is a price update.
/// @param data The data to attach to the call.
struct MulticallAction {
address target;
bool isPriceUpdate;
bytes data;
}
/// ERRORS ///
error Multicall__InvalidTarget();
error Multicall__UnknownCalldata();
/// EXTERNAL FUNCTIONS ///
/// @notice Executes multiple calls in a single transaction.
/// This can be used to update oracle prices before
/// a liquidity dependent action.
function multicall(
MulticallAction[] calldata calls
) external returns (bytes[] memory results) {
ICentralRegistry cr = _getCentralRegistry();
uint256 numCalls = calls.length;
results = new bytes[](numCalls);
MulticallAction memory cachedCall;
for (uint256 i; i < numCalls; ++i) {
cachedCall = calls[i];
if (cachedCall.isPriceUpdate) {
// CASE: We need to update a pull based price oracle and we
// need a direct call to the target address.
address checker = cr.multicallChecker(cachedCall.target);
// Validate we know how to verify this calldata.
if (checker == address(0)) {
revert Multicall__UnknownCalldata();
}
IMulticallChecker(checker).checkCalldata(
msg.sender,
cachedCall.target,
cachedCall.data
);
results[i] = LowLevelCallsHelper.
_call(cachedCall.target, cachedCall.data);
continue;
}
// CASE: Not a price update and we need delegate the call to the
// current address.
if (address(this) != cachedCall.target) {
revert Multicall__InvalidTarget();
}
results[i] = LowLevelCallsHelper.
_delegateCall(address(this), cachedCall.data);
}
}
/// @notice Returns the Protocol Central Registry contract in interface
/// form.
/// @dev MUST be overridden in every multicallable contract's
/// implementation.
function _getCentralRegistry()
internal
view
virtual
returns (ICentralRegistry);
}
// contracts/libraries/PluginDelegable.sol
/// @title Curvance Plugin Delegation Manager.
/// @notice Facilitates delegated actions on behalf of a user inside Curvance.
/// @dev `PluginDelegable` allows the Curvance Protocol to be a modular system
/// that plugins can be built on top of. By delegating action authority
/// to an address or addresses users can utilize potential third-party
/// features such as limit orders, crosschain actions, reward auto
/// compounding, chained (multiple sequential) actions, etc.
abstract contract PluginDelegable is IPluginDelegable {
/// CONSTANTS ///
/// @notice Curvance DAO Hub.
ICentralRegistry public immutable centralRegistry;
/// STORAGE ///
/// @notice Status of whether a user or contract has the ability to act
/// on behalf of an account.
/// @dev Account address => approval index => Spender address => Can act
/// on behalf of account.
mapping(address => mapping(uint256 => mapping(address => bool)))
internal _isDelegate;
/// EVENTS ///
event DelegateApproval(
address indexed owner,
address indexed delegate,
uint256 approvalIndex,
bool isApproved
);
/// ERRORS ///
error PluginDelegable__Unauthorized();
error PluginDelegable__DelegatingDisabled();
error PluginDelegable_InvalidParameter();
/// CONSTRUCTOR ///
/// @param cr The address of the Central Registry contract.
constructor(ICentralRegistry cr) {
CentralRegistryLib._isCentralRegistry(cr);
centralRegistry = cr;
}
/// EXTERNAL FUNCTIONS ///
/// @notice Approves or restricts `delegate`'s authority to operate
/// on the caller's behalf.
/// @dev NOTE: Be careful who you approve here!
/// They can delay actions such as asset redemption through repeated
/// denial of service.
/// Emits a {DelegateApproval} event.
/// @param delegate The address that will be approved or restricted
/// from delegated actions on behalf of the caller.
/// @param isApproved Whether `delegate` is being approved or restricted
/// of authority to operate on behalf of caller.
function setDelegateApproval(address delegate, bool isApproved) external {
if (delegate == msg.sender) {
revert PluginDelegable_InvalidParameter();
}
// Validate that new delegation configuration is current allowed for
// the caller.
if (centralRegistry.checkNewDelegationDisabled(msg.sender)) {
revert PluginDelegable__DelegatingDisabled();
}
uint256 currentIndex = centralRegistry.userApprovalIndex(msg.sender);
_isDelegate[msg.sender][currentIndex][delegate] = isApproved;
emit DelegateApproval(msg.sender, delegate, currentIndex, isApproved);
}
/// @notice Returns `user`'s current approval index value.
/// @dev The approval index is a way to revoke approval on all tokens,
/// and features at once if a malicious delegation was allowed by
/// `user`.
/// @param user The user to check delegated approval index for.
/// @return result The `user`'s current approval index value.
function userApprovalIndex(
address user
) external view returns (uint256 result) {
result = centralRegistry.userApprovalIndex(user);
}
/// @notice Returns whether `delegate` has the ability to act on behalf of
/// `user`.
/// @param user The address to check whether `delegate` has delegation
/// permissions for.
/// @param delegate The address to check delegation permissions of `user`.
/// @return result Indicates whether `delegate` is an approved delegate or
/// not of `user`, true = is a delegate, false = is not
/// a delegate.
function isDelegate(
address user,
address delegate
) external view returns (bool result) {
result = _isDelegate[user][centralRegistry
.userApprovalIndex(user)][delegate];
}
/// @notice Returns whether a user has delegation disabled.
/// @dev This is not a silver bullet for phishing attacks, but, adds
/// an additional wall of defense.
/// @param user The user to check delegation status for.
/// @return result Indicates whether `user` has delegation disabled
/// or not, true = disabled, false = not disabled.
function checkNewDelegationDisabled(
address user
) external view returns (bool result) {
result = centralRegistry.checkNewDelegationDisabled(user);
}
/// INTERNAL FUNCTIONS ///
/// @notice Checks whether `delegate` has the ability to act on behalf of
/// `user`, reverts if they do not.
/// @param user The address to check whether `delegate` has delegation
/// permissions for.
/// @param delegate The address to check delegation permissions of `user`.
function _checkDelegate(address user, address delegate) internal view {
if (
!_isDelegate[user][centralRegistry
.userApprovalIndex(user)][delegate]
) {
revert PluginDelegable__Unauthorized();
}
}
}
// contracts/libraries/CommonLib.sol
/// @title Curvance Common Library
/// @notice A utility library for common functions used throughout the
/// Curvance Protocol.
library CommonLib {
/// @notice Returns whether `tokenA` matches `tokenB` or not.
/// @param tokenA The first token address to compare.
/// @param tokenB The second token address to compare.
/// @return Whether `tokenA` matches `tokenB` or not.
function _isMatchingToken(
address tokenA,
address tokenB
) internal pure returns (bool) {
if (tokenA == tokenB) {
return true;
}
if (_isNative(tokenA) && _isNative(tokenB)) {
return true;
}
return false;
}
/// @notice Returns whether `token` is referring to network gas token
/// or not.
/// @param token The address to review.
/// @return result Whether `token` is referring to network gas token or
/// not.
function _isNative(address token) internal pure returns (bool result) {
result = token == address(0) ||
token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
}
/// @notice Returns balance of `token` for this contract.
/// @param token The token address to query balance of.
/// @return b The balance of `token` inside address(this).
function _balanceOf(address token) internal view returns (uint256 b) {
b = _isNative(token) ? address(this).balance :
IERC20(token).balanceOf(address(this));
}
/// @notice Returns the Oracle Manager in interface form from `cr`.
/// @param cr The address of the Protocol Central Registry.
/// @return oracleManager The Oracle Manager in interface form.
function _oracleManager(
ICentralRegistry cr
) internal view returns (IOracleManager oracleManager) {
oracleManager = IOracleManager(cr.oracleManager());
}
}
// contracts/interfaces/IBorrowableCToken.sol
interface IBorrowableCToken {
/// ICToken GENERIC FUNCTIONS ///
/// @notice Starts a cToken market, executed via marketManager.
/// @dev This initial mint is a failsafe against rounding exploits,
/// although, we protect against them in many ways,
/// better safe than sorry.
/// @param by The account initializing deposits.
function initializeDeposits(address by) external returns (bool);
/// @notice Returns the decimals of the cToken.
/// @dev We pull directly from underlying incase its a proxy contract,
/// and changes decimals on us.
/// @return The number of decimals for this cToken,
/// matching the underlying token.
function decimals() external view returns (uint8);
/// @notice Returns whether the underlying token can be borrowed.
/// @dev true = Borrowable; false = Not Borrowable.
/// @return Whether this token is borrowable or not.
function isBorrowable() external view returns (bool);
/// @notice The token balance of an account.
/// @dev Account address => account token balance.
/// @param account The address of the account to query token balance for.
function balanceOf(address account) external view returns (uint256);
/// @notice Returns the address of the underlying asset.
/// @return The address of the underlying asset.
function asset() external view returns (address);
/// @notice Returns the current vesting yield information.
/// @return vestingRate % per second in `asset()`.
/// @return vestingEnd When the current vesting period ends and interest
/// rates paid will update.
/// @return lastVestingClaim Last time pending vested yield was claimed.
/// @return debtIndex The current market debt index.
function getYieldInformation() external view returns (
uint256 vestingRate,
uint256 vestingEnd,
uint256 lastVestingClaim,
uint256 debtIndex
);
/// @notice Get a snapshot of `account` data in this Curvance token.
/// @dev Used by marketManager to more efficiently perform
/// liquidity checks.
/// NOTE: Does not accrue pending interest as part of the call.
/// @param account The address of the account to snapshot.
/// @return The account snapshot of `account`.
function getSnapshot(
address account
) external view returns (AccountSnapshot memory);
/// @notice Total number of cTokens in circulation.
function totalSupply() external view returns (uint256);
/// @notice Returns the total amount of assets held by the market.
/// @return The total amount of assets held by the market.
function totalAssets() external view returns (uint256);
/// @notice Address of the Market Manager linked to this contract.
function marketManager() external view returns (IMarketManager);
/// @notice Returns the amount of assets that would be exchanged
/// by the vault for `shares` provided.
/// @param shares The number of shares to theoretically use
/// for conversion to assets.
/// @return The number of assets a user would receive for converting
/// `shares`.
function convertToAssets(uint256 shares) external view returns (uint256);
/// @notice Returns share -> asset exchange rate, in `WAD`.
/// @dev Oracle Manager calculates cToken value from this exchange rate.
function exchangeRate() external view returns (uint256);
/// @notice Executes multiple calls in a single transaction.
/// This can be used to update oracle prices before
/// a liquidity dependent action.
function multicall(
Multicall.MulticallAction[] memory calls
) external returns (bytes[] memory results);
/// @notice Caller deposits `assets` into the market and `receiver`
/// receives shares.
/// @param assets The amount of the underlying assets to deposit.
/// @param receiver The account that should receive the shares.
/// @return shares The amount of shares received by `receiver`.
function deposit(
uint256 assets,
address receiver
) external returns (uint256 shares);
/// @notice Caller deposits `assets` into the market, `receiver` receives
/// shares, and collateralization of `assets` is enabled.
/// @dev The caller must be depositing for themselves, or be managing
/// their position through a Position Manager contract.
/// If the caller is not approved to collateralize the function will
/// simply deposit assets on behalf of `receiver`.
/// @param assets The amount of the underlying assets to deposit.
/// @param receiver The account that should receive the shares.
/// @return shares The amount of shares received by `receiver`.
function depositAsCollateral(
uint256 assets,
address receiver
) external returns (uint256 shares);
/// @notice Caller deposits `assets` into the market, `receiver` receives
/// shares, and collateralization of `assets` is enabled.
/// @dev Requires that `receiver` approves the caller prior to
/// collateralize on their behalf.
/// NOTE: Be careful who you approve here!
/// They can delay redemption of assets through repeated
/// collateralization preventing withdrawal.
/// If the caller is not approved to collateralize the function will
/// simply deposit assets on behalf of `receiver`.
/// @param assets The amount of the underlying assets to deposit.
/// @param receiver The account that should receive the shares.
/// @return shares The amount of shares received by `receiver`.
function depositAsCollateralFor(
uint256 assets,
address receiver
) external returns (uint256 shares);
/// @notice Withdraws assets, quoted in `shares` from the market,
/// and burns `owner` shares.
/// @dev Does not force collateral to be withdrawn.
/// @param shares The amount of shares to be redeemed.
/// @param receiver The account that should receive the assets.
/// @param owner The account that will burn their shares to withdraw
/// assets.
/// @return assets The amount of assets redeemed by `owner`.
function redeem(
uint256 shares,
address receiver,
address owner
) external returns (uint256 assets);
/// @notice Withdraws assets, quoted in `shares` from the market,
/// and burns `owner` shares, sending assets to `receiver`.
/// @dev Does not force collateral to be withdrawn.
/// @param shares The amount of shares to redeemed.
/// @param receiver The account that should receive the assets.
/// @param owner The account that will burn their shares to withdraw
/// assets.
/// @return assets The amount of assets redeemed by `owner` and sent to
/// `receiver`.
function redeemFor(
uint256 shares,
address receiver,
address owner
) external returns (uint256 assets);
/// @notice Caller withdraws assets from the market and burns their
/// shares, on behalf of `owner`.
/// @dev Forces collateral to be withdrawn from `owner` collateralPosted.
/// @param shares The amount of shares to redeemed.
/// @param receiver The account that should receive the assets.
/// @param owner The account that will burn their shares to withdraw
/// assets.
/// @return assets The amount of assets redeemed by `owner` and sent to
/// `receiver`.
function redeemCollateralFor(
uint256 shares,
address receiver,
address owner
) external returns (uint256 assets);
/// @notice Used by a Position Manager contract to redeem assets from
/// collateralized shares by `account` to perform a complex
/// action.
/// @param assets The amount of the underlying assets to redeem.
/// @param owner The owner address of assets to redeem.
/// @param action Instructions for a deleverage action containing:
/// cToken Address of the cToken that will be redeemed from
/// and assets swapped into `borrowableCToken` asset.
/// collateralAssets The amount of `cToken` that will be
/// deleveraged, in assets.
/// borrowableCToken Address of the borrowableCToken that
/// will have its debt paid.
/// repayAssets The amount of `borrowableCToken` asset that
/// will be repaid to lenders.
/// swapActions Swap actions instructions converting
/// collateral asset into debt asset to
/// facilitate deleveraging.
/// auxData Optional auxiliary data for execution of a
/// deleverage action.
function withdrawByPositionManager(
uint256 assets,
address owner,
IPositionManager.DeleverageAction memory action
) external;
/// @notice Amount of tokens that has been posted as collateral,
/// in shares.
function marketCollateralPosted() external view returns (uint256);
/// @notice Shares of this token that an account has posted as collateral.
/// @param account The address of the account to check collateral posted
/// of.
function collateralPosted(address account) external view returns (uint256);
/// @notice Transfers tokens from `account` to `liquidator`.
/// @dev Will fail unless called by a cToken during the process
/// of liquidation.
/// @param shares An array containing the number of cToken shares
/// to seize.
/// @param liquidator The account receiving seized cTokens.
/// @param accounts An array containing the accounts having
/// collateral seized.
function seize(
uint256[] calldata shares,
address liquidator,
address[] calldata accounts
) external;
/// @notice Allows users to simulate the effects of their deposit at
/// the current block.
/// @param assets The number of assets to preview a deposit call.
/// @return The shares received for depositing `assets`.
function previewDeposit(uint256 assets) external view returns (uint256);
/// IBorrowableCToken SPECIFIC FUNCTIONS ///
/// @notice Address of the current Dynamic IRM.
function IRM() external view returns (IDynamicIRM);
/// @notice Fee that goes to protocol for interested generated for
/// lenders, in `WAD`.
function interestFee() external view returns (uint256);
/// @notice Can accrue interest yield, configure next interest accrual
/// period, and updates vesting data, if needed.
/// @dev May emit a {RatesAdjusted} event.
function accrueIfNeeded() external;
/// @notice The amount of tokens that has been borrowed as debt,
/// in assets.
function marketOutstandingDebt() external view returns (uint256);
/// @notice Returns the current debt balance for `account`.
/// @dev Note: Pending interest is not applied in this calculation.
/// @param account The address whose debt balance should be calculated.
/// @return result The current outstanding debt balance of `account`.
function debtBalance(
address account
) external view returns (uint256 result);
/// @notice Updates pending interest and returns the current outstanding
/// debt owed by `account`.
/// @param account The address whose debt balance should be calculated.
/// @return result The current outstanding debt of `account`, with pending
/// interest applied.
function debtBalanceUpdated(
address account
) external returns (uint256 result);
/// @notice Updates pending interest and returns the up-to-date exchange
/// rate from the underlying to the BorrowableCToken.
/// @return result The share -> asset exchange rate, in `WAD`.
function exchangeRateUpdated() external returns (uint256);
/// @notice Used by a delegated user to borrow underlying tokens
/// from lenders, based on collateral posted inside this market
/// by `account`.
/// @dev Updates pending interest before executing the borrow.
/// NOTE: Be careful who you approve here!
/// Not only can they take borrowed funds, but, they can delay
/// repayment through repeated borrows preventing withdrawal.
/// @param assets The amount of the underlying asset to borrow.
/// @param receiver The account who will receive the borrowed assets.
/// @param owner The account who will have their assets borrowed
/// against.
function borrowFor(
uint256 assets,
address receiver,
address owner
) external;
/// @notice Used by a Position Manager contract to borrow assets from
/// lenders, based on collateralized shares by `account` to
/// perform a complex action.
/// @param assets The amount of the underlying assets to borrow.
/// @param owner The account address to borrow on behalf of.
/// @param action Instructions for a leverage action containing:
/// borrowableCToken Address of the borrowableCToken that
/// will be borrowed from and assets
/// swapped into `cToken` asset.
/// borrowAssets The amount borrowed from
/// `borrowableCToken`, in assets.
/// cToken Curvance token assets that borrowed funds will be
/// swapped into.
/// swapAction Swap action instructions converting debt
/// asset into collateral asset to facilitate
/// leveraging.
/// auxData Optional auxiliary data for execution of a
/// leverage action.
function borrowForPositionManager(
uint256 assets,
address owner,
IPositionManager.LeverageAction memory action
) external;
/// @notice Repays underlying tokens to lenders, on behalf of `account`,
/// freeing up their collateral posted inside this market.
/// @dev Updates pending interest before executing the repay.
/// @param assets The amount to repay, or 0 for the full outstanding
/// amount.
/// @param owner The account address to repay on behalf of.
function repayFor(uint256 assets, address owner) external;
/// @notice Gets balance of this contract, in terms of the underlying.
/// @dev This excludes changes in underlying token balance by the
/// current transaction, if any.
/// @return The quantity of underlying tokens held by the market.
function assetsHeld() external view returns (uint256);
}
// contracts/interfaces/ICToken.sol
struct AccountSnapshot {
address asset;
address underlying;
uint8 decimals;
bool isCollateral;
uint256 collateralPosted;
uint256 debtBalance;
}
interface ICToken {
/// @notice Starts a cToken market, executed via marketManager.
/// @dev This initial mint is a failsafe against rounding exploits,
/// although, we protect against them in many ways,
/// better safe than sorry.
/// @param by The account initializing deposits.
function initializeDeposits(address by) external returns (bool);
/// @notice Returns the decimals of the cToken.
/// @dev We pull directly from underlying incase its a proxy contract,
/// and changes decimals on us.
/// @return The number of decimals for this cToken,
/// matching the underlying token.
function decimals() external view returns (uint8);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
/// @notice Returns whether the underlying token can be borrowed.
/// @dev true = Borrowable; false = Not Borrowable.
/// @return Whether this token is borrowable or not.
function isBorrowable() external view returns (bool);
/// @notice The token balance of an account.
/// @dev Account address => account token balance.
/// @param account The address of the account to query token balance for.
function balanceOf(address account) external view returns (uint256);
/// @notice Returns the address of the underlying asset.
/// @return The address of the underlying asset.
function asset() external view returns (address);
/// @notice Updates pending assets and returns a snapshot of the cToken
/// and `account` data.
/// @dev Used by marketManager to more efficiently perform
/// liquidity checks.
/// @return result The snapshot of the cToken and `account` data.
function getSnapshotUpdated(
address account
) external returns (AccountSnapshot memory result);
/// @notice Get a snapshot of `account` data in this Curvance token.
/// @dev NOTE: Does not accrue pending assets as part of the call.
/// @param account The address of the account to snapshot.
/// @return The account snapshot of `account`.
function getSnapshot(
address account
) external view returns (AccountSnapshot memory);
/// @notice Total number of cTokens in circulation.
function totalSupply() external view returns (uint256);
/// @notice Returns the total amount of assets held by the market.
/// @return The total amount of assets held by the market.
function totalAssets() external view returns (uint256);
/// @notice Address of the Market Manager linked to this contract.
function marketManager() external view returns (IMarketManager);
/// @notice Returns the amount of assets that would be exchanged
/// by the vault for `shares` provided.
/// @param shares The number of shares to theoretically use
/// for conversion to assets.
/// @return The number of assets a user would receive for converting
/// `shares`.
function convertToAssets(uint256 shares) external view returns (uint256);
/// @notice Updates pending assets and returns the up-to-date exchange
/// rate from the underlying to the BorrowableCToken.
/// @dev Oracle Manager calculates cToken value from this exchange rate.
/// @return The share -> asset exchange rate, in `WAD`.
function exchangeRateUpdated() external returns (uint256) ;
/// @notice Returns the up-to-date exchange rate from the underlying to
/// the BorrowableCToken.
/// @dev Oracle Manager calculates cToken value from this exchange rate.
/// @return The share -> asset exchange rate, in `WAD`.
function exchangeRate() external view returns (uint256);
/// @notice Executes multiple calls in a single transaction.
/// This can be used to update oracle prices before
/// a liquidity dependent action.
function multicall(
Multicall.MulticallAction[] memory calls
) external returns (bytes[] memory results);
/// @notice Caller deposits `assets` into the market and `receiver`
/// receives shares.
/// @param assets The amount of the underlying assets to deposit.
/// @param receiver The account that should receive the shares.
/// @return shares The amount of shares received by `receiver`.
function deposit(
uint256 assets,
address receiver
) external returns (uint256 shares);
/// @notice Caller deposits `assets` into the market, `receiver` receives
/// shares, and collateralization of `assets` is enabled.
/// @dev The caller must be depositing for themselves, or be managing
/// their position through a Position Manager contract.
/// @param assets The amount of the underlying assets to deposit.
/// @param receiver The account that should receive the shares.
/// @return shares The amount of shares received by `receiver`.
function depositAsCollateral(
uint256 assets,
address receiver
) external returns (uint256 shares);
/// @notice Caller deposits `assets` into the market, `receiver` receives
/// shares, and collateralization of `assets` is enabled.
/// @dev Requires that `receiver` approves the caller prior to
/// collateralize on their behalf.
/// NOTE: Be careful who you approve here!
/// They can delay redemption of assets through repeated
/// collateralization preventing withdrawal.
/// @param assets The amount of the underlying assets to deposit.
/// @param receiver The account that should receive the shares.
/// @return shares The amount of shares received by `receiver`.
function depositAsCollateralFor(
uint256 assets,
address receiver
) external returns (uint256 shares);
/// @notice Withdraws assets, quoted in `shares` from the market,
/// and burns `owner` shares.
/// @dev Does not force collateral to be withdrawn.
/// @param shares The amount of shares to be redeemed.
/// @param receiver The account that should receive the assets.
/// @param owner The account that will burn their shares to withdraw
/// assets.
/// @return assets The amount of assets redeemed by `owner`.
function redeem(
uint256 shares,
address receiver,
address owner
) external returns (uint256 assets);
/// @notice Withdraws assets, quoted in `shares` from the market,
/// and burns `owner` shares, sending assets to `receiver`.
/// @dev Does not force collateral to be withdrawn.
/// @param shares The amount of shares to redeemed.
/// @param receiver The account that should receive the assets.
/// @param owner The account that will burn their shares to withdraw
/// assets.
/// @return assets The amount of assets redeemed by `owner` and sent to
/// `receiver`.
function redeemFor(
uint256 shares,
address receiver,
address owner
) external returns (uint256 assets);
/// @notice Caller withdraws assets from the market and burns their
/// shares, on behalf of `owner`.
/// @dev Forces collateral to be withdrawn from `owner` collateralPosted.
/// @param shares The amount of shares to redeemed.
/// @param receiver The account that should receive the assets.
/// @param owner The account that will burn their shares to withdraw
/// assets.
/// @return assets The amount of assets redeemed by `owner` and sent to
/// `receiver`.
function redeemCollateralFor(
uint256 shares,
address receiver,
address owner
) external returns (uint256 assets);
/// @notice Used by a Position Manager contract to redeem assets from
/// collateralized shares by `account` to perform a complex
/// action.
/// @param assets The amount of the underlying assets to redeem.
/// @param owner The owner address of assets to redeem.
/// @param action Instructions for a deleverage action containing:
/// cToken Address of the cToken that will be redeemed from
/// and assets swapped into `borrowableCToken` asset.
/// collateralAssets The amount of `cToken` that will be
/// deleveraged, in assets.
/// borrowableCToken Address of the borrowableCToken that
/// will have its debt paid.
/// repayAssets The amount of `borrowableCToken` asset that
/// will be repaid to lenders.
/// swapActions Swap actions instructions converting
/// collateral asset into debt asset to
/// facilitate deleveraging.
/// auxData Optional auxiliary data for execution of a
/// deleverage action.
function withdrawByPositionManager(
uint256 assets,
address owner,
IPositionManager.DeleverageAction memory action
) external;
/// @notice Amount of tokens that has been posted as collateral,
/// in shares.
function marketCollateralPosted() external view returns (uint256);
/// @notice Shares of this token that an account has posted as collateral.
/// @param account The address of the account to check collateral posted
/// of.
function collateralPosted(address account) external view returns (uint256);
/// @notice Transfers tokens from `account` to `liquidator`.
/// @dev Will fail unless called by a cToken during the process
/// of liquidation.
/// @param shares An array containing the number of cToken shares
/// to seize.
/// @param liquidator The account receiving seized cTokens.
/// @param accounts An array containing the accounts having
/// collateral seized.
function seize(
uint256[] calldata shares,
address liquidator,
address[] calldata accounts
) external;
/// @notice Allows users to simulate the effects of their deposit at
/// the current block.
/// @param assets The number of assets to preview a deposit call.
/// @return The shares received for depositing `assets`.
function previewDeposit(uint256 assets) external view returns (uint256);
}
// contracts/interfaces/IExternalCalldataChecker.sol
interface IExternalCalldataChecker {
/// @notice Inspects calldata for compliance with other swap instruction
/// parameters.
/// @dev Used on swap to inspect and validate calldata safety.
/// @param swapAction Swap action instructions including both direct
/// parameters and decodeable calldata.
/// @param expectedRecipient Address who will receive proceeds of
/// `swapAction`.
function checkCalldata(
SwapperLib.Swap memory swapAction,
address expectedRecipient
) external;
}
// contracts/interfaces/IOracleManager.sol
interface IOracleManager {
/// @notice Retrieves the price of a specified asset from either single
/// or dual oracles.
/// @dev If the asset has one oracle, it fetches the price from a single feed.
/// If it has two or more oracles, it fetches the price from both feeds.
/// @param asset The address of the asset to retrieve the price for.
/// @param inUSD Whether the price should be returned in USD or ETH.
/// @param getLower Whether the lower or higher price should be returned
/// if two feeds are available.
/// @return price The current price of `asset`.
/// @return errorCode An error code related to fetching the price:
/// '0' indicates no error fetching price.
/// '1' indicates that price should be taken with
/// caution.
/// '2' indicates a complete failure in receiving
/// a price.
function getPrice(
address asset,
bool inUSD,
bool getLower
) external view returns (uint256 price, uint256 errorCode);
/// @notice Retrieves the prices of a collateral token and debt token
/// underlyings.
/// @param collateralToken The cToken currently collateralized to price.
/// @param debtToken The cToken borrowed from to price.
/// @param errorCodeBreakpoint The error code that will cause liquidity
/// operations to revert.
/// @return collateralUnderlyingPrice The current price of
/// `collateralToken` underlying.
/// @return debtUnderlyingPrice The current price of `debtToken`
/// underlying.
function getPriceIsolatedPair(
address collateralToken,
address debtToken,
uint256 errorCodeBreakpoint
) external returns (uint256, uint256);
/// @notice Retrieves the prices and account data of multiple assets
/// inside a Curvance Market.
/// @param account The account to retrieve data for.
/// @param assets An array of asset addresses to retrieve the prices for.
/// @param errorCodeBreakpoint The error code that will cause liquidity
/// operations to revert.
/// @return AccountSnapshot[] Contains `assets` data for `account`
/// @return uint256[] Contains prices for `assets`.
/// @return uint256 The number of assets `account` is in.
function getPricesForMarket(
address account,
address[] calldata assets,
uint256 errorCodeBreakpoint
)
external
returns (AccountSnapshot[] memory, uint256[] memory, uint256);
/// @notice Potentially removes the dependency on pricing from `adaptor`
/// for `asset`, triggered by an adaptor's notification of a price
/// feed's removal.
/// @notice Removes a pricing adaptor for `asset` triggered by an
/// adaptor's notification of a price feed's removal.
/// @dev Requires that the adaptor is currently being used for pricing
/// for `asset`.
/// NOTE: This intentionally does not modify asset deviation values
/// because they simply wont be used if there are less than two
/// pricing adaptors in use, so no reason to delete data as
/// when a second pricing adaptor is configured the deviation
/// has the opportunity be to reconfigured anyway.
/// @param asset The address of the asset to potentially remove the
/// pricing adaptor dependency from depending on current
/// `asset` configuration.
function notifyFeedRemoval(address asset) external;
/// @notice Returns the adaptors used for pricing `asset`.
/// @param asset The address of the asset to get pricing adaptors for.
/// @return The current adaptor(s) used for pricing `asset`.
function getPricingAdaptors(
address asset
) external view returns(address[] memory);
/// @notice Address => Adaptor approval status.
/// @param adaptor The address of the adaptor to check.
/// @return True if the adaptor is supported, false otherwise.
function isApprovedAdaptor(address adaptor) external view returns (bool);
/// @notice Whether a token is recognized as a Curvance token or not,
/// if it is, will return its underlying asset address instead
/// of address (0).
/// @return The cToken's underlying asset, or address(0) if not a cToken.
function cTokens(address cToken) external view returns (address);
/// @notice Checks if a given asset is supported by the Oracle Manager.
/// @dev An asset is considered supported if it has one
/// or more associated price feeds.
/// @param asset The address of the asset to check.
/// @return True if the asset is supported, false otherwise.
function isSupportedAsset(address asset) external view returns (bool);
/// @notice Check whether L2 sequencer is valid or down.
/// @return True if sequencer is valid.
function isSequencerValid() external view returns (bool);
}
// contracts/interfaces/IPositionManager.sol
interface IPositionManager {
/// TYPES ///
/// @notice Instructions for a leverage action.
/// @param borrowableCToken Address of the borrowableCToken that will be
/// borrowed from and assets swapped into `cToken`
/// asset.
/// @param borrowAssets The amount borrowed from `borrowableCToken`,
/// in assets.
/// @param cToken Curvance token assets that borrowed funds will be
/// swapped into.
/// @param expectedShares The expected shares received from depositing
/// into `cToken` with swapped `borrowAssets`.
/// @param swapAction Swap action instructions converting debt asset into
/// collateral asset to facilitate leveraging.
/// @param auxData Optional auxiliary data for execution of a leverage
/// action.
struct LeverageAction {
IBorrowableCToken borrowableCToken;
uint256 borrowAssets;
ICToken cToken;
uint256 expectedShares;
SwapperLib.Swap swapAction;
bytes auxData;
}
/// @notice Instructions for a deleverage action.
/// @param cToken Address of the cToken that will be redeemed from and
/// assets swapped into `borrowableCToken` asset.
/// @param collateralAssets The amount of `cToken` that will be
/// deleveraged, in assets.
/// @param borrowableCToken Address of the borrowableCToken that will
/// have its debt paid.
/// @param repayAssets The amount of `borrowableCToken` asset that will
/// be repaid to lenders.
/// @param swapActions Swap actions instructions converting collateral
/// asset into debt asset to facilitate deleveraging.
/// @param auxData Optional auxiliary data for execution of a deleverage
/// action.
struct DeleverageAction {
ICToken cToken;
uint256 collateralAssets;
IBorrowableCToken borrowableCToken;
uint256 repayAssets;
SwapperLib.Swap[] swapActions;
bytes auxData;
}
/// @notice Callback function to execute post borrow of
/// `borrowableCToken`'s asset and swap it to deposit
/// new collateralized shares for `owner`.
/// @dev Measures slippage after this callback validating that `owner`
/// is still within acceptable liquidity requirements.
/// @param borrowableCToken The borrowableCToken borrowed from.
/// @param borrowAssets The amount of `borrowableCToken`'s asset borrowed.
/// @param owner The account borrowing that will be swapped into
/// collateral assets deposited into Curvance.
/// @param action Instructions for a leverage action containing:
/// borrowableCToken Address of the borrowableCToken that
/// will be borrowed from and assets
/// swapped into `cToken` asset.
/// borrowAssets The amount borrowed from
/// `borrowableCToken`, in assets.
/// cToken Curvance token assets that borrowed funds will be
/// swapped into.
/// swapAction Swap action instructions converting debt
/// asset into collateral asset to facilitate
/// leveraging.
/// auxData Optional auxiliary data for execution of a
/// leverage action.
function onBorrow(
address borrowableCToken,
uint256 borrowAssets,
address owner,
LeverageAction memory action
) external;
/// @notice Callback function to execute post redemption of `cToken`'s
/// asset and swap it to repay outstanding debt for `owner`.
/// @dev Measures slippage after this callback validating that `owner`
/// is still within acceptable liquidity requirements.
/// @param cToken The Curvance token redeemed for its underlying.
/// @param collateralAssets The amount of `cToken` underlying redeemed.
/// @param owner The account redeeming collateral that will be used to
/// repay their active debt.
/// @param action Instructions for a deleverage action containing:
/// cToken Address of the cToken that will be redeemed from
/// and assets swapped into `borrowableCToken` asset.
/// collateralAssets The amount of `cToken` that will be
/// deleveraged, in assets.
/// borrowableCToken Address of the borrowableCToken that
/// will have its debt paid.
/// repayAssets The amount of `borrowableCToken` asset that
/// will be repaid to lenders.
/// swapAction Swap actions instructions converting
/// collateral asset into debt asset to
/// facilitate deleveraging.
/// auxData Optional auxiliary data for execution of a
/// deleverage action.
function onRedeem(
address cToken,
uint256 collateralAssets,
address owner,
DeleverageAction memory action
) external;
}
// contracts/libraries/SwapperLib.sol
/// @title Curvance Swapper Library.
/// @notice Helper Library for performing composable swaps with varying
/// degrees of slippage tolerance. "Unsafe" swaps perform a standard
/// slippage check whereas "safe" swaps not only check for standard
/// slippage but also check against the Oracle Manager's prices as
/// well.
/// NOTE: This library does not intend to provide support for fee on
/// transfer tokens though support may be built in the future.
library SwapperLib {
/// TYPES ///
/// @notice Instructions to execute a swap, selling `inputToken` for
/// `outputToken`.
/// @param inputToken Address of input token to swap from.
/// @param inputAmount The amount of `inputToken` to swap.
/// @param outputToken Address of token to swap into.
/// @param target Address of the swapper, usually an aggregator.
/// @param slippage The amount of value-loss acceptable from swapping
/// between tokens.
/// @param call Swap instruction calldata.
struct Swap {
address inputToken;
uint256 inputAmount;
address outputToken;
address target;
uint256 slippage;
bytes call;
}
/// @notice Address identifying a chain's native token.
address public constant native =
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
/// ERRORS ///
error SwapperLib__UnknownCalldata();
error SwapperLib__TokenPrice(address inputToken);
error SwapperLib__Slippage(uint256 slippage);
error SwapperLib__SameTokens();
/// INTERNAL FUNCTIONS ///
/// @notice Swaps `action.inputToken` into a `action.outputToken`
/// without an extra slippage check.
/// @param cr The address of the Protocol Central Registry to pull
/// addresses from.
/// @param action Instructions for a swap action containing:
/// inputToken Address of input token to swap from.
/// inputAmount The amount of `inputToken` to swap.
/// outputToken Address of token to swap into.
/// target Address of the swapper, usually an aggregator.
/// slippage The amount of value-loss acceptable from
/// swapping between tokens.
/// call Swap instruction calldata.
/// @return outAmount The output amount received from swapping.
function _swapUnsafe(
ICentralRegistry cr,
Swap memory action
) internal returns (uint256 outAmount) {
address outputToken = action.outputToken;
address inputToken = action.inputToken;
// Do not use this library if the tokens are the same.
if (CommonLib._isMatchingToken(inputToken, outputToken)) {
revert SwapperLib__SameTokens();
}
address callDataChecker = cr.externalCalldataChecker(action.target);
// Validate we know how to verify this calldata.
if (callDataChecker == address(0)) {
revert SwapperLib__UnknownCalldata();
}
// Verify calldata integrity.
IExternalCalldataChecker(callDataChecker)
.checkCalldata(action, address(this));
// Approve `action.inputToken` to target contract, if necessary.
_approveIfNeeded(inputToken, action.target, action.inputAmount);
// Cache output token from struct for easier querying.
uint256 balanceBefore = CommonLib._balanceOf(outputToken);
uint256 callValue = CommonLib._isNative(inputToken) ?
action.inputAmount : 0;
// Execute the swap.
LowLevelCallsHelper._callWithNative(
action.target,
action.call,
callValue
);
// Remove any excess approval.
_removeApprovalIfNeeded(inputToken, action.target);
outAmount = CommonLib._balanceOf(outputToken) - balanceBefore;
}
/// @notice Swaps `action.inputToken` into a `action.outputToken`
/// with an extra slippage check.
/// @param cr The address of the Protocol Central Registry to pull
/// addresses from.
/// @param action Instructions for a swap action containing:
/// inputToken Address of input token to swap from.
/// inputAmount The amount of `inputToken` to swap.
/// outputToken Address of token to swap into.
/// target Address of the swapper, usually an
/// aggregator.
/// slippage The amount of value-loss acceptable from
/// swapping between tokens.
/// call Swap instruction calldata.
/// @return outAmount The output amount received from swapping.
function _swapSafe(
ICentralRegistry cr,
Swap memory action
) internal returns (uint256 outAmount) {
if (action.slippage >= WAD) {
revert SwapperLib__Slippage(action.slippage);
}
outAmount = _swapUnsafe(cr, action);
IOracleManager om = CommonLib._oracleManager(cr);
uint256 valueIn = _getValue(om, action.inputToken, action.inputAmount);
uint256 valueOut = _getValue(om, action.outputToken, outAmount);
// Check if swap received positive slippage.
if (valueOut > valueIn) {
return outAmount;
}
// Calculate % slippage from executed swap.
uint256 slippage = FixedPointMathLib.mulDivUp(
valueIn - valueOut,
WAD,
valueIn
);
if (slippage > action.slippage) {
revert SwapperLib__Slippage(slippage);
}
}
/// @notice Get the value of a token amount.
/// @notice Approves `token` spending allowance, if needed.
/// @param om The Oracle Manager address to call for pricing `token`.
/// @param token The token address to get the value of.
/// @param amount The amount of `token` to get the value of.
function _getValue(
IOracleManager om,
address token,
uint256 amount
) internal view returns (uint256 result) {
// If token is native, normalize to address(0) so it is compatible
// with the Oracle Manager.
if (token == address(0)) {
token = native;
}
(uint256 price, uint256 errorCode) = om.getPrice(token, true, true);
if (errorCode != NO_ERROR) {
revert SwapperLib__TokenPrice(token);
}
// Return price in WAD form.
result = FixedPointMathLib.mulDiv(
price,
amount,
10 ** (CommonLib._isNative(token) ? 18 : IERC20(token).decimals())
);
}
/// @notice Approves `token` spending allowance, if needed.
/// @param token The token address to approve.
/// @param spender The spender address.
/// @param amount The approval amount.
function _approveIfNeeded(
address token,
address spender,
uint256 amount
) internal {
if (!CommonLib._isNative(token)) {
SafeTransferLib.safeApprove(token, spender, amount);
}
}
/// @notice Removes `token` spending allowance, if needed.
/// @param token The token address to remove approval.
/// @param spender The spender address.
function _removeApprovalIfNeeded(address token, address spender) internal {
if (!CommonLib._isNative(token)) {
if (IERC20(token).allowance(address(this), spender) > 0) {
SafeTransferLib.safeApprove(token, spender, 0);
}
}
}
}
// contracts/market/position-management/BasePositionManager.sol
/// @title Curvance Base Position Manager.
/// @notice Base contract for executing leverage related actions.
/// @dev Curvance Position Manager contracts enshrine actions that
/// usually would require multiple sequential actions to facilitate,
/// specifically leveraging a position up or deleveraging it for
/// withdrawal.
///
/// Curvance token contracts facilitate these operations through
/// enshrined integrations with Position Manager callback functions.
///
/// NOTE:
/// Position Manager checks tokens against listed market manager token
/// list. If a market manager ever lists a token with callbacks such as
/// ERC777 this can allow callbacks to occur which could potentially
/// cause issues. Market with callback enabled tokens SHOULD NOT be
/// hooked up to a position manager contract.
///
/// Typical workflow for:
/// Leverage -> borrow assets from a borrowableCToken -> swap debt assets
/// into collateral assets -> deposit collateral assets and collateralize
/// received shares -> check that there is no liquidity shortfall from
/// the initial assets borrowed versus the new collateralized shares.
///
/// Deleverage -> redeem collateralized shares from a cToken for assets
/// -> swap collateral assets for debt assets -> repay outstanding debt
/// with debt assets -> check that there is no liquidity shortfall from
/// the initial shares redeemed versus the newly decreased outstanding
/// debt.
///
/// The "base" contract is the basis on which all position manager are
/// built on top of.
///
abstract contract BasePositionManager is
IPositionManager,
PluginDelegable,
ERC165,
ReentrancyGuard,
Multicall
{
/// CONSTANTS ///
/// @notice The address of wrapped native token on this chain.
address public immutable wrappedNative;
/// @notice Address of the Market Manager linked to this contract.
IMarketManager public immutable marketManager;
/// ERRORS ///
error BasePositionManager__Unauthorized();
error BasePositionManager__InvalidSlippage();
error BasePositionManager__InvalidMarketManager();
error BasePositionManager__InvalidParam();
error BasePositionManager__InvalidAmount();
error BasePositionManager__InvalidTokenPrice();
error BasePositionManager__InsufficientAssetsForRepayment();
/// MODIFIERS ///
/// @dev Executes a predeposit to a leverage action.
/// @param assets The amount of the underlying assets to deposit.
/// @param cToken Curvance token to deposit `assets` into.
modifier preDeposit(uint256 assets, ICToken cToken) {
address collateralAsset = cToken.asset();
// Transfer `collateralAsset` to deposit.
SafeTransferLib.safeTransferFrom(
collateralAsset,
msg.sender,
address(this),
assets
);
// Approve cToken to process a deposit.
SwapperLib._approveIfNeeded(collateralAsset, address(cToken), assets);
// Deposit and collateralize `collateralAsset` in cToken contract.
cToken.depositAsCollateral(assets, msg.sender);
// Remove any excess approval.
SwapperLib._removeApprovalIfNeeded(collateralAsset, address(cToken));
_;
}
/// @dev Checks slippage prior to and after leverage/deleverage action,
/// works similar to reentryguard with pre and post checks.
/// NOTE: This slippage check is primarily a sanity check rather than
/// a security guarantee that users should rely on for protection.
/// Users should perform their own slippage calculations and validations
/// before executing leverage/deleverage operations.
/// @param slippage Slippage accepted by the user for execution of
/// `action` leverage action, in `WAD`.
modifier checkSlippage(address account, uint256 slippage) {
(uint256 collateralBefore, , uint256 debtBefore) = marketManager
.statusOf(account);
uint256 valueIn = collateralBefore - debtBefore;
_;
(uint256 collateralAfter, , uint256 debtAfter) = marketManager
.statusOf(account);
uint256 valueOut = collateralAfter - debtAfter;
// If there was slippage, make sure its within slippage tolerance.
if (valueIn > valueOut) {
if ((valueIn - valueOut) > _mulDiv(valueIn, slippage, WAD)) {
revert BasePositionManager__InvalidSlippage();
}
}
}
/// CONSTRUCTOR ///
/// @param cr The address of the Protocol Central Registry.
/// @param mm The address of the MarketManager which manages liquidity
/// positions between linked cTokens inside a joint market.
/// @param wNative The address of wrapped native token.
constructor(
ICentralRegistry cr,
address mm,
address wNative
) PluginDelegable(cr) {
// Validate that `mm` is configured as a Market Manager inside the
// Protocol Central Registry.
if (!cr.isMarketManager(mm)) {
revert BasePositionManager__InvalidMarketManager();
}
marketManager = IMarketManager(mm);
wrappedNative = wNative;
}
/// EXTERNAL FUNCTIONS ///
/// @notice Allows contract to receive native gas tokens.
receive() external payable {}
/// @notice Deposits into a Curvance position and then leverages in favor
/// of increasing both collateral and debt inside the system.
/// @dev Measures slippage through pre/post conditional slippage check
/// in `checkSlippage` modifier.
/// NOTE: This position manager MUST be recognized as an official
/// Position Manager by the market manager connected to
/// `action.cToken`. Also, the caller MUST have approved this smart
/// contract to have delegated actions inside `action.cToken`.
/// Otherwise, the leveraged deposit will fail.
/// @param assets The amount of the underlying assets to deposit.
/// @param action Instructions for a leverage action containing:
/// borrowableCToken Address of the borrowableCToken that
/// will be borrowed from and assets
/// swapped into `cToken` asset.
/// borrowAssets The amount borrowed from
/// `borrowableCToken`, in assets.
/// cToken Curvance token assets that borrowed funds will be
/// swapped into.
/// swapAction Swap action instructions converting debt
/// asset into collateral asset to facilitate
/// leveraging.
/// auxData Optional auxiliary data for execution of a
/// leverage action.
/// @param slippage Slippage accepted by the user for execution of
/// `action` leverage action, in WAD (1e18).
function depositAndLeverage(
uint256 assets,
LeverageAction calldata action,
uint256 slippage
) external nonReentrant preDeposit(
assets,
action.cToken
) checkSlippage(msg.sender, slippage) {
// Execute pre deposit, then the leverage action.
_leverage(action, msg.sender);
}
/// @notice Leverages an active Curvance position in favor of increasing
/// both collateral and debt inside the system.
/// @dev Measures slippage through pre/post conditional slippage check
/// in `checkSlippage` modifier.
/// @param action Instructions for a leverage action containing:
/// borrowableCToken Address of the borrowableCToken that
/// will be borrowed from and assets
/// swapped into `cToken` asset.
/// borrowAssets The amount borrowed from
/// `borrowableCToken`, in assets.
/// cToken Curvance token assets that borrowed funds will be
/// swapped into.
/// swapAction Swap action instructions converting debt
/// asset into collateral asset to facilitate
/// leveraging.
/// auxData Optional auxiliary data for execution of a
/// leverage action.
/// @param slippage Slippage accepted by the user for execution of
/// `action` leverage action, in WAD (1e18).
function leverage(
LeverageAction calldata action,
uint256 slippage
) external nonReentrant checkSlippage(msg.sender, slippage) {
// Execute leverage action.
_leverage(action, msg.sender);
}
/// @notice Leverages an active Curvance position in favor of increasing
/// both collateral and debt inside the system, via delegation.
/// @dev Measures slippage through pre/post conditional slippage check
/// in `checkSlippage` modifier.
/// NOTE: Be careful who you approve here!
/// The caller can select slippage, potentially causing loss of funds
/// if delegation is provided to a malicious party.
/// @param action Instructions for a leverage action containing:
/// borrowableCToken Address of the borrowableCToken that
/// will be borrowed from and assets
/// swapped into `cToken` asset.
/// borrowAssets The amount borrowed from
/// `borrowableCToken`, in assets.
/// cToken Curvance token assets that borrowed funds will be
/// swapped into.
/// swapAction Swap action instructions converting debt
/// asset into collateral asset to facilitate
/// leveraging.
/// auxData Optional auxiliary data for execution of a
/// leverage action.
/// @param account The account to leverage an active Curvance position
/// for.
/// @param slippage Slippage accepted by the user for execution of
/// `action` leverage action, in WAD (1e18).
function leverageFor(
LeverageAction calldata action,
address account,
uint256 slippage
) external nonReentrant checkSlippage(account, slippage) {
_checkDelegate(account, msg.sender);
// Check for delegation permissions, then the leverage action.
_leverage(action, account);
}
/// @notice Deleverages an active Curvance position in favor of decreasing
/// both collateral and debt inside the system.
/// @dev Measures slippage through pre/post conditional slippage check
/// in `checkSlippage` modifier.
/// NOTE: Be careful who you approve here!
/// The caller can select slippage, potentially causing loss of funds
/// if delegation is provided to a malicious party.
/// @param action Instructions for a deleverage action containing:
/// cToken Address of the cToken that will be redeemed from
/// and assets swapped into `borrowableCToken` asset.
/// collateralAssets The amount of `cToken` that will be
/// deleveraged, in assets.
/// borrowableCToken Address of the borrowableCToken that
/// will have its debt paid.
/// repayAssets The amount of `borrowableCToken` asset that
/// will be repaid to lenders.
/// swapActions Swap actions instructions converting
/// collateral asset into debt asset to
/// facilitate deleveraging.
/// auxData Optional auxiliary data for execution of a
/// deleverage action.
/// @param slippage Slippage accepted by the user for execution of
/// `action` deleverage action, in WAD (1e18).
function deleverage(
DeleverageAction calldata action,
uint256 slippage
) external nonReentrant checkSlippage(msg.sender, slippage) {
// Execute deleverage action.
_deleverage(action, msg.sender);
}
/// @notice Deleverages an active Curvance position in favor of decreasing
/// both collateral and debt inside the system, via delegation.
/// @dev Measures slippage through pre/post conditional slippage check
/// in `checkSlippage` modifier.
/// @param action Instructions for a deleverage action containing:
/// cToken Address of the cToken that will be redeemed from
/// and assets swapped into `borrowableCToken` asset.
/// collateralAssets The amount of `cToken` that will be
/// deleveraged, in assets.
/// borrowableCToken Address of the borrowableCToken that
/// will have its debt paid.
/// repayAssets The amount of `borrowableCToken` asset that
/// will be repaid to lenders.
/// swapActions Swap actions instructions converting
/// collateral asset into debt asset to
/// facilitate deleveraging.
/// auxData Optional auxiliary data for execution of a
/// deleverage action.
/// @param account The account to deleverage an active Curvance position
/// for.
/// @param slippage Slippage accepted by the user for execution of
/// `action` deleverage action, in WAD (1e18).
function deleverageFor(
DeleverageAction calldata action,
address account,
uint256 slippage
) external nonReentrant checkSlippage(account, slippage) {
_checkDelegate(account, msg.sender);
// Check for delegation permissions, then the deleverage action.
_deleverage(action, account);
}
/// @notice Callback function to execute post borrow of
/// `borrowableCToken`'s asset and swap it to deposit
/// new collateralized shares for `owner`.
/// @dev Measures slippage after this callback validating that `owner`
/// is still within acceptable liquidity requirements.
/// @param borrowableCToken The borrowable token borrowed from.
/// @param borrowAssets The amount of `borrowableCToken`'s asset borrowed.
/// @param owner The account borrowing that will be swapped into
/// collateral assets deposited into Curvance.
/// @param action Instructions for a leverage action containing:
/// borrowableCToken Address of the borrowableCToken that
/// will be borrowed from and assets
/// swapped into `cToken` asset.
/// borrowAssets The amount borrowed from
/// `borrowableCToken`, in assets.
/// cToken Curvance token assets that borrowed funds will be
/// swapped into.
/// swapAction Swap action instructions converting debt
/// asset into collateral asset to facilitate
/// leveraging.
/// auxData Optional auxiliary data for execution of a
/// leverage action.
function onBorrow(
address borrowableCToken,
uint256 borrowAssets,
address owner,
LeverageAction memory action
) external override {
ICToken cToken = action.cToken;
// Validate action.cToken is a listed Curvance market to prevent callbacks
// through untrusted tokens during the callback context.
if (!marketManager.isListed(address(cToken))) {
revert BasePositionManager__Unauthorized();
}
// Cache debt asset address.
address debtAsset = IBorrowableCToken(borrowableCToken).asset();
// Validate that `cToken` is listed inside `marketManager` and is the
// caller, then that the action instructions are built correct, then
// take the protocol fee, if any.
action.borrowAssets = _validateInputsAndApplyFee(
borrowableCToken,
borrowAssets,
address(action.borrowableCToken),
action.borrowAssets,
debtAsset
);
// Unwrap leverage instructions for collateral deposit.
address collateralAsset = cToken.asset();
// Swap borrowed assets into collateral asset underlying.
_swapDebtAssetToCollateralAsset(action, owner);
uint256 amount = IERC20(collateralAsset).balanceOf(address(this));
// Approve `amount` of `collateralAsset` to `cToken` contract.
SwapperLib._approveIfNeeded(collateralAsset, address(cToken), amount);
// Enter Curvance collateral position.
uint256 shares = cToken.depositAsCollateral(amount, owner);
// Make sure sufficient shares were received from deposit action.
if (shares < action.expectedShares) {
revert BasePositionManager__InvalidSlippage();
}
uint256 remaining = IERC20(debtAsset).balanceOf(address(this));
// Transfer remaining borrow underlying back to the user.
if (remaining > 0) {
SafeTransferLib.safeTransfer(debtAsset, owner, remaining);
}
// Remove any excess approval.
SwapperLib._removeApprovalIfNeeded(collateralAsset, address(cToken));
}
/// @notice Callback function to execute post redemption of `cToken`'s
/// asset and swap it to repay outstanding debt for `owner`.
/// @dev Measures slippage after this callback validating that `owner`
/// is still within acceptable liquidity requirements.
/// @param cToken The cToken redeemed for its underlying.
/// @param collateralAssets The amount of `cToken` underlying redeemed.
/// @param owner The account redeeming collateral that will be used to
/// repay their active debt.
/// @param action Instructions for a deleverage action containing:
/// cToken Address of the cToken that will be redeemed from
/// and assets swapped into `borrowableCToken` asset.
/// collateralAssets The amount of `cToken` that will be
/// deleveraged, in assets.
/// borrowableCToken Address of the borrowableCToken that
/// will have its debt paid.
/// repayAssets The amount of `borrowableCToken` asset that
/// will be repaid to lenders.
/// swapActions Swap actions instructions converting
/// collateral asset into debt asset to
/// facilitate deleveraging.
/// auxData Optional auxiliary data for execution of a
/// deleverage action.
function onRedeem(
address cToken,
uint256 collateralAssets,
address owner,
DeleverageAction memory action
) external override {
IBorrowableCToken borrowableCToken = action.borrowableCToken;
if (!marketManager.isListed(address(borrowableCToken))) {
revert BasePositionManager__Unauthorized();
}
// Cache collateral asset address.
address collateralAsset = ICToken(cToken).asset();
// Validate that `cToken` is listed inside `marketManager` and is the
// caller, then that the action instructions are built correct, then
// take the protocol fee, if any.
action.collateralAssets = _validateInputsAndApplyFee(
cToken,
collateralAssets,
address(action.cToken),
action.collateralAssets,
collateralAsset
);
// Swap redeemed `collateralAsset` assets into debt token assets.
_swapCollateralAssetToDebtAsset(action);
// Unwrap deleverage instructions for debt repayment.
address debtAsset = borrowableCToken.asset();
uint256 assetsHeld = IERC20(debtAsset).balanceOf(address(this));
uint256 repayAssets = action.repayAssets;
if (repayAssets == 0) {
// Accrue any interest owed so repayAssets includes all
// `owner` debt.
repayAssets = borrowableCToken.debtBalanceUpdated(owner);
}
if (repayAssets > assetsHeld) {
revert BasePositionManager__InsufficientAssetsForRepayment();
}
uint256 remaining = assetsHeld - repayAssets;
// Approve `repayAssets` of `debtAsset` to `borrowableCToken` contract.
SwapperLib._approveIfNeeded(
debtAsset,
address(borrowableCToken),
repayAssets
);
// Repay debt.
borrowableCToken.repayFor(repayAssets, owner);
// Transfer remaining borrow underlying back to user.
if (remaining > 0) {
SafeTransferLib.safeTransfer(debtAsset, owner, remaining);
}
remaining = IERC20(collateralAsset).balanceOf(address(this));
// Transfer remaining collateral underlying back to the user.
if (remaining > 0) {
SafeTransferLib.safeTransfer(collateralAsset, owner, remaining);
}
// Transfer remaining swap dust back to the user.
uint256 numSwaps = action.swapActions.length;
if (numSwaps > 0) {
for (uint256 i; i < numSwaps; ++i) {
remaining =
CommonLib._balanceOf(action.swapActions[i].outputToken);
if (remaining > 0) {
_transferToRecipient(
action.swapActions[i].outputToken,
owner,
remaining
);
}
}
}
// Remove any excess approval.
SwapperLib._removeApprovalIfNeeded(
debtAsset,
address(borrowableCToken)
);
}
/// PUBLIC FUNCTIONS ///
/// @inheritdoc ERC165
function supportsInterface(
bytes4 interfaceId
) public view override returns (bool result) {
result = interfaceId == type(IPositionManager).interfaceId ||
super.supportsInterface(interfaceId);
}
/// INTERNAL FUNCTIONS ///
/// @notice Validate `action` parameters versus function parameters and
/// apply any protocol fee.
/// @param cToken The Curvance token given from function parameters,
/// should be token used during the callback action.
/// @param assets The amount of `cTokenUnderlying` given from function
/// parameters to be used during the callback action.
/// @param actionToken The Curvance token given from `action` parameters,
/// should be token used during the callback action.
/// @param actionAssets The amount of `cTokenUnderlying` given from
/// `action` parameters to be used during the callback
/// action.
/// @param cTokenUnderlying The `asset()` token of `cToken`.
/// @return The `cTokenUnderlying` assets for callback action potentially
/// with fee applied.
function _validateInputsAndApplyFee(
address cToken,
uint256 assets,
address actionToken,
uint256 actionAssets,
address cTokenUnderlying
) internal returns (uint256) {
// Validate that the token itself is executing the callback and
// `cToken` is actually listed in this Market Manager.
if (msg.sender != cToken || !marketManager.isListed(cToken)) {
revert BasePositionManager__Unauthorized();
}
// Validate enough `cTokenUnderlying` was received to preform desired
// action.
if (IERC20(cTokenUnderlying).balanceOf(address(this)) < assets) {
revert BasePositionManager__InvalidAmount();
}
// Validate that calldata matches explicit action inputs.
if (cToken != address(actionToken) || assets != actionAssets) {
revert BasePositionManager__InvalidParam();
}
// Calculate protocol fee, rounded up, in favor of protocol.
uint256 fee = FixedPointMathLib.mulDivUp(
actionAssets,
centralRegistry.protocolLeverageFee(),
BPS
);
// Apply protocol fee, if there is any.
if (fee > 0) {
actionAssets -= fee;
SafeTransferLib.safeTransfer(
cTokenUnderlying,
centralRegistry.daoAddress(),
fee
);
}
// Return `cTokenUnderlying` assets for callback action potentially
// with fee applied.
return actionAssets;
}
/// @notice Leverages an active Curvance position in favor of increasing
/// both collateral and debt inside the system.
/// @param action Instructions for a leverage action containing:
/// borrowableCToken Address of the borrowableCToken that
/// will be borrowed from and assets
/// swapped into `cToken` asset.
/// borrowAssets The amount borrowed from
/// `borrowableCToken`, in assets.
/// cToken Curvance token assets that borrowed funds will be
/// swapped into.
/// swapAction Swap action instructions converting debt
/// asset into collateral asset to facilitate
/// leveraging.
/// auxData Optional auxiliary data for execution of a
/// leverage action.
/// @param account The account to leverage an active Curvance position
/// for.
function _leverage(
LeverageAction memory action,
address account
) internal {
// Validate `action.borrowableCToken` is a known Curvance token.
if (!marketManager.isListed(address(action.borrowableCToken))) {
revert BasePositionManager__Unauthorized();
}
action.borrowableCToken.borrowForPositionManager(
action.borrowAssets,
account,
action
);
}
/// @notice Deleverages an active Curvance position in favor of decreasing
/// both collateral and debt inside the system.
/// @param action Instructions for a deleverage action containing:
/// cToken Address of the cToken that will be redeemed from
/// and assets swapped into `borrowableCToken` asset.
/// collateralAssets The amount of `cToken` that will be
/// deleveraged, in assets.
/// borrowableCToken Address of the borrowableCToken that
/// will have its debt paid.
/// repayAssets The amount of `borrowableCToken` asset that
/// will be repaid to lenders.
/// swapActions Swap actions instructions converting
/// collateral asset into debt asset to
/// facilitate deleveraging.
/// auxData Optional auxiliary data for execution of a
/// deleverage action.
/// @param account The account to deleverage an active Curvance position
/// for.
function _deleverage(
DeleverageAction memory action,
address account
) internal {
// Validate `action.cToken` is a known Curvance token.
if (!marketManager.isListed(address(action.cToken))) {
revert BasePositionManager__Unauthorized();
}
action.cToken.withdrawByPositionManager(
action.collateralAssets,
account,
action
);
}
/// @notice Helper function for efficiently transferring tokens
/// to desired user.
/// @param token The token to transfer to `recipient`,
/// this can be the network gas token.
/// @param recipient The user receiving `token`.
/// @param amount The amount of `token` to be transferred to `recipient`.
function _transferToRecipient(
address token,
address recipient,
uint256 amount
) internal {
// If the token to refund is the chains' native gas token we wrap
// then transfer it to prevent callback attack vectors.
if (CommonLib._isNative(token)) {
IWETH(wrappedNative).deposit{ value: amount }();
token = wrappedNative;
}
// Transfer `amount` tokens to refund to `recipient`.
SafeTransferLib.safeTransfer(token, recipient, amount);
}
/// @dev Returns `floor(x * y / d)`.
/// Reverts if `x * y` overflows, or `d` is zero.
function _mulDiv(
uint256 x,
uint256 y,
uint256 d
) internal pure returns (uint256 z) {
z = FixedPointMathLib.mulDiv(x, y, d);
}
/// @notice Returns the Central Registry contract in interface form.
function _getCentralRegistry()
internal
view
override
returns (ICentralRegistry)
{
return centralRegistry;
}
/// INTERNAL FUNCTIONS TO OVERRIDE ///
/// @notice Callback function on borrowing tokens from a Curvance token
/// providing instant liquidity in the debt token underlying which
/// is then swapped into the underlying of a collateral token that
/// a user currently has collateralized against the debt position,
/// creating/increasing a leveraged spot position.
/// @dev MUST be overridden in every Position Manager implementation.
function _swapDebtAssetToCollateralAsset(
LeverageAction memory, /* action */
address /* receiver */
) internal virtual;
/// @notice Callback function on redemption of tokens from a Curvance token
/// providing instant liquidity in the collateral token underlying
/// which is then swapped into the underlying of a debt token that
/// a user is currently borrowing from, partially or fully closing
/// a leveraged spot position.
/// @dev MUST be overridden in every Position Manager implementation.
function _swapCollateralAssetToDebtAsset(
DeleverageAction memory /* action */
) internal virtual;
}
// contracts/market/position-management/SimplePositionManager.sol
/// @title Curvance Simple Position Manager.
/// @notice Simple Asset-specific contract for executing leverage related
/// actions.
/// @dev Curvance Position Manager contracts enshrine actions that
/// usually would require multiple sequential actions to facilitate,
/// specifically leveraging a position up or deleveraging it for
/// withdrawal.
///
/// Curvance token contracts facilitate these operations through
/// enshrined integrations with Position Manager callback functions.
///
/// Typical workflow for:
/// Leverage -> borrow assets from a borrowableCToken -> swap debt assets
/// into collateral assets -> deposit collateral assets and collateralize
/// received shares -> check that there is no liquidity shortfall from
/// the initial assets borrowed versus the new collateralized shares.
///
/// Deleverage -> redeem collateralized shares from a cToken for assets
/// -> swap collateral assets for debt assets -> repay outstanding debt
/// with debt assets -> check that there is no liquidity shortfall from
/// the initial shares redeemed versus the newly decreased outstanding
/// debt.
///
/// The "Simple" contract is the position manager for working with
/// generic non-native erc20 tokens such as USDC or WETH.
///
contract SimplePositionManager is BasePositionManager {
/// CONSTRUCTOR ///
/// @param cr The address of the Protocol Central Registry.
/// @param mm The address of the MarketManager which manages liquidity
/// positions between linked cTokens inside a joint market.
/// @param wNative The address of wrapped native token.
constructor(
ICentralRegistry cr,
address mm,
address wNative
) BasePositionManager(cr, mm, wNative) {}
/// @notice Callback function on borrowing tokens from an borrowableCToken
/// contract providing instant liquidity in the borrowableCToken
/// underlying which is then swapped into the underlying of a
/// cToken that a user is currently putting up as collateral
/// against the borrowableCToken debt position, creating a
/// leveraged spot position.
/// @param action Instructions for a leverage action containing:
/// borrowableCToken Address of the borrowableCToken that
/// will be borrowed from and assets
/// swapped into `cToken` asset.
/// borrowAssets The amount borrowed from
/// `borrowableCToken`, in assets.
/// cToken Curvance token assets that borrowed funds will be
/// swapped into.
/// swapAction Swap action instructions converting debt
/// asset into collateral asset to facilitate
/// leveraging.
/// auxData Optional auxiliary data for execution of a
/// leverage action.
function _swapDebtAssetToCollateralAsset(
LeverageAction memory action,
address /* receiver */
) internal virtual override {
address debtAsset = action.borrowableCToken.asset();
address collateralAsset = action.cToken.asset();
// This check implies they have selected the same cToken as both
// cToken and borrowableCToken, otherwise its not possible to have
// the same underlying.
if (CommonLib._isMatchingToken(debtAsset, collateralAsset)) {
revert BasePositionManager__InvalidParam();
}
SwapperLib.Swap memory swapAction = action.swapAction;
if (
swapAction.call.length == 0 ||
swapAction.target == address(0) ||
swapAction.inputToken != debtAsset ||
swapAction.outputToken != collateralAsset ||
swapAction.inputAmount != action.borrowAssets
) {
revert BasePositionManager__InvalidParam();
}
// Swap debt asset to collateral asset.
SwapperLib._swapSafe(centralRegistry, swapAction);
}
/// @notice Callback function on redemption of tokens from a cToken vault
/// providing instant liquidity in the cToken underlying which is
/// then swapped into the underlying of an borrowableCToken that a
/// user is currently borrowing from, partially or fully closing a
/// leveraged spot position.
/// @param action Instructions for a deleverage action containing:
/// cToken Address of the cToken that will be redeemed from
/// and assets swapped into `borrowableCToken` asset.
/// collateralAssets The amount of `cToken` that will be
/// deleveraged, in assets.
/// borrowableCToken Address of the borrowableCToken that
/// will have its debt paid.
/// repayAssets The amount of `borrowableCToken` asset that
/// will be repaid to lenders.
/// swapActions Swap actions instructions converting
/// collateral asset into debt asset to
/// facilitate deleveraging.
/// auxData Optional auxiliary data for execution of a
/// deleverage action.
function _swapCollateralAssetToDebtAsset(
DeleverageAction memory action
) internal virtual override {
address collateralAsset = action.cToken.asset();
address debtAsset = action.borrowableCToken.asset();
// This check implies they have selected the same cToken as both
// cToken and borrowableCToken, otherwise its not possible to have
// the same underlying.
if (CommonLib._isMatchingToken(debtAsset, collateralAsset)) {
revert BasePositionManager__InvalidParam();
}
// For simple actions there should only ever be one swap.
if (action.swapActions.length != 1) {
revert BasePositionManager__InvalidParam();
}
// Load the one swap action.
SwapperLib.Swap memory swapAction = action.swapActions[0];
if (
swapAction.call.length == 0 ||
swapAction.target == address(0) ||
swapAction.inputToken != collateralAsset ||
swapAction.outputToken != debtAsset ||
swapAction.inputAmount != action.collateralAssets
) {
revert BasePositionManager__InvalidParam();
}
// Swap collateral asset to debt asset.
SwapperLib._swapSafe(centralRegistry, swapAction);
}
}
// contracts/market/position-management/NativeVaultPositionManager.sol
/// @title Curvance Native Vault Position Manager.
/// @notice Native Vault-specific contract for executing leverage related
/// actions.
/// @dev Curvance Position Manager contracts enshrine actions that
/// usually would require multiple sequential actions to facilitate,
/// specifically leveraging a position up or deleveraging it for
/// withdrawal.
///
/// Curvance token contracts facilitate these operations through
/// enshrined integrations with Position Manager callback functions.
///
/// Typical workflow for:
/// Leverage -> borrow assets from a borrowableCToken -> swap debt assets
/// into collateral assets -> deposit collateral assets and collateralize
/// received shares -> check that there is no liquidity shortfall from
/// the initial assets borrowed versus the new collateralized shares.
///
/// Deleverage -> redeem collateralized shares from a cToken for assets
/// -> swap collateral assets for debt assets -> repay outstanding debt
/// with debt assets -> check that there is no liquidity shortfall from
/// the initial shares redeemed versus the newly decreased outstanding
/// debt.
///
/// The "Native Vault" contract is the position manager for working with
/// native-token based erc4626-like tokens such as shMON or aprMON. No type
/// specific "_swapCollateralAssetToDebtAsset" is written as execution is
/// intended to be the same as the "simple" position manager where
/// collateral is simply swapped via dex aggregator. The expectation is
/// that if the best path is erc4626 redemption versus general swapping a
/// mature chain's dex aggregator will support redemption via erc4626
/// vault contract.
///
contract NativeVaultPositionManager is SimplePositionManager {
/// CONSTRUCTOR ///
/// @param cr The address of the Protocol Central Registry.
/// @param mm The address of the MarketManager which manages liquidity
/// positions between linked cTokens inside a joint market.
/// @param wNative The address of wrapped native token.
constructor(
ICentralRegistry cr,
address mm,
address wNative
) SimplePositionManager(cr, mm, wNative) {}
/// INTERNAL FUNCTIONS ///
/// @notice Borrow callback: convert the debt asset to native (unwrap wrapped native
/// if already wrapped; otherwise swap once to native), then deposit native
/// into the ERC4626 vault to mint shares.
/// @dev If `debtAsset == wrappedNative`, unwrap to native and deposit.
/// Otherwise validate and execute exactly one aggregator swap from
/// `debtAsset` -> native.
/// @param action Instructions for a leverage action containing:
/// borrowableCToken Address of the borrowableCToken that
/// will be borrowed from and assets
/// swapped into `cToken` asset.
/// borrowAssets The amount borrowed from
/// `borrowableCToken`, in assets.
/// cToken Curvance token assets that borrowed funds will be
/// swapped into.
/// swapAction Swap action instructions converting debt
/// asset into collateral asset to facilitate
/// leveraging.
/// auxData Optional auxiliary data for execution of a
/// leverage action.
function _swapDebtAssetToCollateralAsset(
LeverageAction memory action,
address /* receiver */
) internal override {
address debtAsset = action.borrowableCToken.asset();
if (debtAsset == wrappedNative) {
// Wrapped asset to native.
IWETH(wrappedNative).withdraw(action.borrowAssets);
} else {
SwapperLib.Swap memory swapAction = action.swapAction;
// Validate swap.
if (
swapAction.call.length == 0 ||
swapAction.target == address(0) ||
swapAction.inputToken != debtAsset ||
swapAction.inputAmount != action.borrowAssets ||
!CommonLib._isNative(swapAction.outputToken)
) {
revert BasePositionManager__InvalidParam();
}
// Swap `debtAsset` to vault `underlying`, update action assets.
action.borrowAssets =
SwapperLib._swapSafe(centralRegistry, swapAction);
}
// Validate we have tokens to deposit into the vault.
if (action.borrowAssets == 0) {
revert BasePositionManager__InvalidAmount();
}
// Call the vault contract, the asset of the cToken.
IVault(action.cToken.asset()).deposit{value: action.borrowAssets}
(action.borrowAssets, address(this));
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract ICentralRegistry","name":"cr","type":"address"},{"internalType":"address","name":"mm","type":"address"},{"internalType":"address","name":"wNative","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BasePositionManager__InsufficientAssetsForRepayment","type":"error"},{"inputs":[],"name":"BasePositionManager__InvalidAmount","type":"error"},{"inputs":[],"name":"BasePositionManager__InvalidMarketManager","type":"error"},{"inputs":[],"name":"BasePositionManager__InvalidParam","type":"error"},{"inputs":[],"name":"BasePositionManager__InvalidSlippage","type":"error"},{"inputs":[],"name":"BasePositionManager__InvalidTokenPrice","type":"error"},{"inputs":[],"name":"BasePositionManager__Unauthorized","type":"error"},{"inputs":[],"name":"CentralRegistryLib__InvalidCentralRegistry","type":"error"},{"inputs":[],"name":"LowLevelCallsHelper__CallFailed","type":"error"},{"inputs":[],"name":"LowLevelCallsHelper__InsufficientBalance","type":"error"},{"inputs":[],"name":"Multicall__InvalidTarget","type":"error"},{"inputs":[],"name":"Multicall__UnknownCalldata","type":"error"},{"inputs":[],"name":"PluginDelegable_InvalidParameter","type":"error"},{"inputs":[],"name":"PluginDelegable__DelegatingDisabled","type":"error"},{"inputs":[],"name":"PluginDelegable__Unauthorized","type":"error"},{"inputs":[],"name":"Reentrancy","type":"error"},{"inputs":[],"name":"SwapperLib__SameTokens","type":"error"},{"inputs":[{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"SwapperLib__Slippage","type":"error"},{"inputs":[{"internalType":"address","name":"inputToken","type":"address"}],"name":"SwapperLib__TokenPrice","type":"error"},{"inputs":[],"name":"SwapperLib__UnknownCalldata","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"approvalIndex","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isApproved","type":"bool"}],"name":"DelegateApproval","type":"event"},{"inputs":[],"name":"centralRegistry","outputs":[{"internalType":"contract ICentralRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"checkNewDelegationDisabled","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"contract ICToken","name":"cToken","type":"address"},{"internalType":"uint256","name":"collateralAssets","type":"uint256"},{"internalType":"contract IBorrowableCToken","name":"borrowableCToken","type":"address"},{"internalType":"uint256","name":"repayAssets","type":"uint256"},{"components":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"bytes","name":"call","type":"bytes"}],"internalType":"struct SwapperLib.Swap[]","name":"swapActions","type":"tuple[]"},{"internalType":"bytes","name":"auxData","type":"bytes"}],"internalType":"struct IPositionManager.DeleverageAction","name":"action","type":"tuple"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"deleverage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"contract ICToken","name":"cToken","type":"address"},{"internalType":"uint256","name":"collateralAssets","type":"uint256"},{"internalType":"contract IBorrowableCToken","name":"borrowableCToken","type":"address"},{"internalType":"uint256","name":"repayAssets","type":"uint256"},{"components":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"bytes","name":"call","type":"bytes"}],"internalType":"struct SwapperLib.Swap[]","name":"swapActions","type":"tuple[]"},{"internalType":"bytes","name":"auxData","type":"bytes"}],"internalType":"struct IPositionManager.DeleverageAction","name":"action","type":"tuple"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"deleverageFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"components":[{"internalType":"contract IBorrowableCToken","name":"borrowableCToken","type":"address"},{"internalType":"uint256","name":"borrowAssets","type":"uint256"},{"internalType":"contract ICToken","name":"cToken","type":"address"},{"internalType":"uint256","name":"expectedShares","type":"uint256"},{"components":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"bytes","name":"call","type":"bytes"}],"internalType":"struct SwapperLib.Swap","name":"swapAction","type":"tuple"},{"internalType":"bytes","name":"auxData","type":"bytes"}],"internalType":"struct IPositionManager.LeverageAction","name":"action","type":"tuple"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"depositAndLeverage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"delegate","type":"address"}],"name":"isDelegate","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"contract IBorrowableCToken","name":"borrowableCToken","type":"address"},{"internalType":"uint256","name":"borrowAssets","type":"uint256"},{"internalType":"contract ICToken","name":"cToken","type":"address"},{"internalType":"uint256","name":"expectedShares","type":"uint256"},{"components":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"bytes","name":"call","type":"bytes"}],"internalType":"struct SwapperLib.Swap","name":"swapAction","type":"tuple"},{"internalType":"bytes","name":"auxData","type":"bytes"}],"internalType":"struct IPositionManager.LeverageAction","name":"action","type":"tuple"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"leverage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IBorrowableCToken","name":"borrowableCToken","type":"address"},{"internalType":"uint256","name":"borrowAssets","type":"uint256"},{"internalType":"contract ICToken","name":"cToken","type":"address"},{"internalType":"uint256","name":"expectedShares","type":"uint256"},{"components":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"bytes","name":"call","type":"bytes"}],"internalType":"struct SwapperLib.Swap","name":"swapAction","type":"tuple"},{"internalType":"bytes","name":"auxData","type":"bytes"}],"internalType":"struct IPositionManager.LeverageAction","name":"action","type":"tuple"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"leverageFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"marketManager","outputs":[{"internalType":"contract IMarketManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"isPriceUpdate","type":"bool"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Multicall.MulticallAction[]","name":"calls","type":"tuple[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"borrowableCToken","type":"address"},{"internalType":"uint256","name":"borrowAssets","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"components":[{"internalType":"contract IBorrowableCToken","name":"borrowableCToken","type":"address"},{"internalType":"uint256","name":"borrowAssets","type":"uint256"},{"internalType":"contract ICToken","name":"cToken","type":"address"},{"internalType":"uint256","name":"expectedShares","type":"uint256"},{"components":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"bytes","name":"call","type":"bytes"}],"internalType":"struct SwapperLib.Swap","name":"swapAction","type":"tuple"},{"internalType":"bytes","name":"auxData","type":"bytes"}],"internalType":"struct IPositionManager.LeverageAction","name":"action","type":"tuple"}],"name":"onBorrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"uint256","name":"collateralAssets","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"components":[{"internalType":"contract ICToken","name":"cToken","type":"address"},{"internalType":"uint256","name":"collateralAssets","type":"uint256"},{"internalType":"contract IBorrowableCToken","name":"borrowableCToken","type":"address"},{"internalType":"uint256","name":"repayAssets","type":"uint256"},{"components":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"bytes","name":"call","type":"bytes"}],"internalType":"struct SwapperLib.Swap[]","name":"swapActions","type":"tuple[]"},{"internalType":"bytes","name":"auxData","type":"bytes"}],"internalType":"struct IPositionManager.DeleverageAction","name":"action","type":"tuple"}],"name":"onRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegate","type":"address"},{"internalType":"bool","name":"isApproved","type":"bool"}],"name":"setDelegateApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"userApprovalIndex","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wrappedNative","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60e060405234801561000f575f5ffd5b50604051613c74380380613c7483398101604081905261002e91610209565b8282828282828261003e816100e9565b6001600160a01b03908116608052604051637d5528bd60e01b8152838216600482015290841690637d5528bd90602401602060405180830381865afa158015610089573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100ad9190610253565b6100ca57604051630afb42eb60e01b815260040160405180910390fd5b6001600160a01b0391821660c0521660a0525061027295505050505050565b6100fa816399011ef160e01b61011a565b610117576040516369b5e45b60e11b815260040160405180910390fd5b50565b5f6101248361013c565b80156101355750610135838361016f565b9392505050565b5f61014e826301ffc9a760e01b61016f565b80156101695750610167826001600160e01b031961016f565b155b92915050565b6040516001600160e01b0319821660248201525f90819060440160408051601f19818403018152919052602080820180516001600160e01b03166301ffc9a760e01b17815282519293505f9283928392909183918a617530fa92503d91505f5190508280156101df575060208210155b80156101ea57505f81115b979650505050505050565b6001600160a01b0381168114610117575f5ffd5b5f5f5f6060848603121561021b575f5ffd5b8351610226816101f5565b6020850151909350610237816101f5565b6040850151909250610248816101f5565b809150509250925092565b5f60208284031215610263575f5ffd5b81518015158114610135575f5ffd5b60805160a05160c0516139146103605f395f8181610142015281816103cd015281816108cb01528181610c2d01528181610ce001528181610f0d01528181610fc0015281816111790152818161170e015281816117cb015281816118f6015281816119c30152818161236001526124d301525f818161031301528181611f3201528181611fa2015281816120ca015261211d01525f818161022a0152818161080c015281816110bf01528181611241015281816112e7015281816113f10152818161146001528181611b1901528181611bb901528181611e190152818161220e015261268c01526139145ff3fe6080604052600436106100f2575f3560e01c80639616756e11610087578063e8bbf5d711610057578063e8bbf5d7146102d6578063eb6d3a1114610302578063ebf1965314610335578063fe391e8c14610354575f5ffd5b80639616756e1461024c578063abaa0bbf1461026b578063c3c854b61461028a578063e6248d55146102a9575f5ffd5b806363e6a0e4116100c257806363e6a0e4146101bc5780637f848328146101db57806387c88173146101fa5780638f73dcfa14610219575f5ffd5b806301ffc9a7146100fd57806341ed2c12146101315780634e908d061461017c5780635fec5d0b1461019d575f5ffd5b366100f957005b5f5ffd5b348015610108575f5ffd5b5061011c610117366004612d86565b610373565b60405190151581526020015b60405180910390f35b34801561013c575f5ffd5b506101647f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610128565b348015610187575f5ffd5b5061019b610196366004613067565b6103a9565b005b3480156101a8575f5ffd5b5061011c6101b73660046130ce565b6107d7565b3480156101c7575f5ffd5b5061019b6101d6366004613173565b6108a7565b3480156101e6575f5ffd5b5061019b6101f53660046131e4565b610bde565b348015610205575f5ffd5b5061019b610214366004613225565b610dba565b348015610224575f5ffd5b506101647f000000000000000000000000000000000000000000000000000000000000000081565b348015610257575f5ffd5b5061011c610266366004613271565b61109e565b348015610276575f5ffd5b5061019b6102853660046131e4565b61112a565b348015610295575f5ffd5b5061019b6102a4366004613299565b611203565b3480156102b4575f5ffd5b506102c86102c3366004613271565b6113d0565b604051908152602001610128565b3480156102e1575f5ffd5b506102f56102f03660046132c5565b61145c565b6040516101289190613362565b34801561030d575f5ffd5b506101647f000000000000000000000000000000000000000000000000000000000000000081565b348015610340575f5ffd5b5061019b61034f3660046133c5565b6116be565b34801561035f575f5ffd5b5061019b61036e3660046133c5565b6118a6565b5f6001600160e01b031982166316bb16f160e11b14806103a357506301ffc9a760e01b6001600160e01b03198316145b92915050565b6040818101519051637bca031760e11b81526001600160a01b0380831660048301527f0000000000000000000000000000000000000000000000000000000000000000169063f794062e90602401602060405180830381865afa158015610412573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610436919061341a565b6104535760405163792b839760e11b815260040160405180910390fd5b5f856001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610490573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104b49190613435565b90506104ca8686855f0151866020015185611990565b60208401526104d883611c48565b5f826001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610515573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105399190613435565b6040516370a0823160e01b81523060048201529091505f906001600160a01b038316906370a0823190602401602060405180830381865afa158015610580573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a49190613450565b60608601519091505f819003610620576040516357d159d560e01b81526001600160a01b0388811660048301528616906357d159d5906024016020604051808303815f875af11580156105f9573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061061d9190613450565b90505b81811115610641576040516329efdcc960e11b815260040160405180910390fd5b5f61064c828461347b565b9050610659848784611e45565b604051632796469160e21b8152600481018390526001600160a01b038981166024830152871690639e591a44906044015f604051808303815f87803b1580156106a0575f5ffd5b505af11580156106b2573d5f5f3e3d5ffd5b505050505f8111156106c9576106c9848983611e62565b6040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa15801561070b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061072f9190613450565b9050801561074257610742858983611e62565b60808701515180156107c0575f5b818110156107be57610782896080015182815181106107715761077161348e565b602002602001015160400151611ea2565b925082156107b6576107b6896080015182815181106107a3576107a361348e565b6020026020010151604001518b85611f22565b600101610750565b505b6107ca8588611fcf565b5050505050505050505050565b6001600160a01b038281165f81815260208190526040808220905163e6248d5560e01b815260048101939093529092909183917f0000000000000000000000000000000000000000000000000000000000000000169063e6248d5590602401602060405180830381865afa158015610851573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108759190613450565b815260208082019290925260409081015f9081206001600160a01b039095168152939091529091205460ff1692915050565b6040818101519051637bca031760e11b81526001600160a01b0380831660048301527f0000000000000000000000000000000000000000000000000000000000000000169063f794062e90602401602060405180830381865afa158015610910573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610934919061341a565b6109515760405163792b839760e11b815260040160405180910390fd5b5f856001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561098e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109b29190613435565b90506109c88686855f0151866020015185611990565b8360200181815250505f826001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a0e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a329190613435565b9050610a3e8486612062565b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015610a82573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aa69190613450565b9050610ab3828583611e45565b604051632f4a61d960e01b8152600481018290526001600160a01b0387811660248301525f9190861690632f4a61d9906044016020604051808303815f875af1158015610b02573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b269190613450565b90508560600151811015610b4d576040516375633b0560e11b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038616906370a0823190602401602060405180830381865afa158015610b91573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb59190613450565b90508015610bc857610bc8858983611e62565b610bd28487611fcf565b50505050505050505050565b688000000000ab143c065c15610bfb5763ab143c065f526004601cfd5b30688000000000ab143c065d6040516397a5d5b560e01b815233600482018190529082905f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906397a5d5b5906024016060604051808303815f875af1158015610c73573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9791906134a2565b92505091505f8183610ca9919061347b565b9050610cbd610cb7886134cd565b3361233f565b6040516397a5d5b560e01b81526001600160a01b0386811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906397a5d5b5906024016060604051808303815f875af1158015610d26573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d4a91906134a2565b92505091505f8183610d5c919061347b565b905080841115610da257610d798488670de0b6b3a764000061244f565b610d83828661347b565b1115610da2576040516375633b0560e11b815260040160405180910390fd5b50505050505050505f688000000000ab143c065d5050565b688000000000ab143c065c15610dd75763ab143c065f526004601cfd5b30688000000000ab143c065d82610df46060840160408501613271565b5f816001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e31573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e559190613435565b9050610e6381333086612463565b610e6e818385611e45565b604051632f4a61d960e01b8152600481018490523360248201526001600160a01b03831690632f4a61d9906044016020604051808303815f875af1158015610eb8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610edc9190613450565b50610ee78183611fcf565b6040516397a5d5b560e01b815233600482018190529085905f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906397a5d5b5906024016060604051808303815f875af1158015610f53573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f7791906134a2565b92505091505f8183610f89919061347b565b9050610f9d610f978b6134d8565b336124b2565b6040516397a5d5b560e01b81526001600160a01b0386811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906397a5d5b5906024016060604051808303815f875af1158015611006573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102a91906134a2565b92505091505f818361103c919061347b565b905080841115611082576110598488670de0b6b3a764000061244f565b611063828661347b565b1115611082576040516375633b0560e11b815260040160405180910390fd5b50505050505050505050505f688000000000ab143c065d505050565b604051634b0b3ab760e11b81526001600160a01b0382811660048301525f917f000000000000000000000000000000000000000000000000000000000000000090911690639616756e90602401602060405180830381865afa158015611106573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103a3919061341a565b688000000000ab143c065c156111475763ab143c065f526004601cfd5b30688000000000ab143c065d6040516397a5d5b560e01b815233600482018190529082905f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906397a5d5b5906024016060604051808303815f875af11580156111bf573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111e391906134a2565b92505091505f81836111f5919061347b565b9050610cbd610f97886134d8565b336001600160a01b0383160361122c57604051636eef2f3f60e11b815260040160405180910390fd5b604051634b0b3ab760e11b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639616756e90602401602060405180830381865afa15801561128e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112b2919061341a565b156112d0576040516302d5da9f60e01b815260040160405180910390fd5b60405163e6248d5560e01b81523360048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e6248d5590602401602060405180830381865afa158015611334573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113589190613450565b335f8181526020818152604080832085845282528083206001600160a01b03891680855290835292819020805460ff191688151590811790915581518681529283015293945090927ffeeb3502e62327bd3fece59983b972dc941e6abedd652971aac3adea23cf7e17910160405180910390a3505050565b60405163e6248d5560e01b81526001600160a01b0382811660048301525f917f00000000000000000000000000000000000000000000000000000000000000009091169063e6248d5590602401602060405180830381865afa158015611438573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103a39190613450565b60607f000000000000000000000000000000000000000000000000000000000000000082806001600160401b0381111561149857611498612dcb565b6040519080825280602002602001820160405280156114cb57816020015b60608152602001906001900390816114b65790505b5060408051606080820183525f80835260208301819052928201529194505b828110156116b4578686828181106115045761150461348e565b905060200281019061151691906134e3565b61151f90613501565b915081602001511561165657815160405163191d0cc560e11b81526001600160a01b0391821660048201525f9186169063323a198a90602401602060405180830381865afa158015611573573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115979190613435565b90506001600160a01b0381166115c057604051632f3285fb60e21b815260040160405180910390fd5b8251604080850151905163bd0226d760e01b81526001600160a01b0384169263bd0226d7926115f59233929190600401613586565b5f604051808303815f87803b15801561160c575f5ffd5b505af115801561161e573d5f5f3e3d5ffd5b50505050611633835f01518460400151612591565b8683815181106116455761164561348e565b6020026020010181905250506116ac565b81516001600160a01b0316301461168057604051637720ccd960e01b815260040160405180910390fd5b61168e308360400151612606565b8582815181106116a0576116a061348e565b60200260200101819052505b6001016114ea565b5050505092915050565b688000000000ab143c065c156116db5763ab143c065f526004601cfd5b30688000000000ab143c065d6040516397a5d5b560e01b81526001600160a01b038084166004830152839183915f9182917f000000000000000000000000000000000000000000000000000000000000000016906397a5d5b5906024016060604051808303815f875af1158015611754573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061177891906134a2565b92505091505f818361178a919061347b565b9050611796873361265a565b6117a86117a2896134cd565b8861233f565b6040516397a5d5b560e01b81526001600160a01b0386811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906397a5d5b5906024016060604051808303815f875af1158015611811573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061183591906134a2565b92505091505f8183611847919061347b565b90508084111561188d576118648488670de0b6b3a764000061244f565b61186e828661347b565b111561188d576040516375633b0560e11b815260040160405180910390fd5b50505050505050505f688000000000ab143c065d505050565b688000000000ab143c065c156118c35763ab143c065f526004601cfd5b30688000000000ab143c065d6040516397a5d5b560e01b81526001600160a01b038084166004830152839183915f9182917f000000000000000000000000000000000000000000000000000000000000000016906397a5d5b5906024016060604051808303815f875af115801561193c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061196091906134a2565b92505091505f8183611972919061347b565b905061197e873361265a565b6117a861198a896134d8565b886124b2565b5f336001600160a01b038716141580611a2e5750604051637bca031760e11b81526001600160a01b0387811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063f794062e90602401602060405180830381865afa158015611a08573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a2c919061341a565b155b15611a4c5760405163792b839760e11b815260040160405180910390fd5b6040516370a0823160e01b815230600482015285906001600160a01b038416906370a0823190602401602060405180830381865afa158015611a90573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ab49190613450565b1015611ad3576040516307d198f760e11b815260040160405180910390fd5b836001600160a01b0316866001600160a01b0316141580611af45750828514155b15611b12576040516307c426b560e21b815260040160405180910390fd5b5f611b9f847f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663fe5764846040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b73573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b979190613450565b61271061273d565b90508015611c3d57611bb1818561347b565b9350611c3d837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632131c68c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c13573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c379190613435565b83611e62565b509195945050505050565b5f815f01516001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c88573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cac9190613435565b90505f82604001516001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611cef573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d139190613435565b9050611d1f8183612769565b15611d3d576040516307c426b560e21b815260040160405180910390fd5b826080015151600114611d63576040516307c426b560e21b815260040160405180910390fd5b5f83608001515f81518110611d7a57611d7a61348e565b602002602001015190508060a00151515f1480611da2575060608101516001600160a01b0316155b80611dc25750826001600160a01b0316815f01516001600160a01b031614155b80611de35750816001600160a01b031681604001516001600160a01b031614155b80611df657508360200151816020015114155b15611e14576040516307c426b560e21b815260040160405180910390fd5b611e3e7f0000000000000000000000000000000000000000000000000000000000000000826127b9565b5050505050565b611e4e8361288d565b611e5d57611e5d8383836128c2565b505050565b816014528060345263a9059cbb60601b5f5260205f604460105f875af13d1560015f51141716611e99576390b8ec185f526004601cfd5b5f603452505050565b5f611eac8261288d565b611f1b576040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015611ef2573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f169190613450565b6103a3565b4792915050565b611f2b8361288d565b15611fc4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004015f604051808303818588803b158015611f89575f5ffd5b505af1158015611f9b573d5f5f3e3d5ffd5b50505050507f000000000000000000000000000000000000000000000000000000000000000092505b611e5d838383611e62565b611fd88261288d565b61205e57604051636eb1769f60e11b81523060048201526001600160a01b0382811660248301525f919084169063dd62ed3e90604401602060405180830381865afa158015612029573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061204d9190613450565b111561205e5761205e82825f6128c2565b5050565b5f825f01516001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120a2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120c69190613435565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031603612181576020830151604051632e1a7d4d60e01b815260048101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d906024015f604051808303815f87803b158015612166575f5ffd5b505af1158015612178573d5f5f3e3d5ffd5b5050505061223a565b608083015160a08101515115806121a3575060608101516001600160a01b0316155b806121c35750816001600160a01b0316815f01516001600160a01b031614155b806121d657508360200151816020015114155b806121eb57506121e9816040015161288d565b155b15612209576040516307c426b560e21b815260040160405180910390fd5b6122337f0000000000000000000000000000000000000000000000000000000000000000826127b9565b6020850152505b82602001515f0361225e576040516307d198f760e11b815260040160405180910390fd5b82604001516001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561229e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122c29190613435565b6020840151604051636e553f6560e01b8152600481018290523060248201526001600160a01b039290921691636e553f65919060440160206040518083038185885af1158015612314573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906123399190613450565b50505050565b8151604051637bca031760e11b81526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063f794062e90602401602060405180830381865afa1580156123a7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123cb919061341a565b6123e85760405163792b839760e11b815260040160405180910390fd5b8151602083015160405163bdca672360e01b81526001600160a01b039092169163bdca67239161241e9185908790600401613609565b5f604051808303815f87803b158015612435575f5ffd5b505af1158015612447573d5f5f3e3d5ffd5b505050505050565b5f61245b8484846128f9565b949350505050565b60405181606052826040528360601b602c526323b872dd60601b600c5260205f6064601c5f895af13d1560015f511417166124a557637939f4245f526004601cfd5b5f60605260405250505050565b8151604051637bca031760e11b81526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063f794062e90602401602060405180830381865afa15801561251a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061253e919061341a565b61255b5760405163792b839760e11b815260040160405180910390fd5b8151602083015160405163010b626160e71b81526001600160a01b03909216916385b130809161241e91859087906004016136e6565b60605f5f846001600160a01b03165f856040516125ae919061376c565b5f6040518083038185875af1925050503d805f81146125e8576040519150601f19603f3d011682016040523d82523d5f602084013e6125ed565b606091505b50915091506125fd85838361291d565b95945050505050565b60605f5f846001600160a01b031684604051612622919061376c565b5f60405180830381855af49150503d805f81146125e8576040519150601f19603f3d011682016040523d82523d5f602084013e6125ed565b6001600160a01b038281165f81815260208190526040808220905163e6248d5560e01b815260048101939093529290917f00000000000000000000000000000000000000000000000000000000000000009091169063e6248d5590602401602060405180830381865afa1580156126d3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126f79190613450565b815260208082019290925260409081015f9081206001600160a01b038516825290925290205460ff1661205e576040516367ee2b0160e11b815260040160405180910390fd5b5f825f19048411830215820261275a5763ad251c275f526004601cfd5b50910281810615159190040190565b5f816001600160a01b0316836001600160a01b03160361278b575060016103a3565b6127948361288d565b80156127a457506127a48261288d565b156127b1575060016103a3565b505f92915050565b5f670de0b6b3a76400008260800151106127f75781608001516040516319b3b4a760e01b81526004016127ee91815260200190565b60405180910390fd5b6128018383612965565b90505f61280d84612b07565b90505f61282282855f01518660200151612b68565b90505f61283483866040015186612b68565b905081811115612846575050506103a3565b5f612863612854838561347b565b670de0b6b3a76400008561273d565b905085608001518111156116b4576040516319b3b4a760e01b8152600481018290526024016127ee565b5f6001600160a01b03821615806103a35750506001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b816014528060345263095ea7b360601b5f5260205f604460105f875af13d1560015f51141716611e9957633e3f8f735f526004601cfd5b5f825f1904841183021582026129165763ad251c275f526004601cfd5b5091020490565b60606129298383612ccb565b815115801561294057506001600160a01b0384163b155b1561295e576040516314859aeb60e21b815260040160405180910390fd5b5092915050565b604081015181515f91906129798183612769565b1561299757604051636991e51560e11b815260040160405180910390fd5b6060840151604051631d4686fd60e31b81526001600160a01b0391821660048201525f9187169063ea3437e890602401602060405180830381865afa1580156129e2573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a069190613435565b90506001600160a01b038116612a2f57604051637409771560e11b815260040160405180910390fd5b60405163383d5bf360e11b81526001600160a01b0382169063707ab7e690612a5d9088903090600401613782565b5f604051808303815f87803b158015612a74575f5ffd5b505af1158015612a86573d5f5f3e3d5ffd5b50505050612a9d8286606001518760200151611e45565b5f612aa784611ea2565b90505f612ab38461288d565b612abd575f612ac3565b86602001515b9050612ad887606001518860a0015183612cf9565b50612ae7848860600151611fcf565b81612af186611ea2565b612afb919061347b565b98975050505050505050565b5f816001600160a01b031663565d878c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b44573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103a39190613435565b5f6001600160a01b038316612b8f5773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92505b604051635ae6916360e01b81526001600160a01b03848116600483015260016024830181905260448301525f918291871690635ae69163906064016040805180830381865afa158015612be4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c0891906137ab565b915091505f8114612c37576040516383a1fb8b60e01b81526001600160a01b03861660048201526024016127ee565b612cc18285612c458861288d565b612cae57876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c85573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ca991906137cd565b612cb1565b60125b612cbc90600a6138d0565b6128f9565b9695505050505050565b8161205e5780515f03612cf1576040516314859aeb60e21b815260040160405180910390fd5b805181602001fd5b606081471015612d1c5760405163595909b560e11b815260040160405180910390fd5b5f5f856001600160a01b03168486604051612d37919061376c565b5f6040518083038185875af1925050503d805f8114612d71576040519150601f19603f3d011682016040523d82523d5f602084013e612d76565b606091505b5091509150612cc186838361291d565b5f60208284031215612d96575f5ffd5b81356001600160e01b031981168114612dad575f5ffd5b9392505050565b6001600160a01b0381168114612dc8575f5ffd5b50565b634e487b7160e01b5f52604160045260245ffd5b60405160c081016001600160401b0381118282101715612e0157612e01612dcb565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612e2f57612e2f612dcb565b604052919050565b8035612e4281612db4565b919050565b5f82601f830112612e56575f5ffd5b81356001600160401b03811115612e6f57612e6f612dcb565b612e82601f8201601f1916602001612e07565b818152846020838601011115612e96575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f60c08284031215612ec2575f5ffd5b612eca612ddf565b90508135612ed781612db4565b8152602082810135908201526040820135612ef181612db4565b60408201526060820135612f0481612db4565b60608201526080828101359082015260a08201356001600160401b03811115612f2b575f5ffd5b612f3784828501612e47565b60a08301525092915050565b5f82601f830112612f52575f5ffd5b81356001600160401b03811115612f6b57612f6b612dcb565b8060051b612f7b60208201612e07565b91825260208185018101929081019086841115612f96575f5ffd5b6020860192505b83831015612cc15782356001600160401b03811115612fba575f5ffd5b612fc9886020838a0101612eb2565b83525060209283019290910190612f9d565b5f60c08284031215612feb575f5ffd5b612ff3612ddf565b9050612ffe82612e37565b81526020828101359082015261301660408301612e37565b60408201526060828101359082015260808201356001600160401b0381111561303d575f5ffd5b61304984828501612f43565b60808301525060a08201356001600160401b03811115612f2b575f5ffd5b5f5f5f5f6080858703121561307a575f5ffd5b843561308581612db4565b935060208501359250604085013561309c81612db4565b915060608501356001600160401b038111156130b6575f5ffd5b6130c287828801612fdb565b91505092959194509250565b5f5f604083850312156130df575f5ffd5b82356130ea81612db4565b915060208301356130fa81612db4565b809150509250929050565b5f60c08284031215613115575f5ffd5b61311d612ddf565b905061312882612e37565b81526020828101359082015261314060408301612e37565b60408201526060828101359082015260808201356001600160401b03811115613167575f5ffd5b61304984828501612eb2565b5f5f5f5f60808587031215613186575f5ffd5b843561319181612db4565b93506020850135925060408501356131a881612db4565b915060608501356001600160401b038111156131c2575f5ffd5b6130c287828801613105565b5f60c082840312156131de575f5ffd5b50919050565b5f5f604083850312156131f5575f5ffd5b82356001600160401b0381111561320a575f5ffd5b613216858286016131ce565b95602094909401359450505050565b5f5f5f60608486031215613237575f5ffd5b8335925060208401356001600160401b03811115613253575f5ffd5b61325f868287016131ce565b93969395505050506040919091013590565b5f60208284031215613281575f5ffd5b8135612dad81612db4565b8015158114612dc8575f5ffd5b5f5f604083850312156132aa575f5ffd5b82356132b581612db4565b915060208301356130fa8161328c565b5f5f602083850312156132d6575f5ffd5b82356001600160401b038111156132eb575f5ffd5b8301601f810185136132fb575f5ffd5b80356001600160401b03811115613310575f5ffd5b8560208260051b8401011115613324575f5ffd5b6020919091019590945092505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156133b957603f198786030184526133a4858351613334565b94506020938401939190910190600101613388565b50929695505050505050565b5f5f5f606084860312156133d7575f5ffd5b83356001600160401b038111156133ec575f5ffd5b6133f8868287016131ce565b935050602084013561340981612db4565b929592945050506040919091013590565b5f6020828403121561342a575f5ffd5b8151612dad8161328c565b5f60208284031215613445575f5ffd5b8151612dad81612db4565b5f60208284031215613460575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156103a3576103a3613467565b634e487b7160e01b5f52603260045260245ffd5b5f5f5f606084860312156134b4575f5ffd5b5050815160208301516040909301519094929350919050565b5f6103a33683612fdb565b5f6103a33683613105565b5f8235605e198336030181126134f7575f5ffd5b9190910192915050565b5f60608236031215613511575f5ffd5b604051606081016001600160401b038111828210171561353357613533612dcb565b604052823561354181612db4565b815260208301356135518161328c565b602082015260408301356001600160401b0381111561356e575f5ffd5b61357a36828601612e47565b60408301525092915050565b6001600160a01b038481168252831660208201526060604082018190525f906125fd90830184613334565b80516001600160a01b03908116835260208083015190840152604080830151821690840152606080830151909116908301526080808201519083015260a08181015160c09184018290525f9161245b90850182613334565b83815260018060a01b0383166020820152606060408201525f610120820160018060a01b0384511660608401526020840151608084015260018060a01b0360408501511660a0840152606084015160c0840152608084015160c060e0850152818151808452610140860191506101408160051b87010193506020830192505f5b818110156136bb5761013f198786030183526136a68585516135b1565b94506020938401939290920191600101613689565b5050505060a0840151838203605f19016101008501526136db8282613334565b979650505050505050565b83815260018060a01b03831660208201526060604082015260018060a01b0382511660608201526020820151608082015260018060a01b0360408301511660a0820152606082015160c08201525f608083015160c060e084015261374e6101208401826135b1565b905060a0840151605f19848303016101008501526136db8282613334565b5f82518060208501845e5f920191825250919050565b604081525f61379460408301856135b1565b905060018060a01b03831660208301529392505050565b5f5f604083850312156137bc575f5ffd5b505080516020909101519092909150565b5f602082840312156137dd575f5ffd5b815160ff81168114612dad575f5ffd5b6001815b60018411156138285780850481111561380c5761380c613467565b600184161561381a57908102905b60019390931c9280026137f1565b935093915050565b5f8261383e575060016103a3565b8161384a57505f6103a3565b8160018114613860576002811461386a57613886565b60019150506103a3565b60ff84111561387b5761387b613467565b50506001821b6103a3565b5060208310610133831016604e8410600b84101617156138a9575081810a6103a3565b6138b55f1984846137ed565b805f19048211156138c8576138c8613467565b029392505050565b5f612dad60ff84168361383056fea264697066735822122069022c390b5c888ba0cc9a96eddc9c38967cf03a3ed114cae5a6286362eae57864736f6c634300081c00330000000000000000000000001310f352f1389969ece6741671c4b919523912ff000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e20000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a
Deployed Bytecode
0x6080604052600436106100f2575f3560e01c80639616756e11610087578063e8bbf5d711610057578063e8bbf5d7146102d6578063eb6d3a1114610302578063ebf1965314610335578063fe391e8c14610354575f5ffd5b80639616756e1461024c578063abaa0bbf1461026b578063c3c854b61461028a578063e6248d55146102a9575f5ffd5b806363e6a0e4116100c257806363e6a0e4146101bc5780637f848328146101db57806387c88173146101fa5780638f73dcfa14610219575f5ffd5b806301ffc9a7146100fd57806341ed2c12146101315780634e908d061461017c5780635fec5d0b1461019d575f5ffd5b366100f957005b5f5ffd5b348015610108575f5ffd5b5061011c610117366004612d86565b610373565b60405190151581526020015b60405180910390f35b34801561013c575f5ffd5b506101647f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e281565b6040516001600160a01b039091168152602001610128565b348015610187575f5ffd5b5061019b610196366004613067565b6103a9565b005b3480156101a8575f5ffd5b5061011c6101b73660046130ce565b6107d7565b3480156101c7575f5ffd5b5061019b6101d6366004613173565b6108a7565b3480156101e6575f5ffd5b5061019b6101f53660046131e4565b610bde565b348015610205575f5ffd5b5061019b610214366004613225565b610dba565b348015610224575f5ffd5b506101647f0000000000000000000000001310f352f1389969ece6741671c4b919523912ff81565b348015610257575f5ffd5b5061011c610266366004613271565b61109e565b348015610276575f5ffd5b5061019b6102853660046131e4565b61112a565b348015610295575f5ffd5b5061019b6102a4366004613299565b611203565b3480156102b4575f5ffd5b506102c86102c3366004613271565b6113d0565b604051908152602001610128565b3480156102e1575f5ffd5b506102f56102f03660046132c5565b61145c565b6040516101289190613362565b34801561030d575f5ffd5b506101647f0000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a81565b348015610340575f5ffd5b5061019b61034f3660046133c5565b6116be565b34801561035f575f5ffd5b5061019b61036e3660046133c5565b6118a6565b5f6001600160e01b031982166316bb16f160e11b14806103a357506301ffc9a760e01b6001600160e01b03198316145b92915050565b6040818101519051637bca031760e11b81526001600160a01b0380831660048301527f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e2169063f794062e90602401602060405180830381865afa158015610412573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610436919061341a565b6104535760405163792b839760e11b815260040160405180910390fd5b5f856001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610490573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104b49190613435565b90506104ca8686855f0151866020015185611990565b60208401526104d883611c48565b5f826001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610515573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105399190613435565b6040516370a0823160e01b81523060048201529091505f906001600160a01b038316906370a0823190602401602060405180830381865afa158015610580573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a49190613450565b60608601519091505f819003610620576040516357d159d560e01b81526001600160a01b0388811660048301528616906357d159d5906024016020604051808303815f875af11580156105f9573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061061d9190613450565b90505b81811115610641576040516329efdcc960e11b815260040160405180910390fd5b5f61064c828461347b565b9050610659848784611e45565b604051632796469160e21b8152600481018390526001600160a01b038981166024830152871690639e591a44906044015f604051808303815f87803b1580156106a0575f5ffd5b505af11580156106b2573d5f5f3e3d5ffd5b505050505f8111156106c9576106c9848983611e62565b6040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa15801561070b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061072f9190613450565b9050801561074257610742858983611e62565b60808701515180156107c0575f5b818110156107be57610782896080015182815181106107715761077161348e565b602002602001015160400151611ea2565b925082156107b6576107b6896080015182815181106107a3576107a361348e565b6020026020010151604001518b85611f22565b600101610750565b505b6107ca8588611fcf565b5050505050505050505050565b6001600160a01b038281165f81815260208190526040808220905163e6248d5560e01b815260048101939093529092909183917f0000000000000000000000001310f352f1389969ece6741671c4b919523912ff169063e6248d5590602401602060405180830381865afa158015610851573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108759190613450565b815260208082019290925260409081015f9081206001600160a01b039095168152939091529091205460ff1692915050565b6040818101519051637bca031760e11b81526001600160a01b0380831660048301527f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e2169063f794062e90602401602060405180830381865afa158015610910573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610934919061341a565b6109515760405163792b839760e11b815260040160405180910390fd5b5f856001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561098e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109b29190613435565b90506109c88686855f0151866020015185611990565b8360200181815250505f826001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a0e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a329190613435565b9050610a3e8486612062565b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015610a82573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aa69190613450565b9050610ab3828583611e45565b604051632f4a61d960e01b8152600481018290526001600160a01b0387811660248301525f9190861690632f4a61d9906044016020604051808303815f875af1158015610b02573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b269190613450565b90508560600151811015610b4d576040516375633b0560e11b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038616906370a0823190602401602060405180830381865afa158015610b91573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb59190613450565b90508015610bc857610bc8858983611e62565b610bd28487611fcf565b50505050505050505050565b688000000000ab143c065c15610bfb5763ab143c065f526004601cfd5b30688000000000ab143c065d6040516397a5d5b560e01b815233600482018190529082905f9081906001600160a01b037f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e216906397a5d5b5906024016060604051808303815f875af1158015610c73573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9791906134a2565b92505091505f8183610ca9919061347b565b9050610cbd610cb7886134cd565b3361233f565b6040516397a5d5b560e01b81526001600160a01b0386811660048301525f9182917f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e216906397a5d5b5906024016060604051808303815f875af1158015610d26573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d4a91906134a2565b92505091505f8183610d5c919061347b565b905080841115610da257610d798488670de0b6b3a764000061244f565b610d83828661347b565b1115610da2576040516375633b0560e11b815260040160405180910390fd5b50505050505050505f688000000000ab143c065d5050565b688000000000ab143c065c15610dd75763ab143c065f526004601cfd5b30688000000000ab143c065d82610df46060840160408501613271565b5f816001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e31573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e559190613435565b9050610e6381333086612463565b610e6e818385611e45565b604051632f4a61d960e01b8152600481018490523360248201526001600160a01b03831690632f4a61d9906044016020604051808303815f875af1158015610eb8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610edc9190613450565b50610ee78183611fcf565b6040516397a5d5b560e01b815233600482018190529085905f9081906001600160a01b037f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e216906397a5d5b5906024016060604051808303815f875af1158015610f53573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f7791906134a2565b92505091505f8183610f89919061347b565b9050610f9d610f978b6134d8565b336124b2565b6040516397a5d5b560e01b81526001600160a01b0386811660048301525f9182917f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e216906397a5d5b5906024016060604051808303815f875af1158015611006573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102a91906134a2565b92505091505f818361103c919061347b565b905080841115611082576110598488670de0b6b3a764000061244f565b611063828661347b565b1115611082576040516375633b0560e11b815260040160405180910390fd5b50505050505050505050505f688000000000ab143c065d505050565b604051634b0b3ab760e11b81526001600160a01b0382811660048301525f917f0000000000000000000000001310f352f1389969ece6741671c4b919523912ff90911690639616756e90602401602060405180830381865afa158015611106573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103a3919061341a565b688000000000ab143c065c156111475763ab143c065f526004601cfd5b30688000000000ab143c065d6040516397a5d5b560e01b815233600482018190529082905f9081906001600160a01b037f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e216906397a5d5b5906024016060604051808303815f875af11580156111bf573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111e391906134a2565b92505091505f81836111f5919061347b565b9050610cbd610f97886134d8565b336001600160a01b0383160361122c57604051636eef2f3f60e11b815260040160405180910390fd5b604051634b0b3ab760e11b81523360048201527f0000000000000000000000001310f352f1389969ece6741671c4b919523912ff6001600160a01b031690639616756e90602401602060405180830381865afa15801561128e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112b2919061341a565b156112d0576040516302d5da9f60e01b815260040160405180910390fd5b60405163e6248d5560e01b81523360048201525f907f0000000000000000000000001310f352f1389969ece6741671c4b919523912ff6001600160a01b03169063e6248d5590602401602060405180830381865afa158015611334573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113589190613450565b335f8181526020818152604080832085845282528083206001600160a01b03891680855290835292819020805460ff191688151590811790915581518681529283015293945090927ffeeb3502e62327bd3fece59983b972dc941e6abedd652971aac3adea23cf7e17910160405180910390a3505050565b60405163e6248d5560e01b81526001600160a01b0382811660048301525f917f0000000000000000000000001310f352f1389969ece6741671c4b919523912ff9091169063e6248d5590602401602060405180830381865afa158015611438573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103a39190613450565b60607f0000000000000000000000001310f352f1389969ece6741671c4b919523912ff82806001600160401b0381111561149857611498612dcb565b6040519080825280602002602001820160405280156114cb57816020015b60608152602001906001900390816114b65790505b5060408051606080820183525f80835260208301819052928201529194505b828110156116b4578686828181106115045761150461348e565b905060200281019061151691906134e3565b61151f90613501565b915081602001511561165657815160405163191d0cc560e11b81526001600160a01b0391821660048201525f9186169063323a198a90602401602060405180830381865afa158015611573573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115979190613435565b90506001600160a01b0381166115c057604051632f3285fb60e21b815260040160405180910390fd5b8251604080850151905163bd0226d760e01b81526001600160a01b0384169263bd0226d7926115f59233929190600401613586565b5f604051808303815f87803b15801561160c575f5ffd5b505af115801561161e573d5f5f3e3d5ffd5b50505050611633835f01518460400151612591565b8683815181106116455761164561348e565b6020026020010181905250506116ac565b81516001600160a01b0316301461168057604051637720ccd960e01b815260040160405180910390fd5b61168e308360400151612606565b8582815181106116a0576116a061348e565b60200260200101819052505b6001016114ea565b5050505092915050565b688000000000ab143c065c156116db5763ab143c065f526004601cfd5b30688000000000ab143c065d6040516397a5d5b560e01b81526001600160a01b038084166004830152839183915f9182917f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e216906397a5d5b5906024016060604051808303815f875af1158015611754573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061177891906134a2565b92505091505f818361178a919061347b565b9050611796873361265a565b6117a86117a2896134cd565b8861233f565b6040516397a5d5b560e01b81526001600160a01b0386811660048301525f9182917f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e216906397a5d5b5906024016060604051808303815f875af1158015611811573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061183591906134a2565b92505091505f8183611847919061347b565b90508084111561188d576118648488670de0b6b3a764000061244f565b61186e828661347b565b111561188d576040516375633b0560e11b815260040160405180910390fd5b50505050505050505f688000000000ab143c065d505050565b688000000000ab143c065c156118c35763ab143c065f526004601cfd5b30688000000000ab143c065d6040516397a5d5b560e01b81526001600160a01b038084166004830152839183915f9182917f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e216906397a5d5b5906024016060604051808303815f875af115801561193c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061196091906134a2565b92505091505f8183611972919061347b565b905061197e873361265a565b6117a861198a896134d8565b886124b2565b5f336001600160a01b038716141580611a2e5750604051637bca031760e11b81526001600160a01b0387811660048301527f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e2169063f794062e90602401602060405180830381865afa158015611a08573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a2c919061341a565b155b15611a4c5760405163792b839760e11b815260040160405180910390fd5b6040516370a0823160e01b815230600482015285906001600160a01b038416906370a0823190602401602060405180830381865afa158015611a90573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ab49190613450565b1015611ad3576040516307d198f760e11b815260040160405180910390fd5b836001600160a01b0316866001600160a01b0316141580611af45750828514155b15611b12576040516307c426b560e21b815260040160405180910390fd5b5f611b9f847f0000000000000000000000001310f352f1389969ece6741671c4b919523912ff6001600160a01b031663fe5764846040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b73573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b979190613450565b61271061273d565b90508015611c3d57611bb1818561347b565b9350611c3d837f0000000000000000000000001310f352f1389969ece6741671c4b919523912ff6001600160a01b0316632131c68c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c13573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c379190613435565b83611e62565b509195945050505050565b5f815f01516001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c88573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cac9190613435565b90505f82604001516001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611cef573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d139190613435565b9050611d1f8183612769565b15611d3d576040516307c426b560e21b815260040160405180910390fd5b826080015151600114611d63576040516307c426b560e21b815260040160405180910390fd5b5f83608001515f81518110611d7a57611d7a61348e565b602002602001015190508060a00151515f1480611da2575060608101516001600160a01b0316155b80611dc25750826001600160a01b0316815f01516001600160a01b031614155b80611de35750816001600160a01b031681604001516001600160a01b031614155b80611df657508360200151816020015114155b15611e14576040516307c426b560e21b815260040160405180910390fd5b611e3e7f0000000000000000000000001310f352f1389969ece6741671c4b919523912ff826127b9565b5050505050565b611e4e8361288d565b611e5d57611e5d8383836128c2565b505050565b816014528060345263a9059cbb60601b5f5260205f604460105f875af13d1560015f51141716611e99576390b8ec185f526004601cfd5b5f603452505050565b5f611eac8261288d565b611f1b576040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015611ef2573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f169190613450565b6103a3565b4792915050565b611f2b8361288d565b15611fc4577f0000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a6001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004015f604051808303818588803b158015611f89575f5ffd5b505af1158015611f9b573d5f5f3e3d5ffd5b50505050507f0000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a92505b611e5d838383611e62565b611fd88261288d565b61205e57604051636eb1769f60e11b81523060048201526001600160a01b0382811660248301525f919084169063dd62ed3e90604401602060405180830381865afa158015612029573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061204d9190613450565b111561205e5761205e82825f6128c2565b5050565b5f825f01516001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120a2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120c69190613435565b90507f0000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a6001600160a01b0316816001600160a01b031603612181576020830151604051632e1a7d4d60e01b815260048101919091527f0000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a6001600160a01b031690632e1a7d4d906024015f604051808303815f87803b158015612166575f5ffd5b505af1158015612178573d5f5f3e3d5ffd5b5050505061223a565b608083015160a08101515115806121a3575060608101516001600160a01b0316155b806121c35750816001600160a01b0316815f01516001600160a01b031614155b806121d657508360200151816020015114155b806121eb57506121e9816040015161288d565b155b15612209576040516307c426b560e21b815260040160405180910390fd5b6122337f0000000000000000000000001310f352f1389969ece6741671c4b919523912ff826127b9565b6020850152505b82602001515f0361225e576040516307d198f760e11b815260040160405180910390fd5b82604001516001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561229e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122c29190613435565b6020840151604051636e553f6560e01b8152600481018290523060248201526001600160a01b039290921691636e553f65919060440160206040518083038185885af1158015612314573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906123399190613450565b50505050565b8151604051637bca031760e11b81526001600160a01b0391821660048201527f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e29091169063f794062e90602401602060405180830381865afa1580156123a7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123cb919061341a565b6123e85760405163792b839760e11b815260040160405180910390fd5b8151602083015160405163bdca672360e01b81526001600160a01b039092169163bdca67239161241e9185908790600401613609565b5f604051808303815f87803b158015612435575f5ffd5b505af1158015612447573d5f5f3e3d5ffd5b505050505050565b5f61245b8484846128f9565b949350505050565b60405181606052826040528360601b602c526323b872dd60601b600c5260205f6064601c5f895af13d1560015f511417166124a557637939f4245f526004601cfd5b5f60605260405250505050565b8151604051637bca031760e11b81526001600160a01b0391821660048201527f000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e29091169063f794062e90602401602060405180830381865afa15801561251a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061253e919061341a565b61255b5760405163792b839760e11b815260040160405180910390fd5b8151602083015160405163010b626160e71b81526001600160a01b03909216916385b130809161241e91859087906004016136e6565b60605f5f846001600160a01b03165f856040516125ae919061376c565b5f6040518083038185875af1925050503d805f81146125e8576040519150601f19603f3d011682016040523d82523d5f602084013e6125ed565b606091505b50915091506125fd85838361291d565b95945050505050565b60605f5f846001600160a01b031684604051612622919061376c565b5f60405180830381855af49150503d805f81146125e8576040519150601f19603f3d011682016040523d82523d5f602084013e6125ed565b6001600160a01b038281165f81815260208190526040808220905163e6248d5560e01b815260048101939093529290917f0000000000000000000000001310f352f1389969ece6741671c4b919523912ff9091169063e6248d5590602401602060405180830381865afa1580156126d3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126f79190613450565b815260208082019290925260409081015f9081206001600160a01b038516825290925290205460ff1661205e576040516367ee2b0160e11b815260040160405180910390fd5b5f825f19048411830215820261275a5763ad251c275f526004601cfd5b50910281810615159190040190565b5f816001600160a01b0316836001600160a01b03160361278b575060016103a3565b6127948361288d565b80156127a457506127a48261288d565b156127b1575060016103a3565b505f92915050565b5f670de0b6b3a76400008260800151106127f75781608001516040516319b3b4a760e01b81526004016127ee91815260200190565b60405180910390fd5b6128018383612965565b90505f61280d84612b07565b90505f61282282855f01518660200151612b68565b90505f61283483866040015186612b68565b905081811115612846575050506103a3565b5f612863612854838561347b565b670de0b6b3a76400008561273d565b905085608001518111156116b4576040516319b3b4a760e01b8152600481018290526024016127ee565b5f6001600160a01b03821615806103a35750506001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b816014528060345263095ea7b360601b5f5260205f604460105f875af13d1560015f51141716611e9957633e3f8f735f526004601cfd5b5f825f1904841183021582026129165763ad251c275f526004601cfd5b5091020490565b60606129298383612ccb565b815115801561294057506001600160a01b0384163b155b1561295e576040516314859aeb60e21b815260040160405180910390fd5b5092915050565b604081015181515f91906129798183612769565b1561299757604051636991e51560e11b815260040160405180910390fd5b6060840151604051631d4686fd60e31b81526001600160a01b0391821660048201525f9187169063ea3437e890602401602060405180830381865afa1580156129e2573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a069190613435565b90506001600160a01b038116612a2f57604051637409771560e11b815260040160405180910390fd5b60405163383d5bf360e11b81526001600160a01b0382169063707ab7e690612a5d9088903090600401613782565b5f604051808303815f87803b158015612a74575f5ffd5b505af1158015612a86573d5f5f3e3d5ffd5b50505050612a9d8286606001518760200151611e45565b5f612aa784611ea2565b90505f612ab38461288d565b612abd575f612ac3565b86602001515b9050612ad887606001518860a0015183612cf9565b50612ae7848860600151611fcf565b81612af186611ea2565b612afb919061347b565b98975050505050505050565b5f816001600160a01b031663565d878c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b44573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103a39190613435565b5f6001600160a01b038316612b8f5773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92505b604051635ae6916360e01b81526001600160a01b03848116600483015260016024830181905260448301525f918291871690635ae69163906064016040805180830381865afa158015612be4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c0891906137ab565b915091505f8114612c37576040516383a1fb8b60e01b81526001600160a01b03861660048201526024016127ee565b612cc18285612c458861288d565b612cae57876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c85573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ca991906137cd565b612cb1565b60125b612cbc90600a6138d0565b6128f9565b9695505050505050565b8161205e5780515f03612cf1576040516314859aeb60e21b815260040160405180910390fd5b805181602001fd5b606081471015612d1c5760405163595909b560e11b815260040160405180910390fd5b5f5f856001600160a01b03168486604051612d37919061376c565b5f6040518083038185875af1925050503d805f8114612d71576040519150601f19603f3d011682016040523d82523d5f602084013e612d76565b606091505b5091509150612cc186838361291d565b5f60208284031215612d96575f5ffd5b81356001600160e01b031981168114612dad575f5ffd5b9392505050565b6001600160a01b0381168114612dc8575f5ffd5b50565b634e487b7160e01b5f52604160045260245ffd5b60405160c081016001600160401b0381118282101715612e0157612e01612dcb565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612e2f57612e2f612dcb565b604052919050565b8035612e4281612db4565b919050565b5f82601f830112612e56575f5ffd5b81356001600160401b03811115612e6f57612e6f612dcb565b612e82601f8201601f1916602001612e07565b818152846020838601011115612e96575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f60c08284031215612ec2575f5ffd5b612eca612ddf565b90508135612ed781612db4565b8152602082810135908201526040820135612ef181612db4565b60408201526060820135612f0481612db4565b60608201526080828101359082015260a08201356001600160401b03811115612f2b575f5ffd5b612f3784828501612e47565b60a08301525092915050565b5f82601f830112612f52575f5ffd5b81356001600160401b03811115612f6b57612f6b612dcb565b8060051b612f7b60208201612e07565b91825260208185018101929081019086841115612f96575f5ffd5b6020860192505b83831015612cc15782356001600160401b03811115612fba575f5ffd5b612fc9886020838a0101612eb2565b83525060209283019290910190612f9d565b5f60c08284031215612feb575f5ffd5b612ff3612ddf565b9050612ffe82612e37565b81526020828101359082015261301660408301612e37565b60408201526060828101359082015260808201356001600160401b0381111561303d575f5ffd5b61304984828501612f43565b60808301525060a08201356001600160401b03811115612f2b575f5ffd5b5f5f5f5f6080858703121561307a575f5ffd5b843561308581612db4565b935060208501359250604085013561309c81612db4565b915060608501356001600160401b038111156130b6575f5ffd5b6130c287828801612fdb565b91505092959194509250565b5f5f604083850312156130df575f5ffd5b82356130ea81612db4565b915060208301356130fa81612db4565b809150509250929050565b5f60c08284031215613115575f5ffd5b61311d612ddf565b905061312882612e37565b81526020828101359082015261314060408301612e37565b60408201526060828101359082015260808201356001600160401b03811115613167575f5ffd5b61304984828501612eb2565b5f5f5f5f60808587031215613186575f5ffd5b843561319181612db4565b93506020850135925060408501356131a881612db4565b915060608501356001600160401b038111156131c2575f5ffd5b6130c287828801613105565b5f60c082840312156131de575f5ffd5b50919050565b5f5f604083850312156131f5575f5ffd5b82356001600160401b0381111561320a575f5ffd5b613216858286016131ce565b95602094909401359450505050565b5f5f5f60608486031215613237575f5ffd5b8335925060208401356001600160401b03811115613253575f5ffd5b61325f868287016131ce565b93969395505050506040919091013590565b5f60208284031215613281575f5ffd5b8135612dad81612db4565b8015158114612dc8575f5ffd5b5f5f604083850312156132aa575f5ffd5b82356132b581612db4565b915060208301356130fa8161328c565b5f5f602083850312156132d6575f5ffd5b82356001600160401b038111156132eb575f5ffd5b8301601f810185136132fb575f5ffd5b80356001600160401b03811115613310575f5ffd5b8560208260051b8401011115613324575f5ffd5b6020919091019590945092505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156133b957603f198786030184526133a4858351613334565b94506020938401939190910190600101613388565b50929695505050505050565b5f5f5f606084860312156133d7575f5ffd5b83356001600160401b038111156133ec575f5ffd5b6133f8868287016131ce565b935050602084013561340981612db4565b929592945050506040919091013590565b5f6020828403121561342a575f5ffd5b8151612dad8161328c565b5f60208284031215613445575f5ffd5b8151612dad81612db4565b5f60208284031215613460575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156103a3576103a3613467565b634e487b7160e01b5f52603260045260245ffd5b5f5f5f606084860312156134b4575f5ffd5b5050815160208301516040909301519094929350919050565b5f6103a33683612fdb565b5f6103a33683613105565b5f8235605e198336030181126134f7575f5ffd5b9190910192915050565b5f60608236031215613511575f5ffd5b604051606081016001600160401b038111828210171561353357613533612dcb565b604052823561354181612db4565b815260208301356135518161328c565b602082015260408301356001600160401b0381111561356e575f5ffd5b61357a36828601612e47565b60408301525092915050565b6001600160a01b038481168252831660208201526060604082018190525f906125fd90830184613334565b80516001600160a01b03908116835260208083015190840152604080830151821690840152606080830151909116908301526080808201519083015260a08181015160c09184018290525f9161245b90850182613334565b83815260018060a01b0383166020820152606060408201525f610120820160018060a01b0384511660608401526020840151608084015260018060a01b0360408501511660a0840152606084015160c0840152608084015160c060e0850152818151808452610140860191506101408160051b87010193506020830192505f5b818110156136bb5761013f198786030183526136a68585516135b1565b94506020938401939290920191600101613689565b5050505060a0840151838203605f19016101008501526136db8282613334565b979650505050505050565b83815260018060a01b03831660208201526060604082015260018060a01b0382511660608201526020820151608082015260018060a01b0360408301511660a0820152606082015160c08201525f608083015160c060e084015261374e6101208401826135b1565b905060a0840151605f19848303016101008501526136db8282613334565b5f82518060208501845e5f920191825250919050565b604081525f61379460408301856135b1565b905060018060a01b03831660208301529392505050565b5f5f604083850312156137bc575f5ffd5b505080516020909101519092909150565b5f602082840312156137dd575f5ffd5b815160ff81168114612dad575f5ffd5b6001815b60018411156138285780850481111561380c5761380c613467565b600184161561381a57908102905b60019390931c9280026137f1565b935093915050565b5f8261383e575060016103a3565b8161384a57505f6103a3565b8160018114613860576002811461386a57613886565b60019150506103a3565b60ff84111561387b5761387b613467565b50506001821b6103a3565b5060208310610133831016604e8410600b84101617156138a9575081810a6103a3565b6138b55f1984846137ed565b805f19048211156138c8576138c8613467565b029392505050565b5f612dad60ff84168361383056fea264697066735822122069022c390b5c888ba0cc9a96eddc9c38967cf03a3ed114cae5a6286362eae57864736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001310f352f1389969ece6741671c4b919523912ff000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e20000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a
-----Decoded View---------------
Arg [0] : cr (address): 0x1310f352f1389969Ece6741671c4B919523912fF
Arg [1] : mm (address): 0xE1C24B2E93230FBe33d32Ba38ECA3218284143e2
Arg [2] : wNative (address): 0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000001310f352f1389969ece6741671c4b919523912ff
Arg [1] : 000000000000000000000000e1c24b2e93230fbe33d32ba38eca3218284143e2
Arg [2] : 0000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a
Deployed Bytecode Sourcemap
178125:3274:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;160451:236;;;;;;;;;;-1:-1:-1;160451:236:0;;;;;:::i;:::-;;:::i;:::-;;;470:14:1;;463:22;445:41;;433:2;418:18;160451:236:0;;;;;;;;139223:45;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;683:32:1;;;665:51;;653:2;638:18;139223:45:0;497:225:1;157202:3181:0;;;;;;;;;;-1:-1:-1;157202:3181:0;;;;;:::i;:::-;;:::i;:::-;;87447:223;;;;;;;;;;-1:-1:-1;87447:223:0;;;;;:::i;:::-;;:::i;153444:2215::-;;;;;;;;;;-1:-1:-1;153444:2215:0;;;;;:::i;:::-;;:::i;149863:244::-;;;;;;;;;;-1:-1:-1;149863:244:0;;;;;:::i;:::-;;:::i;144507:352::-;;;;;;;;;;-1:-1:-1;144507:352:0;;;;;:::i;:::-;;:::i;84089:49::-;;;;;;;;;;;;;;;88068:178;;;;;;;;;;-1:-1:-1;88068:178:0;;;;;:::i;:::-;;:::i;146123:236::-;;;;;;;;;;-1:-1:-1;146123:236:0;;;;;:::i;:::-;;:::i;85737:666::-;;;;;;;;;;-1:-1:-1;85737:666:0;;;;;:::i;:::-;;:::i;86785:163::-;;;;;;;;;;-1:-1:-1;86785:163:0;;;;;:::i;:::-;;:::i;:::-;;;10888:25:1;;;10876:2;10861:18;86785:163:0;10742:177:1;81497:1590:0;;;;;;;;;;-1:-1:-1;81497:1590:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;139106:38::-;;;;;;;;;;;;;;;151619:348;;;;;;;;;;-1:-1:-1;151619:348:0;;;;;:::i;:::-;;:::i;147939:340::-;;;;;;;;;;-1:-1:-1;147939:340:0;;;;;:::i;:::-;;:::i;160451:236::-;160544:11;-1:-1:-1;;;;;;160577:49:0;;-1:-1:-1;;;160577:49:0;;:102;;-1:-1:-1;;;;;;;;;;75629:40:0;;;160643:36;160568:111;160451:236;-1:-1:-1;;160451:236:0:o;157202:3181::-;157418:23;;;;;157459:49;;-1:-1:-1;;;157459:49:0;;-1:-1:-1;;;;;683:32:1;;;157459:49:0;;;665:51:1;157459:13:0;:22;;;;638:18:1;;157459:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;157454:125;;157532:35;;-1:-1:-1;;;157532:35:0;;;;;;;;;;;157454:125;157635:23;157669:6;-1:-1:-1;;;;;157661:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;157635:49;;157923:194;157964:6;157985:16;158024:6;:13;;;158053:6;:23;;;158091:15;157923:26;:194::i;:::-;157897:23;;;:220;158205:39;157897:6;158205:31;:39::i;:::-;158320:17;158340:16;-1:-1:-1;;;;;158340:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;158396:42;;-1:-1:-1;;;158396:42:0;;158432:4;158396:42;;;665:51:1;158320:44:0;;-1:-1:-1;158375:18:0;;-1:-1:-1;;;;;158396:27:0;;;;;638:18:1;;158396:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;158471:18;;;;158375:63;;-1:-1:-1;158449:19:0;158504:16;;;158500:204;;158650:42;;-1:-1:-1;;;158650:42:0;;-1:-1:-1;;;;;683:32:1;;;158650:42:0;;;665:51:1;158650:35:0;;;;;638:18:1;;158650:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;158636:56;;158500:204;158734:10;158720:11;:24;158716:117;;;158768:53;;-1:-1:-1;;;158768:53:0;;;;;;;;;;;158716:117;158843:17;158863:24;158876:11;158863:10;:24;:::i;:::-;158843:44;;158981:128;159023:9;159055:16;159087:11;158981:27;:128::i;:::-;159146:45;;-1:-1:-1;;;159146:45:0;;;;;15305:25:1;;;-1:-1:-1;;;;;15366:32:1;;;15346:18;;;15339:60;159146:25:0;;;;;15278:18:1;;159146:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;159283:1;159271:9;:13;159267:103;;;159301:57;159330:9;159341:5;159348:9;159301:28;:57::i;:::-;159394:48;;-1:-1:-1;;;159394:48:0;;159436:4;159394:48;;;665:51:1;-1:-1:-1;;;;;159394:33:0;;;;;638:18:1;;159394:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;159382:60;-1:-1:-1;159530:13:0;;159526:109;;159560:63;159589:15;159606:5;159613:9;159560:28;:63::i;:::-;159725:18;;;;:25;159765:12;;159761:453;;159799:9;159794:409;159814:8;159810:1;:12;159794:409;;;159881:55;159902:6;:18;;;159921:1;159902:21;;;;;;;;:::i;:::-;;;;;;;:33;;;159881:20;:55::i;:::-;159848:88;-1:-1:-1;159959:13:0;;159955:233;;159997:171;160044:6;:18;;;160063:1;160044:21;;;;;;;;:::i;:::-;;;;;;;:33;;;160104:5;160136:9;159997:20;:171::i;:::-;159824:3;;159794:409;;;;159761:453;160266:109;160315:9;160347:16;160266:34;:109::i;:::-;157370:3013;;;;;;;157202:3181;;;;:::o;87447:223::-;-1:-1:-1;;;;;87580:17:0;;;87547:11;87580:17;;;;;;;;;;;87598:53;;-1:-1:-1;;;87598:53:0;;;;;665:51:1;;;;87547:11:0;;87580:17;;87547:11;;87598:15;:47;;;;638:18:1;;87598:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;87580:72;;;;;;;;;;;;;;-1:-1:-1;87580:72:0;;;-1:-1:-1;;;;;87580:82:0;;;;;;;;;;;;;;;;87447:223;-1:-1:-1;;87447:223:0:o;153444:2215::-;153644:13;;;;;153825:39;;-1:-1:-1;;;153825:39:0;;-1:-1:-1;;;;;683:32:1;;;153825:39:0;;;665:51:1;153825:13:0;:22;;;;638:18:1;;153825:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;153820:115;;153888:35;;-1:-1:-1;;;153888:35:0;;;;;;;;;;;153820:115;153985:17;154023:16;-1:-1:-1;;;;;154005:41:0;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;153985:63;;154283:200;154324:16;154355:12;154390:6;:23;;;154429:6;:19;;;154463:9;154283:26;:200::i;:::-;154261:6;:19;;:222;;;;;154561:23;154587:6;-1:-1:-1;;;;;154587:12:0;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;154561:40;;154681:46;154713:6;154721:5;154681:31;:46::i;:::-;154757:48;;-1:-1:-1;;;154757:48:0;;154799:4;154757:48;;;665:51:1;154740:14:0;;-1:-1:-1;;;;;154757:33:0;;;;;638:18:1;;154757:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;154740:65;;154890:69;154918:15;154943:6;154952;154890:27;:69::i;:::-;155037:41;;-1:-1:-1;;;155037:41:0;;;;;15305:25:1;;;-1:-1:-1;;;;;15366:32:1;;;15346:18;;;15339:60;155020:14:0;;155037:26;;;;;;15278:18:1;;155037:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;155020:58;;155179:6;:21;;;155170:6;:30;155166:108;;;155224:38;;-1:-1:-1;;;155224:38:0;;;;;;;;;;;155166:108;155306:42;;-1:-1:-1;;;155306:42:0;;155342:4;155306:42;;;665:51:1;155286:17:0;;-1:-1:-1;;;;;155306:27:0;;;;;638:18:1;;155306:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;155286:62;-1:-1:-1;155432:13:0;;155428:103;;155462:57;155491:9;155502:5;155509:9;155462:28;:57::i;:::-;155583:68;155618:15;155643:6;155583:34;:68::i;:::-;153616:2043;;;;;;153444:2215;;;;:::o;149863:244::-;54996:22;54990:29;54987:146;;;55052:10;55046:4;55039:24;55113:4;55107;55100:18;54987:146;55178:9;55154:22;55147:41;141332:45:::1;::::0;-1:-1:-1;;;141332:45:0;;149996:10:::1;141332:45;::::0;::::1;665:51:1::0;;;149996:10:0;150008:8;;141282:24:::1;::::0;;;-1:-1:-1;;;;;141332:13:0::1;:36;::::0;::::1;::::0;638:18:1;;141332:45:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;141281:96;;;;;141388:15;141425:10;141406:16;:29;;;;:::i;:::-;141388:47:::0;-1:-1:-1;150068:31:0::2;;150080:6:::0;150068:31:::2;:::i;:::-;150088:10;150068:11;:31::i;:::-;141511:45:::1;::::0;-1:-1:-1;;;141511:45:0;;-1:-1:-1;;;;;683:32:1;;;141511:45:0::1;::::0;::::1;665:51:1::0;141463:23:0::1;::::0;;;141511:13:::1;:36;::::0;::::1;::::0;638:18:1;;141511:45:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;141462:94;;;;;141567:16;141604:9;141586:15;:27;;;;:::i;:::-;141567:46;;141716:8;141706:7;:18;141702:190;;;141768:31;141776:7;141785:8;636:4;141768:7;:31::i;:::-;141746:18;141756:8:::0;141746:7;:18:::1;:::i;:::-;141745:54;141741:140;;;141827:38;;-1:-1:-1::0;;;141827:38:0::1;;;;;;;;;;;141741:140;141270:629;;;;;;55209:1;;55320::::0;55296:22;55289:33;149863:244;;:::o;144507:352::-;54996:22;54990:29;54987:146;;;55052:10;55046:4;55039:24;55113:4;55107;55100:18;54987:146;55178:9;55154:22;55147:41;144678:6;144695:13:::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;139953:23;139979:6;-1:-1:-1::0;;;;;139979:12:0::1;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;139953:40;;140065:147;140112:15;140142:10;140175:4;140195:6;140065:32;:147::i;:::-;140274:69;140302:15;140327:6;140336;140274:27;:69::i;:::-;140432:46;::::0;-1:-1:-1;;;140432:46:0;;::::1;::::0;::::1;15305:25:1::0;;;140467:10:0::1;15346:18:1::0;;;15339:60;-1:-1:-1;;;;;140432:26:0;::::1;::::0;::::1;::::0;15278:18:1;;140432:46:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;140531:68;140566:15;140591:6;140531:34;:68::i;:::-;141332:45:::2;::::0;-1:-1:-1;;;141332:45:0;;144730:10:::2;141332:45;::::0;::::2;665:51:1::0;;;144730:10:0;144742:8;;141282:24:::2;::::0;;;-1:-1:-1;;;;;141332:13:0::2;:36;::::0;::::2;::::0;638:18:1;;141332:45:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;141281:96;;;;;141388:15;141425:10;141406:16;:29;;;;:::i;:::-;141388:47:::0;-1:-1:-1;144822:29:0::3;;144832:6:::0;144822:29:::3;:::i;:::-;144840:10;144822:9;:29::i;:::-;141511:45:::2;::::0;-1:-1:-1;;;141511:45:0;;-1:-1:-1;;;;;683:32:1;;;141511:45:0::2;::::0;::::2;665:51:1::0;141463:23:0::2;::::0;;;141511:13:::2;:36;::::0;::::2;::::0;638:18:1;;141511:45:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;141462:94;;;;;141567:16;141604:9;141586:15;:27;;;;:::i;:::-;141567:46;;141716:8;141706:7;:18;141702:190;;;141768:31;141776:7;141785:8;636:4;141768:7;:31::i;:::-;141746:18;141756:8:::0;141746:7;:18:::2;:::i;:::-;141745:54;141741:140;;;141827:38;;-1:-1:-1::0;;;141827:38:0::2;;;;;;;;;;;141741:140;141270:629;;;;;;140612:1;;139942:679:::1;55209:1;;55320::::0;55296:22;55289:33;144507:352;;;:::o;88068:178::-;88190:48;;-1:-1:-1;;;88190:48:0;;-1:-1:-1;;;;;683:32:1;;;88190:48:0;;;665:51:1;88157:11:0;;88190:15;:42;;;;;;638:18:1;;88190:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;146123:236::-;54996:22;54990:29;54987:146;;;55052:10;55046:4;55039:24;55113:4;55107;55100:18;54987:146;55178:9;55154:22;55147:41;141332:45:::1;::::0;-1:-1:-1;;;141332:45:0;;146252:10:::1;141332:45;::::0;::::1;665:51:1::0;;;146252:10:0;146264:8;;141282:24:::1;::::0;;;-1:-1:-1;;;;;141332:13:0::1;:36;::::0;::::1;::::0;638:18:1;;141332:45:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;141281:96;;;;;141388:15;141425:10;141406:16;:29;;;;:::i;:::-;141388:47:::0;-1:-1:-1;146322:29:0::2;;146332:6:::0;146322:29:::2;:::i;85737:666::-:0;85837:10;-1:-1:-1;;;;;85825:22:0;;;85821:96;;85871:34;;-1:-1:-1;;;85871:34:0;;;;;;;;;;;85821:96;86035:54;;-1:-1:-1;;;86035:54:0;;86078:10;86035:54;;;665:51:1;86035:15:0;-1:-1:-1;;;;;86035:42:0;;;;638:18:1;;86035:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;86031:131;;;86113:37;;-1:-1:-1;;;86113:37:0;;;;;;;;;;;86031:131;86197:45;;-1:-1:-1;;;86197:45:0;;86231:10;86197:45;;;665:51:1;86174:20:0;;86197:15;-1:-1:-1;;;;;86197:33:0;;;;638:18:1;;86197:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;86265:10;86253:11;:23;;;;;;;;;;;:37;;;;;;;;-1:-1:-1;;;;;86253:47:0;;;;;;;;;;;;:60;;-1:-1:-1;;86253:60:0;;;;;;;;;;86331:64;;16883:25:1;;;16924:18;;;16917:50;86253:37:0;;-1:-1:-1;86253:47:0;;86331:64;;16856:18:1;86331:64:0;;;;;;;85810:593;85737:666;;:::o;86785:163::-;86901:39;;-1:-1:-1;;;86901:39:0;;-1:-1:-1;;;;;683:32:1;;;86901:39:0;;;665:51:1;86865:14:0;;86901:15;:33;;;;;;638:18:1;;86901:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;81497:1590::-;81584:22;167966:15;81692:5;;-1:-1:-1;;;;;81725:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;81715:31:0;;-1:-1:-1;81803:1277:0;81823:8;81819:1;:12;81803:1277;;;81866:5;;81872:1;81866:8;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;81853:21;;;:::i;:::-;;;81907:10;:24;;;81903:810;;;82135:17;;82115:38;;-1:-1:-1;;;82115:38:0;;-1:-1:-1;;;;;683:32:1;;;82115:38:0;;;665:51:1;82097:15:0;;82115:19;;;;;638:18:1;;82115:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;82097:56;-1:-1:-1;;;;;;82244:21:0;;82240:105;;82297:28;;-1:-1:-1;;;82297:28:0;;;;;;;;;;;82240:105;82461:17;;82501:15;;;;;82365:170;;-1:-1:-1;;;82365:170:0;;-1:-1:-1;;;;;82365:40:0;;;;;:170;;82428:10;;82461:17;82501:15;82365:170;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82569:83;82617:10;:17;;;82636:10;:15;;;82569:47;:83::i;:::-;82556:7;82564:1;82556:10;;;;;;;;:::i;:::-;;;;;;:96;;;;82689:8;;;81903:810;82869:17;;-1:-1:-1;;;;;82852:34:0;82860:4;82852:34;82848:108;;82914:26;;-1:-1:-1;;;82914:26:0;;;;;;;;;;;82848:108;82985:83;83045:4;83052:10;:15;;;82985:51;:83::i;:::-;82972:7;82980:1;82972:10;;;;;;;;:::i;:::-;;;;;;:96;;;;81803:1277;81833:3;;81803:1277;;;;81608:1479;;;81497:1590;;;;:::o;151619:348::-;54996:22;54990:29;54987:146;;;55052:10;55046:4;55039:24;55113:4;55107;55100:18;54987:146;55178:9;55154:22;55147:41;141332:45:::1;::::0;-1:-1:-1;;;141332:45:0;;-1:-1:-1;;;;;683:32:1;;;141332:45:0::1;::::0;::::1;665:51:1::0;151781:7:0;;151790:8;;141282:24:::1;::::0;;;141332:13:::1;:36;::::0;::::1;::::0;638:18:1;;141332:45:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;141281:96;;;;;141388:15;141425:10;141406:16;:29;;;;:::i;:::-;141388:47;;151811:35:::2;151826:7;151835:10;151811:14;:35::i;:::-;151931:28;;151943:6:::0;151931:28:::2;:::i;:::-;151951:7;151931:11;:28::i;:::-;141511:45:::1;::::0;-1:-1:-1;;;141511:45:0;;-1:-1:-1;;;;;683:32:1;;;141511:45:0::1;::::0;::::1;665:51:1::0;141463:23:0::1;::::0;;;141511:13:::1;:36;::::0;::::1;::::0;638:18:1;;141511:45:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;141462:94;;;;;141567:16;141604:9;141586:15;:27;;;;:::i;:::-;141567:46;;141716:8;141706:7;:18;141702:190;;;141768:31;141776:7;141785:8;636:4;141768:7;:31::i;:::-;141746:18;141756:8:::0;141746:7;:18:::1;:::i;:::-;141745:54;141741:140;;;141827:38;;-1:-1:-1::0;;;141827:38:0::1;;;;;;;;;;;141741:140;141270:629;;;;;;55209:1;;55320::::0;55296:22;55289:33;151619:348;;;:::o;147939:340::-;54996:22;54990:29;54987:146;;;55052:10;55046:4;55039:24;55113:4;55107;55100:18;54987:146;55178:9;55154:22;55147:41;141332:45:::1;::::0;-1:-1:-1;;;141332:45:0;;-1:-1:-1;;;;;683:32:1;;;141332:45:0::1;::::0;::::1;665:51:1::0;148097:7:0;;148106:8;;141282:24:::1;::::0;;;141332:13:::1;:36;::::0;::::1;::::0;638:18:1;;141332:45:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;141281:96;;;;;141388:15;141425:10;141406:16;:29;;;;:::i;:::-;141388:47;;148127:35:::2;148142:7;148151:10;148127:14;:35::i;:::-;148245:26;;148255:6:::0;148245:26:::2;:::i;:::-;148263:7;148245:9;:26::i;161668:1608::-:0;161875:7;162036:10;-1:-1:-1;;;;;162036:20:0;;;;;:55;;-1:-1:-1;162061:30:0;;-1:-1:-1;;;162061:30:0;;-1:-1:-1;;;;;683:32:1;;;162061:30:0;;;665:51:1;162061:13:0;:22;;;;638:18:1;;162061:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;162060:31;162036:55;162032:130;;;162115:35;;-1:-1:-1;;;162115:35:0;;;;;;;;;;;162032:130;162277:49;;-1:-1:-1;;;162277:49:0;;162320:4;162277:49;;;665:51:1;162329:6:0;;-1:-1:-1;;;;;162277:34:0;;;;;638:18:1;;162277:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:58;162273:134;;;162359:36;;-1:-1:-1;;;162359:36:0;;;;;;;;;;;162273:134;162508:11;-1:-1:-1;;;;;162490:30:0;:6;-1:-1:-1;;;;;162490:30:0;;;:56;;;;162534:12;162524:6;:22;;162490:56;162486:131;;;162570:35;;-1:-1:-1;;;162570:35:0;;;;;;;;;;;162486:131;162699:11;162713:134;162754:12;162781:15;-1:-1:-1;;;;;162781:35:0;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;745:3;162713:26;:134::i;:::-;162699:148;-1:-1:-1;162913:7:0;;162909:221;;162937:19;162953:3;162937:19;;:::i;:::-;;;162971:147;163018:16;163053:15;-1:-1:-1;;;;;163053:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;163100:3;162971:28;:147::i;:::-;-1:-1:-1;163256:12:0;;161668:1608;-1:-1:-1;;;;;161668:1608:0:o;174905:1337::-;175031:23;175057:6;:13;;;-1:-1:-1;;;;;175057:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;175031:47;;175089:17;175109:6;:23;;;-1:-1:-1;;;;;175109:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;175089:51;;175348:54;175375:9;175386:15;175348:26;:54::i;:::-;175344:129;;;175426:35;;-1:-1:-1;;;175426:35:0;;;;;;;;;;;175344:129;175556:6;:18;;;:25;175585:1;175556:30;175552:105;;175610:35;;-1:-1:-1;;;175610:35:0;;;;;;;;;;;175552:105;175707:33;175743:6;:18;;;175762:1;175743:21;;;;;;;;:::i;:::-;;;;;;;175707:57;;175793:10;:15;;;:22;175819:1;175793:27;:75;;;-1:-1:-1;175837:17:0;;;;-1:-1:-1;;;;;175837:31:0;;175793:75;:132;;;;175910:15;-1:-1:-1;;;;;175885:40:0;:10;:21;;;-1:-1:-1;;;;;175885:40:0;;;175793:132;:184;;;;175968:9;-1:-1:-1;;;;;175942:35:0;:10;:22;;;-1:-1:-1;;;;;175942:35:0;;;175793:184;:250;;;;176020:6;:23;;;175994:10;:22;;;:49;;175793:250;175775:349;;;176077:35;;-1:-1:-1;;;176077:35:0;;;;;;;;;;;175775:349;176185:49;176206:15;176223:10;176185:20;:49::i;:::-;;175020:1222;;;174905:1337;:::o;136412:246::-;136545:26;136565:5;136545:19;:26::i;:::-;136540:111;;136588:51;136616:5;136623:7;136632:6;136588:27;:51::i;:::-;136412:246;;;:::o;68152:957::-;68318:2;68312:4;68305:16;68376:6;68370:4;68363:20;-1:-1:-1;;;68436:4:0;68429:48;68836:4;68830;68824;68818;68815:1;68808:5;68801;68796:45;68729:16;68722:24;68718:1;68711:4;68705:11;68702:18;68699:48;68613:247;68585:408;;68908:10;68902:4;68895:24;68973:4;68967;68960:18;68585:408;69020:1;69014:4;69007:15;68152:957;;;:::o;90287:186::-;90345:9;90371:16;90381:5;90371:9;:16::i;:::-;:94;;90427:38;;-1:-1:-1;;;90427:38:0;;90459:4;90427:38;;;665:51:1;-1:-1:-1;;;;;90427:23:0;;;;;638:18:1;;90427:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90371:94;;;90390:21;90367:98;90287:186;-1:-1:-1;;90287:186:0:o;166912:553::-;167190:26;167210:5;167190:19;:26::i;:::-;167186:142;;;167239:13;-1:-1:-1;;;;;167233:28:0;;167270:6;167233:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;167303:13;167295:21;;167186:142;167403:54;167432:5;167439:9;167450:6;167403:28;:54::i;136835:289::-;136925:26;136945:5;136925:19;:26::i;:::-;136920:197;;136972:47;;-1:-1:-1;;;136972:47:0;;137004:4;136972:47;;;18812:51:1;-1:-1:-1;;;;;18899:32:1;;;18879:18;;;18872:60;137022:1:0;;136972:23;;;;;;18785:18:1;;136972:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:51;136968:138;;;137044:46;137072:5;137079:7;137088:1;137044:27;:46::i;:::-;136835:289;;:::o;179963:1431::-;180112:17;180132:6;:23;;;-1:-1:-1;;;;;180132:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;180112:51;;180193:13;-1:-1:-1;;;;;180180:26:0;:9;-1:-1:-1;;;;;180180:26:0;;180176:846;;180294:19;;;;180264:50;;-1:-1:-1;;;180264:50:0;;;;;10888:25:1;;;;180270:13:0;-1:-1:-1;;;;;180264:29:0;;;;10861:18:1;;180264:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;180176:846;;;180383:17;;;;180470:15;;;;:22;:27;;:79;;-1:-1:-1;180518:17:0;;;;-1:-1:-1;;;;;180518:31:0;;180470:79;:134;;;;180595:9;-1:-1:-1;;;;;180570:34:0;:10;:21;;;-1:-1:-1;;;;;180570:34:0;;;180470:134;:200;;;;180651:6;:19;;;180625:10;:22;;;:45;;180470:200;:265;;;;180692:43;180712:10;:22;;;180692:19;:43::i;:::-;180691:44;180470:265;180448:380;;;180777:35;;-1:-1:-1;;;180777:35:0;;;;;;;;;;;180448:380;180961:49;180982:15;180999:10;180961:20;:49::i;:::-;180922:19;;;:88;-1:-1:-1;180176:846:0;181101:6;:19;;;181124:1;181101:24;181097:100;;181149:36;;-1:-1:-1;;;181149:36:0;;;;;;;;;;;181097:100;181278:6;:13;;;-1:-1:-1;;;;;181278:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;181316:19;;;;181271:115;;-1:-1:-1;;;181271:115:0;;;;;15305:25:1;;;181380:4:0;15346:18:1;;;15339:60;-1:-1:-1;;;;;181271:37:0;;;;;;;181316:19;15278:18:1;;181271:115:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;180101:1293;179963:1431;;:::o;166099:452::-;166314:13;;166283:46;;-1:-1:-1;;;166283:46:0;;-1:-1:-1;;;;;683:32:1;;;166283:46:0;;;665:51:1;166283:13:0;:22;;;;;;638:18:1;;166283:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;166278:122;;166353:35;;-1:-1:-1;;;166353:35:0;;;;;;;;;;;166278:122;166412:13;;166466:23;;;;166412:131;;-1:-1:-1;;;166412:131:0;;-1:-1:-1;;;;;166412:39:0;;;;;;:131;;166504:7;;166412:6;;:131;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;166099:452;;:::o;167570:174::-;167677:9;167703:33;167728:1;167731;167734;167703:24;:33::i;:::-;167699:37;167570:174;-1:-1:-1;;;;167570:174:0:o;64891:1160::-;65077:4;65071:11;65143:6;65137:4;65130:20;65209:2;65203:4;65196:16;65275:4;65271:2;65267:13;65261:4;65254:27;-1:-1:-1;;;65332:4:0;65325:48;65744:4;65738;65732;65726;65723:1;65716:5;65709;65704:45;65637:16;65630:24;65626:1;65619:4;65613:11;65610:18;65607:48;65521:247;65493:412;;65816:10;65810:4;65803:24;65885:4;65879;65872:18;65493:412;65932:1;65926:4;65919:15;65989:4;65982:15;-1:-1:-1;;;;64891:1160:0:o;164388:473::-;164609:23;;164578:56;;-1:-1:-1;;;164578:56:0;;-1:-1:-1;;;;;683:32:1;;;164578:56:0;;;665:51:1;164578:13:0;:22;;;;;;638:18:1;;164578:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;164573:132;;164658:35;;-1:-1:-1;;;164658:35:0;;;;;;;;;;;164573:132;164717:23;;164780:19;;;;164717:136;;-1:-1:-1;;;164717:136:0;;-1:-1:-1;;;;;164717:48:0;;;;;;:136;;164814:7;;164717:6;;:136;;;:::i;49206:265::-;49299:12;49325;49339:23;49366:6;-1:-1:-1;;;;;49366:11:0;49385:1;49388:4;49366:27;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49324:69;;;;49421:42;49435:6;49443:7;49452:10;49421:13;:42::i;:::-;49414:49;49206:265;-1:-1:-1;;;;;49206:265:0:o;51086:263::-;51187:12;51213;51227:23;51254:6;-1:-1:-1;;;;;51254:19:0;51274:4;51254:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88610:270;-1:-1:-1;;;;;88710:17:0;;;:11;:17;;;;;;;;;;;88728:57;;-1:-1:-1;;;88728:57:0;;;;;665:51:1;;;;88710:17:0;:11;;88728:15;:51;;;;;;638:18:1;;88728:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88710:76;;;;;;;;;;;;;;-1:-1:-1;88710:76:0;;;-1:-1:-1;;;;;88710:86:0;;;;;;;;;;;;88691:182;;88830:31;;-1:-1:-1;;;88830:31:0;;;;;;;;;;;8475:518;8549:9;8776:1;8772;8768:6;8764:14;8761:1;8758:21;8755:1;8751:29;8744:37;8741:1;8737:45;8727:172;;8816:10;8810:4;8803:24;8879:4;8873;8866:18;8727:172;-1:-1:-1;8961:9:0;;8936:17;;;8929:25;8922:33;8957:17;;;8918:57;;8475:518::o;89338:309::-;89444:4;89475:6;-1:-1:-1;;;;;89465:16:0;:6;-1:-1:-1;;;;;89465:16:0;;89461:60;;-1:-1:-1;89505:4:0;89498:11;;89461:60;89537:17;89547:6;89537:9;:17::i;:::-;:38;;;;;89558:17;89568:6;89558:9;:17::i;:::-;89533:82;;;-1:-1:-1;89599:4:0;89592:11;;89533:82;-1:-1:-1;89634:5:0;89338:309;;;;:::o;134189:939::-;134292:17;636:4;134326:6;:15;;;:22;134322:99;;134393:6;:15;;;134372:37;;-1:-1:-1;;;134372:37:0;;;;;;10888:25:1;;10876:2;10861:18;;10742:177;134372:37:0;;;;;;;;134322:99;134445:23;134457:2;134461:6;134445:11;:23::i;:::-;134433:35;;134481:17;134501:28;134526:2;134501:24;:28::i;:::-;134481:48;;134540:15;134558:52;134568:2;134572:6;:17;;;134591:6;:18;;;134558:9;:52::i;:::-;134540:70;;134621:16;134640:44;134650:2;134654:6;:18;;;134674:9;134640;:44::i;:::-;134621:63;;134766:7;134755:8;:18;134751:67;;;134790:16;;;;;134751:67;134883:16;134902:110;134943:18;134953:8;134943:7;:18;:::i;:::-;636:4;134994:7;134902:26;:110::i;:::-;134883:129;;135040:6;:15;;;135029:8;:26;135025:96;;;135079:30;;-1:-1:-1;;;135079:30:0;;;;;10888:25:1;;;10861:18;;135079:30:0;10742:177:1;89906:185:0;89963:11;-1:-1:-1;;;;;89996:19:0;;;;:87;;-1:-1:-1;;;;;;;90032:51:0;90041:42;90032:51;;89906:185::o;71004:954::-;71169:2;71163:4;71156:16;71227:6;71221:4;71214:20;-1:-1:-1;;;71287:4:0;71280:48;71686:4;71680;71674;71668;71665:1;71658:5;71651;71646:45;71579:16;71572:24;71568:1;71561:4;71555:11;71552:18;71549:48;71463:247;71435:407;;71758:10;71752:4;71745:24;71822:4;71816;71809:18;7895:476;7967:9;8194:1;8190;8186:6;8182:14;8179:1;8176:21;8173:1;8169:29;8162:37;8159:1;8155:45;8145:172;;8234:10;8228:4;8221:24;8297:4;8291;8284:18;8145:172;-1:-1:-1;8340:9:0;;8336:17;;7895:476::o;51563:513::-;51698:12;51723:36;51739:7;51748:10;51723:15;:36::i;:::-;51921:17;;:22;:49;;;;-1:-1:-1;;;;;;51947:18:0;;;:23;51921:49;51917:122;;;51994:33;;-1:-1:-1;;;51994:33:0;;;;;;;;;;;51917:122;-1:-1:-1;52058:10:0;51563:513;-1:-1:-1;;51563:513:0:o;131734:1555::-;131891:18;;;;131941:17;;131839;;131891:18;132039:51;131941:17;131891:18;132039:26;:51::i;:::-;132035:115;;;132114:24;;-1:-1:-1;;;132114:24:0;;;;;;;;;;;132035:115;132215:13;;;;132188:41;;-1:-1:-1;;;132188:41:0;;-1:-1:-1;;;;;683:32:1;;;132188:41:0;;;665:51:1;132162:23:0;;132188:26;;;;;638:18:1;;132188:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;132162:67;-1:-1:-1;;;;;;132304:29:0;;132300:98;;132357:29;;-1:-1:-1;;;132357:29:0;;;;;;;;;;;132300:98;132449:92;;-1:-1:-1;;;132449:92:0;;-1:-1:-1;;;;;132449:69:0;;;;;:92;;132519:6;;132535:4;;132449:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;132628:63;132645:10;132657:6;:13;;;132672:6;:18;;;132628:16;:63::i;:::-;132778:21;132802:33;132823:11;132802:20;:33::i;:::-;132778:57;;132848:17;132868:31;132888:10;132868:19;:31::i;:::-;:69;;132936:1;132868:69;;;132915:6;:18;;;132868:69;132848:89;;132980:124;133030:6;:13;;;133058:6;:11;;;133084:9;132980:35;:124::i;:::-;;133157:50;133181:10;133193:6;:13;;;133157:23;:50::i;:::-;133268:13;133232:33;133253:11;133232:20;:33::i;:::-;:49;;;;:::i;:::-;133220:61;131734:1555;-1:-1:-1;;;;;;;;131734:1555:0:o;90688:183::-;90772:28;90844:2;-1:-1:-1;;;;;90844:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;135453:745::-;135579:14;-1:-1:-1;;;;;135724:19:0;;135720:66;;130607:42;135760:14;;135720:66;135843:30;;-1:-1:-1;;;135843:30:0;;-1:-1:-1;;;;;22892:32:1;;;135843:30:0;;;22874:51:1;135862:4:0;22941:18:1;;;22934:50;;;23000:18;;;22993:50;135807:13:0;;;;135843:11;;;;;22847:18:1;;135843:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;135806:67;;;;1036:1;135888:9;:21;135884:90;;135933:29;;-1:-1:-1;;;135933:29:0;;-1:-1:-1;;;;;683:32:1;;135933:29:0;;;665:51:1;638:18;;135933:29:0;497:225:1;135884:90:0;136033:157;136072:5;136092:6;136120:26;136140:5;136120:19;:26::i;:::-;:58;;136161:5;-1:-1:-1;;;;;136154:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;136120:58;;;136149:2;136120:58;136113:66;;:2;:66;:::i;:::-;136033:24;:157::i;:::-;136024:166;135453:745;-1:-1:-1;;;;;;135453:745:0:o;52252:425::-;52371:7;52366:304;;52399:10;:17;52420:1;52399:22;52395:103;;52449:33;;-1:-1:-1;;;52449:33:0;;;;;;;;;;;52395:103;52632:10;52626:17;52613:10;52609:2;52605:19;52598:46;50104:442;50231:12;50284:5;50260:21;:29;50256:111;;;50313:42;;-1:-1:-1;;;50313:42:0;;;;;;;;;;;50256:111;50380:12;50394:23;50421:6;-1:-1:-1;;;;;50421:11:0;50454:5;50471:4;50421:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50379:97;;;;50496:42;50510:6;50518:7;50527:10;50496:13;:42::i;14:286:1:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:1;;209:43;;199:71;;266:1;263;256:12;199:71;289:5;14:286;-1:-1:-1;;;14:286:1:o;727:131::-;-1:-1:-1;;;;;802:31:1;;792:42;;782:70;;848:1;845;838:12;782:70;727:131;:::o;863:127::-;924:10;919:3;915:20;912:1;905:31;955:4;952:1;945:15;979:4;976:1;969:15;995:253;1067:2;1061:9;1109:4;1097:17;;-1:-1:-1;;;;;1129:34:1;;1165:22;;;1126:62;1123:88;;;1191:18;;:::i;:::-;1227:2;1220:22;995:253;:::o;1253:275::-;1324:2;1318:9;1389:2;1370:13;;-1:-1:-1;;1366:27:1;1354:40;;-1:-1:-1;;;;;1409:34:1;;1445:22;;;1406:62;1403:88;;;1471:18;;:::i;:::-;1507:2;1500:22;1253:275;;-1:-1:-1;1253:275:1:o;1533:143::-;1610:20;;1639:31;1610:20;1639:31;:::i;:::-;1533:143;;;:::o;1681:558::-;1723:5;1776:3;1769:4;1761:6;1757:17;1753:27;1743:55;;1794:1;1791;1784:12;1743:55;1834:6;1821:20;-1:-1:-1;;;;;1856:6:1;1853:30;1850:56;;;1886:18;;:::i;:::-;1930:59;1977:2;1954:17;;-1:-1:-1;;1950:31:1;1983:4;1946:42;1930:59;:::i;:::-;2014:6;2005:7;1998:23;2068:3;2061:4;2052:6;2044;2040:19;2036:30;2033:39;2030:59;;;2085:1;2082;2075:12;2030:59;2150:6;2143:4;2135:6;2131:17;2124:4;2115:7;2111:18;2098:59;2206:1;2177:20;;;2199:4;2173:31;2166:42;;;;2181:7;1681:558;-1:-1:-1;;;1681:558:1:o;2244:993::-;2295:5;2343:4;2331:9;2326:3;2322:19;2318:30;2315:50;;;2361:1;2358;2351:12;2315:50;2383:22;;:::i;:::-;2374:31;;2442:9;2429:23;2461:33;2486:7;2461:33;:::i;:::-;2503:22;;2598:2;2583:18;;;2570:32;2618:14;;;2611:31;2694:2;2679:18;;2666:32;2707:33;2666:32;2707:33;:::i;:::-;2767:2;2756:14;;2749:31;2832:2;2817:18;;2804:32;2845:33;2804:32;2845:33;:::i;:::-;2905:2;2894:14;;2887:31;2991:3;2976:19;;;2963:33;3012:15;;;3005:32;3088:3;3073:19;;3060:33;-1:-1:-1;;;;;3105:30:1;;3102:50;;;3148:1;3145;3138:12;3102:50;3185:45;3226:3;3217:6;3206:9;3202:22;3185:45;:::i;:::-;3179:3;3172:5;3168:15;3161:70;;2244:993;;;;:::o;3242:889::-;3300:5;3353:3;3346:4;3338:6;3334:17;3330:27;3320:55;;3371:1;3368;3361:12;3320:55;3411:6;3398:20;-1:-1:-1;;;;;3433:6:1;3430:30;3427:56;;;3463:18;;:::i;:::-;3509:6;3506:1;3502:14;3536:30;3560:4;3556:2;3552:13;3536:30;:::i;:::-;3602:19;;;3646:4;3678:15;;;3674:26;;;3637:14;;;;3712:15;;;3709:35;;;3740:1;3737;3730:12;3709:35;3776:4;3768:6;3764:17;3753:28;;3790:310;3806:6;3801:3;3798:15;3790:310;;;3894:3;3881:17;-1:-1:-1;;;;;3917:11:1;3914:35;3911:55;;;3962:1;3959;3952:12;3911:55;3991:64;4051:3;4044:4;4030:11;4022:6;4018:24;4014:35;3991:64;:::i;:::-;3979:77;;-1:-1:-1;4085:4:1;3823:14;;;;4076;;;;3790:310;;4136:965;4199:5;4247:4;4235:9;4230:3;4226:19;4222:30;4219:50;;;4265:1;4262;4255:12;4219:50;4287:22;;:::i;:::-;4278:31;;4332:38;4360:9;4332:38;:::i;:::-;4318:53;;4444:2;4429:18;;;4416:32;4464:14;;;4457:31;4520:47;4563:2;4548:18;;4520:47;:::i;:::-;4515:2;4504:14;;4497:71;4641:2;4626:18;;;4613:32;4661:14;;;4654:31;4736:3;4721:19;;4708:33;-1:-1:-1;;;;;4753:30:1;;4750:50;;;4796:1;4793;4786:12;4750:50;4833:61;4890:3;4881:6;4870:9;4866:22;4833:61;:::i;:::-;4827:3;4820:5;4816:15;4809:86;;4948:3;4937:9;4933:19;4920:33;-1:-1:-1;;;;;4968:8:1;4965:32;4962:52;;;5010:1;5007;5000:12;5106:760;5226:6;5234;5242;5250;5303:3;5291:9;5282:7;5278:23;5274:33;5271:53;;;5320:1;5317;5310:12;5271:53;5359:9;5346:23;5378:31;5403:5;5378:31;:::i;:::-;5428:5;-1:-1:-1;5506:2:1;5491:18;;5478:32;;-1:-1:-1;5588:2:1;5573:18;;5560:32;5601:33;5560:32;5601:33;:::i;:::-;5653:7;-1:-1:-1;5711:2:1;5696:18;;5683:32;-1:-1:-1;;;;;5727:30:1;;5724:50;;;5770:1;5767;5760:12;5724:50;5793:67;5852:7;5843:6;5832:9;5828:22;5793:67;:::i;:::-;5783:77;;;5106:760;;;;;;;:::o;5871:388::-;5939:6;5947;6000:2;5988:9;5979:7;5975:23;5971:32;5968:52;;;6016:1;6013;6006:12;5968:52;6055:9;6042:23;6074:31;6099:5;6074:31;:::i;:::-;6124:5;-1:-1:-1;6181:2:1;6166:18;;6153:32;6194:33;6153:32;6194:33;:::i;:::-;6246:7;6236:17;;;5871:388;;;;;:::o;6264:953::-;6325:5;6373:4;6361:9;6356:3;6352:19;6348:30;6345:50;;;6391:1;6388;6381:12;6345:50;6413:22;;:::i;:::-;6404:31;;6458:38;6486:9;6458:38;:::i;:::-;6444:53;;6570:2;6555:18;;;6542:32;6590:14;;;6583:31;6646:47;6689:2;6674:18;;6646:47;:::i;:::-;6641:2;6630:14;;6623:71;6767:2;6752:18;;;6739:32;6787:14;;;6780:31;6862:3;6847:19;;6834:33;-1:-1:-1;;;;;6879:30:1;;6876:50;;;6922:1;6919;6912:12;6876:50;6959:51;7006:3;6997:6;6986:9;6982:22;6959:51;:::i;7222:756::-;7340:6;7348;7356;7364;7417:3;7405:9;7396:7;7392:23;7388:33;7385:53;;;7434:1;7431;7424:12;7385:53;7473:9;7460:23;7492:31;7517:5;7492:31;:::i;:::-;7542:5;-1:-1:-1;7620:2:1;7605:18;;7592:32;;-1:-1:-1;7702:2:1;7687:18;;7674:32;7715:33;7674:32;7715:33;:::i;:::-;7767:7;-1:-1:-1;7825:2:1;7810:18;;7797:32;-1:-1:-1;;;;;7841:30:1;;7838:50;;;7884:1;7881;7874:12;7838:50;7907:65;7964:7;7955:6;7944:9;7940:22;7907:65;:::i;7983:165::-;8052:5;8097:3;8088:6;8083:3;8079:16;8075:26;8072:46;;;8114:1;8111;8104:12;8072:46;-1:-1:-1;8136:6:1;7983:165;-1:-1:-1;7983:165:1:o;8153:488::-;8257:6;8265;8318:2;8306:9;8297:7;8293:23;8289:32;8286:52;;;8334:1;8331;8324:12;8286:52;8374:9;8361:23;-1:-1:-1;;;;;8399:6:1;8396:30;8393:50;;;8439:1;8436;8429:12;8393:50;8462:76;8530:7;8521:6;8510:9;8506:22;8462:76;:::i;:::-;8452:86;8607:2;8592:18;;;;8579:32;;-1:-1:-1;;;;8153:488:1:o;8646:606::-;8757:6;8765;8773;8826:2;8814:9;8805:7;8801:23;8797:32;8794:52;;;8842:1;8839;8832:12;8794:52;8887:23;;;-1:-1:-1;8985:2:1;8970:18;;8957:32;-1:-1:-1;;;;;9001:30:1;;8998:50;;;9044:1;9041;9034:12;8998:50;9067:76;9135:7;9126:6;9115:9;9111:22;9067:76;:::i;:::-;8646:606;;9057:86;;-1:-1:-1;;;;9216:2:1;9201:18;;;;9188:32;;8646:606::o;9489:247::-;9548:6;9601:2;9589:9;9580:7;9576:23;9572:32;9569:52;;;9617:1;9614;9607:12;9569:52;9656:9;9643:23;9675:31;9700:5;9675:31;:::i;10232:118::-;10318:5;10311:13;10304:21;10297:5;10294:32;10284:60;;10340:1;10337;10330:12;10355:382;10420:6;10428;10481:2;10469:9;10460:7;10456:23;10452:32;10449:52;;;10497:1;10494;10487:12;10449:52;10536:9;10523:23;10555:31;10580:5;10555:31;:::i;:::-;10605:5;-1:-1:-1;10662:2:1;10647:18;;10634:32;10675:30;10634:32;10675:30;:::i;10924:645::-;11045:6;11053;11106:2;11094:9;11085:7;11081:23;11077:32;11074:52;;;11122:1;11119;11112:12;11074:52;11162:9;11149:23;-1:-1:-1;;;;;11187:6:1;11184:30;11181:50;;;11227:1;11224;11217:12;11181:50;11250:22;;11303:4;11295:13;;11291:27;-1:-1:-1;11281:55:1;;11332:1;11329;11322:12;11281:55;11372:2;11359:16;-1:-1:-1;;;;;11390:6:1;11387:30;11384:50;;;11430:1;11427;11420:12;11384:50;11483:7;11478:2;11468:6;11465:1;11461:14;11457:2;11453:23;11449:32;11446:45;11443:65;;;11504:1;11501;11494:12;11443:65;11535:2;11527:11;;;;;11557:6;;-1:-1:-1;10924:645:1;-1:-1:-1;;;10924:645:1:o;11574:288::-;11615:3;11653:5;11647:12;11680:6;11675:3;11668:19;11736:6;11729:4;11722:5;11718:16;11711:4;11706:3;11702:14;11696:47;11788:1;11781:4;11772:6;11767:3;11763:16;11759:27;11752:38;11851:4;11844:2;11840:7;11835:2;11827:6;11823:15;11819:29;11814:3;11810:39;11806:50;11799:57;;;11574:288;;;;:::o;11867:779::-;12027:4;12075:2;12064:9;12060:18;12105:2;12094:9;12087:21;12128:6;12163;12157:13;12194:6;12186;12179:22;12232:2;12221:9;12217:18;12210:25;;12294:2;12284:6;12281:1;12277:14;12266:9;12262:30;12258:39;12244:53;;12332:2;12324:6;12320:15;12353:1;12363:254;12377:6;12374:1;12371:13;12363:254;;;12470:2;12466:7;12454:9;12446:6;12442:22;12438:36;12433:3;12426:49;12498:39;12530:6;12521;12515:13;12498:39;:::i;:::-;12488:49;-1:-1:-1;12572:2:1;12595:12;;;;12560:15;;;;;12399:1;12392:9;12363:254;;;-1:-1:-1;12634:6:1;;11867:779;-1:-1:-1;;;;;;11867:779:1:o;12859:629::-;12972:6;12980;12988;13041:2;13029:9;13020:7;13016:23;13012:32;13009:52;;;13057:1;13054;13047:12;13009:52;13097:9;13084:23;-1:-1:-1;;;;;13122:6:1;13119:30;13116:50;;;13162:1;13159;13152:12;13116:50;13185:76;13253:7;13244:6;13233:9;13229:22;13185:76;:::i;:::-;13175:86;;;13311:2;13300:9;13296:18;13283:32;13324:31;13349:5;13324:31;:::i;:::-;12859:629;;13374:5;;-1:-1:-1;;;13452:2:1;13437:18;;;;13424:32;;12859:629::o;14125:245::-;14192:6;14245:2;14233:9;14224:7;14220:23;14216:32;14213:52;;;14261:1;14258;14251:12;14213:52;14293:9;14287:16;14312:28;14334:5;14312:28;:::i;14375:251::-;14445:6;14498:2;14486:9;14477:7;14473:23;14469:32;14466:52;;;14514:1;14511;14504:12;14466:52;14546:9;14540:16;14565:31;14590:5;14565:31;:::i;14631:230::-;14701:6;14754:2;14742:9;14733:7;14729:23;14725:32;14722:52;;;14770:1;14767;14760:12;14722:52;-1:-1:-1;14815:16:1;;14631:230;-1:-1:-1;14631:230:1:o;14866:127::-;14927:10;14922:3;14918:20;14915:1;14908:31;14958:4;14955:1;14948:15;14982:4;14979:1;14972:15;14998:128;15065:9;;;15086:11;;;15083:37;;;15100:18;;:::i;15410:127::-;15471:10;15466:3;15462:20;15459:1;15452:31;15502:4;15499:1;15492:15;15526:4;15523:1;15516:15;15542:456;15630:6;15638;15646;15699:2;15687:9;15678:7;15674:23;15670:32;15667:52;;;15715:1;15712;15705:12;15667:52;-1:-1:-1;;15760:16:1;;15866:2;15851:18;;15845:25;15962:2;15947:18;;;15941:25;15760:16;;15845:25;;-1:-1:-1;15941:25:1;15542:456;-1:-1:-1;15542:456:1:o;16003:220::-;16123:9;16160:57;16202:14;16195:5;16160:57;:::i;16496:214::-;16612:9;16649:55;16689:14;16682:5;16649:55;:::i;16978:332::-;17079:4;17137:11;17124:25;17231:2;17227:7;17216:8;17200:14;17196:29;17192:43;17172:18;17168:68;17158:96;;17250:1;17247;17240:12;17158:96;17271:33;;;;;16978:332;-1:-1:-1;;16978:332:1:o;17315:902::-;17433:9;17492:4;17484:5;17468:14;17464:26;17460:37;17457:57;;;17510:1;17507;17500:12;17457:57;17563:2;17557:9;17605:4;17593:17;;-1:-1:-1;;;;;17625:34:1;;17661:22;;;17622:62;17619:88;;;17687:18;;:::i;:::-;17723:2;17716:22;17762:19;;17790:33;17762:19;17790:33;:::i;:::-;17832:23;;17903:2;17892:14;;17879:28;17916:30;17879:28;17916:30;:::i;:::-;17974:2;17962:15;;17955:32;18034:2;18023:14;;18010:28;-1:-1:-1;;;;;18050:30:1;;18047:50;;;18093:1;18090;18083:12;18047:50;18130:52;18167:14;18158:6;18151:5;18147:18;18130:52;:::i;:::-;18125:2;18113:15;;18106:77;-1:-1:-1;18117:6:1;17315:902;-1:-1:-1;;17315:902:1:o;18222:411::-;-1:-1:-1;;;;;18425:32:1;;;18407:51;;18494:32;;18489:2;18474:18;;18467:60;18563:2;18558;18543:18;;18536:30;;;-1:-1:-1;;18583:44:1;;18608:18;;18600:6;18583:44;:::i;18943:549::-;19024:12;;-1:-1:-1;;;;;19020:38:1;;;19008:51;;19108:4;19097:16;;;19091:23;19075:14;;;19068:47;19168:4;19157:16;;;19151:23;19147:49;;19131:14;;;19124:73;19250:4;19239:16;;;19233:23;19229:49;;;19213:14;;;19206:73;19328:4;19317:16;;;19311:23;19295:14;;;19288:47;19046:3;19370:16;;;19364:23;19419:4;19403:14;;;19396:28;;;-1:-1:-1;;19440:46:1;;19471:14;;19364:23;19440:46;:::i;19497:1508::-;19750:6;19739:9;19732:25;19822:1;19818;19813:3;19809:11;19805:19;19797:6;19793:32;19788:2;19777:9;19773:18;19766:60;19862:2;19857;19846:9;19842:18;19835:30;19713:4;19903:3;19892:9;19888:19;19979:1;19975;19970:3;19966:11;19962:19;19953:6;19947:13;19943:39;19938:2;19927:9;19923:18;19916:67;20038:2;20030:6;20026:15;20020:22;20014:3;20003:9;19999:19;19992:51;20125:1;20121;20116:3;20112:11;20108:19;20102:2;20094:6;20090:15;20084:22;20080:48;20074:3;20063:9;20059:19;20052:77;20185:2;20177:6;20173:15;20167:22;20160:4;20149:9;20145:20;20138:52;20237:3;20229:6;20225:16;20219:23;20279:4;20273:3;20262:9;20258:19;20251:33;20304:6;20339:12;20333:19;20376:6;20368;20361:22;20414:3;20403:9;20399:19;20392:26;;20477:3;20467:6;20464:1;20460:14;20449:9;20445:30;20441:40;20427:54;;20522:2;20508:12;20504:21;20490:35;;20543:1;20553:261;20567:6;20564:1;20561:13;20553:261;;;20660:3;20656:8;20644:9;20636:6;20632:22;20628:37;20623:3;20616:50;20689:45;20727:6;20718;20712:13;20689:45;:::i;:::-;20679:55;-1:-1:-1;20769:2:1;20757:15;;;;20792:12;;;;;20589:1;20582:9;20553:261;;;-1:-1:-1;;;;20863:3:1;20851:16;;20845:23;20909:22;;;-1:-1:-1;;20905:36:1;20899:3;20884:19;;20877:65;20959:40;20913:6;20845:23;20959:40;:::i;:::-;20951:48;19497:1508;-1:-1:-1;;;;;;;19497:1508:1:o;21010:1012::-;21259:6;21248:9;21241:25;21331:1;21327;21322:3;21318:11;21314:19;21306:6;21302:32;21297:2;21286:9;21282:18;21275:60;21371:2;21366;21355:9;21351:18;21344:30;21446:1;21442;21437:3;21433:11;21429:19;21420:6;21414:13;21410:39;21405:2;21394:9;21390:18;21383:67;21505:2;21497:6;21493:15;21487:22;21481:3;21470:9;21466:19;21459:51;21592:1;21588;21583:3;21579:11;21575:19;21569:2;21561:6;21557:15;21551:22;21547:48;21541:3;21530:9;21526:19;21519:77;21652:2;21644:6;21640:15;21634:22;21627:4;21616:9;21612:20;21605:52;21222:4;21704:3;21696:6;21692:16;21686:23;21746:4;21740:3;21729:9;21725:19;21718:33;21774:57;21826:3;21815:9;21811:19;21797:12;21774:57;:::i;:::-;21760:71;;21880:3;21872:6;21868:16;21862:23;21954:2;21950:7;21938:9;21930:6;21926:22;21922:36;21916:3;21905:9;21901:19;21894:65;21976:40;22009:6;21993:14;21976:40;:::i;22027:301::-;22156:3;22194:6;22188:13;22240:6;22233:4;22225:6;22221:17;22216:3;22210:37;22302:1;22266:16;;22291:13;;;-1:-1:-1;22266:16:1;22027:301;-1:-1:-1;22027:301:1:o;22333:346::-;22534:2;22523:9;22516:21;22497:4;22554:50;22600:2;22589:9;22585:18;22577:6;22554:50;:::i;:::-;22546:58;;22669:1;22665;22660:3;22656:11;22652:19;22644:6;22640:32;22635:2;22624:9;22620:18;22613:60;22333:346;;;;;:::o;23054:343::-;23133:6;23141;23194:2;23182:9;23173:7;23169:23;23165:32;23162:52;;;23210:1;23207;23200:12;23162:52;-1:-1:-1;;23255:16:1;;23361:2;23346:18;;;23340:25;23255:16;;23340:25;;-1:-1:-1;23054:343:1:o;23402:273::-;23470:6;23523:2;23511:9;23502:7;23498:23;23494:32;23491:52;;;23539:1;23536;23529:12;23491:52;23571:9;23565:16;23621:4;23614:5;23610:16;23603:5;23600:27;23590:55;;23641:1;23638;23631:12;23680:375;23768:1;23786:5;23800:249;23821:1;23811:8;23808:15;23800:249;;;23871:4;23866:3;23862:14;23856:4;23853:24;23850:50;;;23880:18;;:::i;:::-;23930:1;23920:8;23916:16;23913:49;;;23944:16;;;;23913:49;24027:1;24023:16;;;;;23983:15;;23800:249;;;23680:375;;;;;;:::o;24060:902::-;24109:5;24139:8;24129:80;;-1:-1:-1;24180:1:1;24194:5;;24129:80;24228:4;24218:76;;-1:-1:-1;24265:1:1;24279:5;;24218:76;24310:4;24328:1;24323:59;;;;24396:1;24391:174;;;;24303:262;;24323:59;24353:1;24344:10;;24367:5;;;24391:174;24428:3;24418:8;24415:17;24412:43;;;24435:18;;:::i;:::-;-1:-1:-1;;24491:1:1;24477:16;;24550:5;;24303:262;;24649:2;24639:8;24636:16;24630:3;24624:4;24621:13;24617:36;24611:2;24601:8;24598:16;24593:2;24587:4;24584:12;24580:35;24577:77;24574:203;;;-1:-1:-1;24686:19:1;;;24762:5;;24574:203;24809:42;-1:-1:-1;;24834:8:1;24828:4;24809:42;:::i;:::-;24887:6;24883:1;24879:6;24875:19;24866:7;24863:32;24860:58;;;24898:18;;:::i;:::-;24936:20;;24060:902;-1:-1:-1;;;24060:902:1:o;24967:140::-;25025:5;25054:47;25095:4;25085:8;25081:19;25075:4;25054:47;:::i
Swarm Source
ipfs://69022c390b5c888ba0cc9a96eddc9c38967cf03a3ed114cae5a6286362eae578
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in MON
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.