Source Code
Latest 25 from a total of 53 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Zap Out | 24541719 | 8 days ago | IN | 0 ETH | 0.00059617 | ||||
| Zap Out | 24541352 | 8 days ago | IN | 0 ETH | 0.00005137 | ||||
| Zap Out | 24485072 | 16 days ago | IN | 0 ETH | 0.0004493 | ||||
| Zap Out | 24485063 | 16 days ago | IN | 0 ETH | 0.00055353 | ||||
| Zap Out | 24483235 | 17 days ago | IN | 0 ETH | 0.00047734 | ||||
| Zap Out | 24482856 | 17 days ago | IN | 0 ETH | 0.000466 | ||||
| Zap Out | 24482618 | 17 days ago | IN | 0 ETH | 0.00045389 | ||||
| Zap Out | 24482615 | 17 days ago | IN | 0 ETH | 0.00048055 | ||||
| Zap Out | 24482524 | 17 days ago | IN | 0 ETH | 0.00044083 | ||||
| Transfer | 24482458 | 17 days ago | IN | 0 ETH | 0.00000092 | ||||
| Zap Out | 24482455 | 17 days ago | IN | 0 ETH | 0.00044015 | ||||
| Zap Out | 24482409 | 17 days ago | IN | 0 ETH | 0.00052492 | ||||
| Transfer | 24482401 | 17 days ago | IN | 0 ETH | 0.0000009 | ||||
| Zap Out | 24482396 | 17 days ago | IN | 0 ETH | 0.00011126 | ||||
| Zap Out | 24482000 | 17 days ago | IN | 0 ETH | 0.00002773 | ||||
| Zap Out | 24478720 | 17 days ago | IN | 0 ETH | 0.00007709 | ||||
| Zap Out | 24478711 | 17 days ago | IN | 0 ETH | 0.00000247 | ||||
| Zap Out | 24478502 | 17 days ago | IN | 0 ETH | 0.00011212 | ||||
| Zap Out | 24478485 | 17 days ago | IN | 0 ETH | 0.0018256 | ||||
| Zap Out | 24478481 | 17 days ago | IN | 0 ETH | 0.00182856 | ||||
| Zap Out | 24478476 | 17 days ago | IN | 0 ETH | 0.00209937 | ||||
| Zap Out | 24478465 | 17 days ago | IN | 0 ETH | 0.00179383 | ||||
| Zap Out | 24478344 | 17 days ago | IN | 0 ETH | 0.00186949 | ||||
| Zap Out | 24478341 | 17 days ago | IN | 0 ETH | 0.00190309 | ||||
| Transfer | 24478335 | 17 days ago | IN | 0 ETH | 0.00000258 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
StoneZapOut
Compiler Version
v0.8.27+commit.40a35a09
Optimization Enabled:
Yes with 200 runs
Other Settings:
prague EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {
SafeERC20
} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {ILightPsm, ICurve3Pool, ICurveLusd, ICurveNg} from "./interfaces/ICurve.sol";
/// @title StoneZapOut
/// @notice Zap out of Stone Vault: burn SVT, withdraw DAI+LUSD+crvUSD, swap all to one token (DAI, USDC, USDT, LUSD, crvUSD) in one tx. Owner can sweep dust only.
contract StoneZapOut is Ownable2Step, ReentrancyGuard {
using SafeERC20 for IERC20;
uint256 private constant BPS_DENOMINATOR = 10000;
uint256 private constant MAX_SLIPPAGE_BPS = 500; // 5% maximum slippage
IERC20 public immutable vaultToken;
IERC20 public immutable DAI;
IERC20 public immutable LUSD;
IERC20 public immutable CRVUSD;
IERC20 public immutable USDC;
IERC20 public immutable USDT;
address public immutable vault;
address public immutable lightPsm;
address public immutable curve3Pool;
address public immutable curveLusdPool;
address public immutable curveCrvUsdUsdc;
address public immutable curveCrvUsdUsdt;
error InvalidOutputToken();
error ZeroAmount();
error ZeroReceiver();
error InsufficientOutput();
error DeadlineExpired();
error SlippageTooHigh();
error ZeroAddress();
event ZapOut(
address indexed user,
address indexed tokenOut,
uint256 sharesIn,
uint256 amountOut
);
constructor(
address _vault,
address _dai,
address _lusd,
address _crvusd,
address _usdc,
address _usdt,
address _lightPsm,
address _curve3Pool,
address _curveLusdPool,
address _curveCrvUsdUsdc,
address _curveCrvUsdUsdt
) Ownable(msg.sender) {
// Validate all addresses to prevent deployment with zero addresses
if (_vault == address(0)) revert ZeroAddress();
if (_dai == address(0)) revert ZeroAddress();
if (_lusd == address(0)) revert ZeroAddress();
if (_crvusd == address(0)) revert ZeroAddress();
if (_usdc == address(0)) revert ZeroAddress();
if (_usdt == address(0)) revert ZeroAddress();
if (_lightPsm == address(0)) revert ZeroAddress();
if (_curve3Pool == address(0)) revert ZeroAddress();
if (_curveLusdPool == address(0)) revert ZeroAddress();
if (_curveCrvUsdUsdc == address(0)) revert ZeroAddress();
if (_curveCrvUsdUsdt == address(0)) revert ZeroAddress();
vault = _vault;
vaultToken = IERC20(_vault);
DAI = IERC20(_dai);
LUSD = IERC20(_lusd);
CRVUSD = IERC20(_crvusd);
USDC = IERC20(_usdc);
USDT = IERC20(_usdt);
lightPsm = _lightPsm;
curve3Pool = _curve3Pool;
curveLusdPool = _curveLusdPool;
curveCrvUsdUsdc = _curveCrvUsdUsdc;
curveCrvUsdUsdt = _curveCrvUsdUsdt;
// NOTE: SVT approval removed - StoneVaultCore.withdraw() uses _burn(msg.sender), not transferFrom
}
/// @notice Zap out: burn SVT, withdraw from vault, swap all to one token and send to receiver.
/// @param shares Amount of SVT to burn.
/// @param outputToken One of DAI, USDC, USDT, LUSD, CRVUSD.
/// @param receiver Gets the output token.
/// @param minAmountOut Minimum amount of output token (slippage).
/// @param slippageBps Slippage for each swap in basis points (e.g. 50 = 0.5%, max 500 = 5%).
/// @param minVaultAmountsOut Min amounts from vault [DAI, LUSD, crvUSD]; use [0,0,0] to skip.
/// @param deadline Unix timestamp after which the transaction will revert.
function zapOut(
uint256 shares,
address outputToken,
address receiver,
uint256 minAmountOut,
uint256 slippageBps,
uint256[3] calldata minVaultAmountsOut,
uint256 deadline
) external nonReentrant returns (uint256 amountOut) {
// Validate deadline to prevent stale transactions
if (block.timestamp > deadline) revert DeadlineExpired();
// Validate slippage parameter to prevent user error
if (slippageBps > MAX_SLIPPAGE_BPS) revert SlippageTooHigh();
if (shares == 0) revert ZeroAmount();
if (receiver == address(0)) revert ZeroReceiver();
// L-2: Validate outputToken BEFORE any external calls
bool isValidOutput = outputToken == address(DAI)
|| outputToken == address(LUSD)
|| outputToken == address(CRVUSD)
|| outputToken == address(USDC)
|| outputToken == address(USDT);
if (!isValidOutput) revert InvalidOutputToken();
vaultToken.safeTransferFrom(msg.sender, address(this), shares);
// Measure output token balance BEFORE operations (to exclude any dust)
uint256 balanceBefore = IERC20(outputToken).balanceOf(address(this));
// Snapshot vault token balances BEFORE withdrawal (to compute exact net deltas)
uint256 daiBefore_w = DAI.balanceOf(address(this));
uint256 lusdBefore_w = LUSD.balanceOf(address(this));
uint256 crvusdBefore_w = CRVUSD.balanceOf(address(this));
_withdrawFromVault(shares, minVaultAmountsOut);
// Exact NET amounts received from vault (excludes any pre-existing dust)
uint256 actualDai = DAI.balanceOf(address(this)) - daiBefore_w;
uint256 actualLusd = LUSD.balanceOf(address(this)) - lusdBefore_w;
uint256 actualCrvusd = CRVUSD.balanceOf(address(this)) - crvusdBefore_w;
// Perform swaps to convert everything to outputToken
if (outputToken == address(DAI)) {
_zapOutToDAI(actualDai, actualLusd, actualCrvusd, slippageBps);
} else if (outputToken == address(LUSD)) {
_zapOutToLUSD(actualDai, actualLusd, actualCrvusd, slippageBps);
} else if (outputToken == address(CRVUSD)) {
_zapOutToCRVUSD(actualDai, actualLusd, actualCrvusd, slippageBps);
} else if (outputToken == address(USDC)) {
_zapOutToUSDC(actualDai, actualLusd, actualCrvusd, slippageBps);
} else {
// Must be USDT (already validated above)
_zapOutToUSDT(actualDai, actualLusd, actualCrvusd, slippageBps);
}
// Calculate ACTUAL amount received (balanceAfter - balanceBefore)
// This ensures we only transfer tokens earned in THIS transaction, not dust from previous operations
uint256 balanceAfter = IERC20(outputToken).balanceOf(address(this));
amountOut = balanceAfter - balanceBefore;
if (amountOut < minAmountOut) revert InsufficientOutput();
IERC20(outputToken).safeTransfer(receiver, amountOut);
emit ZapOut(msg.sender, outputToken, shares, amountOut);
return amountOut;
}
/// @notice Sweeps token balance to owner. Admin cannot interleave into user transactions; dust only.
function sweep(address token) external onlyOwner {
uint256 bal = IERC20(token).balanceOf(address(this));
if (bal > 0) {
IERC20(token).safeTransfer(owner(), bal);
}
}
function _withdrawFromVault(
uint256 shares,
uint256[3] calldata minAmountsOut
) internal returns (uint256[3] memory amounts) {
(bool ok, bytes memory data) = vault.call(
abi.encodeWithSignature(
"withdraw(uint256,address,uint256[3])",
shares,
address(this),
minAmountsOut
)
);
if (!ok) _revert(data);
amounts = abi.decode(data, (uint256[3]));
return amounts;
}
function _revert(bytes memory data) internal pure {
if (data.length >= 4) {
assembly {
revert(add(data, 32), mload(data))
}
}
revert("ZapOut: vault call failed");
}
/// @dev Calculates minimum output based on 1:1 stablecoin peg (MEV-resistant).
/// Uses the known peg ratio instead of on-chain get_dy() which can be manipulated.
/// @param amountIn Input amount in source token decimals
/// @param fromDec Source token decimals (6 or 18)
/// @param toDec Destination token decimals (6 or 18)
/// @param bps Slippage tolerance in basis points
function _pegMinOut(
uint256 amountIn,
uint8 fromDec,
uint8 toDec,
uint256 bps
) internal pure returns (uint256) {
uint256 fairQuote;
if (fromDec <= toDec) {
fairQuote = amountIn * 10 ** (toDec - fromDec);
} else {
fairQuote = amountIn / 10 ** (fromDec - toDec);
}
return (fairQuote * (BPS_DENOMINATOR - bps)) / BPS_DENOMINATOR;
}
// ---------- To DAI: keep DAI; LUSD -> DAI (LUSD pool); crvUSD -> USDC -> DAI (PSM) ----------
function _zapOutToDAI(
uint256 daiAmt,
uint256 lusdAmt,
uint256 crvusdAmt,
uint256 slippageBps
) internal {
// DAI from vault is already on the contract (daiAmt kept as-is)
if (lusdAmt > 0) {
LUSD.forceApprove(curveLusdPool, lusdAmt);
ICurveLusd(curveLusdPool).exchange_underlying(
0,
1,
lusdAmt,
_pegMinOut(lusdAmt, 18, 18, slippageBps)
);
}
if (crvusdAmt > 0) {
uint256 usdcBefore = USDC.balanceOf(address(this));
CRVUSD.forceApprove(curveCrvUsdUsdc, crvusdAmt);
ICurveNg(curveCrvUsdUsdc).exchange(
1,
0,
crvusdAmt,
_pegMinOut(crvusdAmt, 18, 6, slippageBps)
);
uint256 usdcReceived = USDC.balanceOf(address(this)) - usdcBefore;
USDC.forceApprove(lightPsm, usdcReceived);
ILightPsm(lightPsm).sellGem(address(this), usdcReceived);
}
}
// ---------- To LUSD: keep LUSD; DAI -> LUSD (LUSD pool); crvUSD -> USDC -> LUSD (LUSD pool) ----------
function _zapOutToLUSD(
uint256 daiAmt,
uint256 lusdAmt,
uint256 crvusdAmt,
uint256 slippageBps
) internal {
// LUSD from vault is already on the contract (lusdAmt kept as-is)
if (daiAmt > 0) {
DAI.forceApprove(curveLusdPool, daiAmt);
ICurveLusd(curveLusdPool).exchange_underlying(
1,
0,
daiAmt,
_pegMinOut(daiAmt, 18, 18, slippageBps)
);
}
if (crvusdAmt > 0) {
uint256 usdcBefore = USDC.balanceOf(address(this));
CRVUSD.forceApprove(curveCrvUsdUsdc, crvusdAmt);
ICurveNg(curveCrvUsdUsdc).exchange(
1,
0,
crvusdAmt,
_pegMinOut(crvusdAmt, 18, 6, slippageBps)
);
uint256 usdcReceived = USDC.balanceOf(address(this)) - usdcBefore;
USDC.forceApprove(curveLusdPool, usdcReceived);
ICurveLusd(curveLusdPool).exchange_underlying(
2,
0,
usdcReceived,
_pegMinOut(usdcReceived, 6, 18, slippageBps)
);
}
}
// ---------- To crvUSD: keep crvUSD; DAI -> USDC -> crvUSD; LUSD -> USDC -> crvUSD ----------
function _zapOutToCRVUSD(
uint256 daiAmt,
uint256 lusdAmt,
uint256 crvusdAmt,
uint256 slippageBps
) internal {
// crvUSD from vault is already on the contract (crvusdAmt kept as-is)
if (daiAmt > 0) {
// DAI -> USDC via PSM (1:1, zero fee) instead of 3pool
uint256 usdcBefore = USDC.balanceOf(address(this));
uint256 usdcWanted = _to6(daiAmt);
DAI.forceApprove(lightPsm, daiAmt);
ILightPsm(lightPsm).buyGem(address(this), usdcWanted);
uint256 usdcReceived = USDC.balanceOf(address(this)) - usdcBefore;
USDC.forceApprove(curveCrvUsdUsdc, usdcReceived);
ICurveNg(curveCrvUsdUsdc).exchange(
0,
1,
usdcReceived,
_pegMinOut(usdcReceived, 6, 18, slippageBps)
);
}
if (lusdAmt > 0) {
uint256 usdcBefore = USDC.balanceOf(address(this));
LUSD.forceApprove(curveLusdPool, lusdAmt);
ICurveLusd(curveLusdPool).exchange_underlying(
0,
2,
lusdAmt,
_pegMinOut(lusdAmt, 18, 6, slippageBps)
);
uint256 usdcReceived = USDC.balanceOf(address(this)) - usdcBefore;
USDC.forceApprove(curveCrvUsdUsdc, usdcReceived);
ICurveNg(curveCrvUsdUsdc).exchange(
0,
1,
usdcReceived,
_pegMinOut(usdcReceived, 6, 18, slippageBps)
);
}
}
// ---------- To USDC: DAI -> PSM buyGem; LUSD -> LUSD pool 0->2; crvUSD -> crvUSD/USDC 1->0 ----------
function _zapOutToUSDC(
uint256 daiAmt,
uint256 lusdAmt,
uint256 crvusdAmt,
uint256 slippageBps
) internal {
// No USDC from vault, all needs to be swapped
if (daiAmt > 0) {
uint256 usdcWanted = _to6(daiAmt);
DAI.forceApprove(lightPsm, daiAmt);
ILightPsm(lightPsm).buyGem(address(this), usdcWanted);
}
if (lusdAmt > 0) {
LUSD.forceApprove(curveLusdPool, lusdAmt);
ICurveLusd(curveLusdPool).exchange_underlying(
0,
2,
lusdAmt,
_pegMinOut(lusdAmt, 18, 6, slippageBps)
);
}
if (crvusdAmt > 0) {
CRVUSD.forceApprove(curveCrvUsdUsdc, crvusdAmt);
ICurveNg(curveCrvUsdUsdc).exchange(
1,
0,
crvusdAmt,
_pegMinOut(crvusdAmt, 18, 6, slippageBps)
);
}
}
// ---------- To USDT: DAI -> 3pool 0->2; LUSD -> LUSD pool 0->3; crvUSD -> crvUSD/USDT 1->0 ----------
function _zapOutToUSDT(
uint256 daiAmt,
uint256 lusdAmt,
uint256 crvusdAmt,
uint256 slippageBps
) internal {
// No USDT from vault, all needs to be swapped
if (daiAmt > 0) {
DAI.forceApprove(curve3Pool, daiAmt);
ICurve3Pool(curve3Pool).exchange(
0,
2,
daiAmt,
_pegMinOut(daiAmt, 18, 6, slippageBps)
);
}
if (lusdAmt > 0) {
LUSD.forceApprove(curveLusdPool, lusdAmt);
ICurveLusd(curveLusdPool).exchange_underlying(
0,
3,
lusdAmt,
_pegMinOut(lusdAmt, 18, 6, slippageBps)
);
}
if (crvusdAmt > 0) {
CRVUSD.forceApprove(curveCrvUsdUsdt, crvusdAmt);
ICurveNg(curveCrvUsdUsdt).exchange(
1,
0,
crvusdAmt,
_pegMinOut(crvusdAmt, 18, 6, slippageBps)
);
}
}
/// @dev 18 decimals -> 6 decimals (scale down)
function _to6(uint256 amt18) internal pure returns (uint256) {
return amt18 / 1e12;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
if (!_safeTransfer(token, to, value, true)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
if (!_safeTransferFrom(token, from, to, value, true)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _safeTransfer(token, to, value, false);
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _safeTransferFrom(token, from, to, value, false);
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
if (!_safeApprove(token, spender, value, false)) {
if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));
if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Oppositely, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity `token.transfer(to, value)` call, relaxing the requirement on the return value: the
* return value is optional (but if data is returned, it must not be false).
*
* @param token The token targeted by the call.
* @param to The recipient of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {
bytes4 selector = IERC20.transfer.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(to, shr(96, not(0))))
mstore(0x24, value)
success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0x00, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
}
}
/**
* @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return
* value: the return value is optional (but if data is returned, it must not be false).
*
* @param token The token targeted by the call.
* @param from The sender of the tokens
* @param to The recipient of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value,
bool bubble
) private returns (bool success) {
bytes4 selector = IERC20.transferFrom.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(from, shr(96, not(0))))
mstore(0x24, and(to, shr(96, not(0))))
mstore(0x44, value)
success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0x00, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
mstore(0x60, 0)
}
}
/**
* @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:
* the return value is optional (but if data is returned, it must not be false).
*
* @param token The token targeted by the call.
* @param spender The spender of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {
bytes4 selector = IERC20.approve.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(spender, shr(96, not(0))))
mstore(0x24, value)
success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0x00, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.20;
import {Ownable} from "./Ownable.sol";
/**
* @dev Contract module which provides access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* This extension of the {Ownable} contract includes a two-step mechanism to transfer
* ownership, where the new owner must call {acceptOwnership} in order to replace the
* old one. This can help prevent common mistakes, such as transfers of ownership to
* incorrect accounts, or to contracts that are unable to interact with the
* permission system.
*
* The initial owner is specified at deployment time in the constructor for `Ownable`. This
* can later be changed with {transferOwnership} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2Step is Ownable {
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*
* Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
if (pendingOwner() != sender) {
revert OwnableUnauthorizedAccount(sender);
}
_transferOwnership(sender);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.5.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
import {StorageSlot} from "./StorageSlot.sol";
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*
* IMPORTANT: Deprecated. This storage-based reentrancy guard will be removed and replaced
* by the {ReentrancyGuardTransient} variant in v6.0.
*
* @custom:stateless
*/
abstract contract ReentrancyGuard {
using StorageSlot for bytes32;
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant REENTRANCY_GUARD_STORAGE =
0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_reentrancyGuardStorageSlot().getUint256Slot().value = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
/**
* @dev A `view` only version of {nonReentrant}. Use to block view functions
* from being called, preventing reading from inconsistent contract state.
*
* CAUTION: This is a "view" modifier and does not change the reentrancy
* status. Use it only on view functions. For payable or non-payable functions,
* use the standard {nonReentrant} modifier instead.
*/
modifier nonReentrantView() {
_nonReentrantBeforeView();
_;
}
function _nonReentrantBeforeView() private view {
if (_reentrancyGuardEntered()) {
revert ReentrancyGuardReentrantCall();
}
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
_nonReentrantBeforeView();
// Any calls to nonReentrant after this point will fail
_reentrancyGuardStorageSlot().getUint256Slot().value = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_reentrancyGuardStorageSlot().getUint256Slot().value = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _reentrancyGuardStorageSlot().getUint256Slot().value == ENTERED;
}
function _reentrancyGuardStorageSlot() internal pure virtual returns (bytes32) {
return REENTRANCY_GUARD_STORAGE;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
/// @title ICurve - Unified Curve Finance interfaces
/// @notice Contains interfaces for all Curve pools used in Stone Vault
interface ILightPsm {
/// @notice Sell gem (USDC/USDT) to receive DAI
/// @param usr Recipient address
/// @param gemAmt Amount of gem tokens to sell
/// @return Amount of DAI received
function sellGem(address usr, uint256 gemAmt) external returns (uint256);
/// @notice Buy gem (USDC/USDT) by paying DAI
/// @param usr Recipient address
/// @param gemAmt Amount of gem tokens to buy
/// @return Amount of DAI paid
function buyGem(address usr, uint256 gemAmt) external returns (uint256);
}
interface ICurve3Pool {
/// @notice Exchange tokens in the 3pool (DAI/USDC/USDT)
/// @param i Index of input token
/// @param j Index of output token
/// @param dx Amount of input token
/// @param min_dy Minimum amount of output token to receive
function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external;
/// @notice Get expected output amount for exchange
/// @param i Index of input token
/// @param j Index of output token
/// @param dx Amount of input token
/// @return Expected output amount
function get_dy(
int128 i,
int128 j,
uint256 dx
) external view returns (uint256);
}
interface ICurveLusd {
/// @notice Exchange underlying tokens in LUSD pool
/// @param i Index of input token
/// @param j Index of output token
/// @param dx Amount of input token
/// @param min_dy Minimum amount of output token to receive
/// @return Actual amount received
function exchange_underlying(
int128 i,
int128 j,
uint256 dx,
uint256 min_dy
) external returns (uint256);
/// @notice Get expected output amount for underlying exchange
/// @param i Index of input token
/// @param j Index of output token
/// @param dx Amount of input token
/// @return Expected output amount
function get_dy_underlying(
int128 i,
int128 j,
uint256 dx
) external view returns (uint256);
}
interface ICurveNg {
/// @notice Exchange tokens in Curve NG pools (crvUSD/USDC, crvUSD/USDT)
/// @param i Index of input token
/// @param j Index of output token
/// @param dx Amount of input token
/// @param min_dy Minimum amount of output token to receive
/// @return Actual amount received
function exchange(
int128 i,
int128 j,
uint256 dx,
uint256 min_dy
) external returns (uint256);
/// @notice Get expected output amount for exchange
/// @param i Index of input token
/// @param j Index of output token
/// @param dx Amount of input token
/// @return Expected output amount
function get_dy(
int128 i,
int128 j,
uint256 dx
) external view returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.20;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC-1967 implementation slot:
* ```solidity
* contract ERC1967 {
* // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(newImplementation.code.length > 0);
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* TIP: Consider using this library along with {SlotDerivation}.
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct Int256Slot {
int256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Int256Slot` with member `value` located at `slot`.
*/
function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
assembly ("memory-safe") {
r.slot := store.slot
}
}
/**
* @dev Returns a `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
assembly ("memory-safe") {
r.slot := store.slot
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* 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[ERC 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);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "prague",
"viaIR": true
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_dai","type":"address"},{"internalType":"address","name":"_lusd","type":"address"},{"internalType":"address","name":"_crvusd","type":"address"},{"internalType":"address","name":"_usdc","type":"address"},{"internalType":"address","name":"_usdt","type":"address"},{"internalType":"address","name":"_lightPsm","type":"address"},{"internalType":"address","name":"_curve3Pool","type":"address"},{"internalType":"address","name":"_curveLusdPool","type":"address"},{"internalType":"address","name":"_curveCrvUsdUsdc","type":"address"},{"internalType":"address","name":"_curveCrvUsdUsdt","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DeadlineExpired","type":"error"},{"inputs":[],"name":"InsufficientOutput","type":"error"},{"inputs":[],"name":"InvalidOutputToken","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"SlippageTooHigh","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"inputs":[],"name":"ZeroReceiver","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"sharesIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"ZapOut","type":"event"},{"inputs":[],"name":"CRVUSD","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAI","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LUSD","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDC","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDT","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"curve3Pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curveCrvUsdUsdc","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curveCrvUsdUsdt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curveLusdPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lightPsm","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"uint256","name":"slippageBps","type":"uint256"},{"internalType":"uint256[3]","name":"minVaultAmountsOut","type":"uint256[3]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"zapOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
610200346103dd57601f61230738819003918201601f19168301916001600160401b038311848410176103e157808492610160946040528339810103126103dd57610049816103f5565b610055602083016103f5565b91610062604082016103f5565b9161006f606083016103f5565b9061007c608084016103f5565b9061008960a085016103f5565b9061009660c086016103f5565b916100a360e087016103f5565b936100b161010088016103f5565b956100cc6101406100c56101208b016103f5565b99016103f5565b9833156103ca57600180546001600160a01b03199081169091555f805433928116831782556040519d92916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00556001600160a01b0386169081156103bb576001600160a01b03169182156103bb576001600160a01b03169283156103bb576001600160a01b03169384156103bb576001600160a01b03169485156103bb576001600160a01b03169586156103bb576001600160a01b038816156103bb576001600160a01b038916156103bb576001600160a01b038a16156103bb576001600160a01b038b16156103bb576001600160a01b038c16156103bb576101405260805260a05260c05260e052610100526101205261016052610180526101a0526101c0526101e052611efd908161040a82396080518181816103d60152610909015260a05181818161038801528181610bf40152818161116c01528181611382015261196d015260c05181818161046f0152818161083601528181610b6c015281816110a7015281816112a70152818161149e0152611c08015260e05181818161029f015281816104c50152818161080401528181610fe201528181611255015281816118100152611aac0152610100518181816106cd015281816107d201528181610abd0152818161142c015281816116000152818161179e0152611a320152610120518181816107a00152610b28015261014051818181610cd20152610f13015261016051818181610a350152818161135f0152611b2e0152610180518181816108c5015261114601526101a05181818161025b0152818161108101528181611281015281816114780152818161189e015281816119470152611be201526101c051818181610bb00152818161122e0152818161152c015281816116b6015281816117ea0152611a8501526101e051818181610a790152610fbb0152f35b63d92e233d60e01b5f5260045ffd5b631e4fbdf760e01b5f525f60045260245ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036103dd5756fe60806040526004361015610011575f80fd5b5f3560e01c806301681a6214610144578063087eb2b41461013f57806316063ec01461013a5780632d7882201461013557806363a6b1da14610130578063703bafd51461012b578063715018a61461012657806379ba5097146101215780637a4b1f561461011c578063877705ee1461011757806389a30271146101125780638da5cb5b1461010d578063c54e44eb14610108578063cf59d56314610103578063d44bd1e5146100fe578063e0bab4c4146100f9578063e30c3978146100f4578063f2fde38b146100ef5763fbfa77cf146100ea575f80fd5b610cbd565b610c4b565b610c23565b610bdf565b610b9b565b610b57565b610b13565b610aec565b610aa8565b610a64565b610a20565b61099b565b610938565b6108f4565b6108b0565b6102ce565b61028a565b610246565b61018f565b600435906001600160a01b038216820361015f57565b5f80fd5b602435906001600160a01b038216820361015f57565b604435906001600160a01b038216820361015f57565b3461015f57602036600319011261015f576101a8610149565b6101b0610d7c565b6040516370a0823160e01b81523060048201526001600160a01b039190911690602081602481855afa908115610237575f91610208575b50806101ef57005b5f54610206926001600160a01b0390911690610d8f565b005b61022a915060203d602011610230575b6102228183610d15565b810190610d3c565b5f6101e7565b503d610218565b610d4b565b5f91031261015f57565b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f5761012036600319011261015f576004356102eb610163565b906102f4610179565b9160643591608435366101041161015f576101043560027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0054146108a15760027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00554211610892576101f48111610883578115610874576001600160a01b03851615610865576001600160a01b03928316927f00000000000000000000000000000000000000000000000000000000000000001683811491828015610833575b8015610801575b80156107cf575b801561079d575b1561078f576103fa8430337f0000000000000000000000000000000000000000000000000000000000000000610e0c565b6040516370a0823160e01b815230600482015292602084602481895afa938415610237575f9461076e575b506040516370a0823160e01b8152306004820152602081602481875afa908115610237575f9161074f575b506040516370a0823160e01b8152306004820152936001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016602086602481845afa958615610237575f9661072e575b506040516370a0823160e01b8152306004820152926001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169290602085602481875afa948515610237575f9561070d575b506105088a610ec4565b506040516370a0823160e01b815230600482015291602090839060249082905afa801561023757610540925f91610682575b50610d6a565b6040516370a0823160e01b81523060048201529096602082602481865afa801561023757610574925f916106825750610d6a565b6040516370a0823160e01b81523060048201529093602082602481875afa8015610237576105a8925f916106825750610d6a565b93156106a15750506105ba9350611a0a565b6040516370a0823160e01b815230600482015290602082602481875afa8015610237576105ed925f916106825750610d6a565b928310610673576106028361066f9584610d8f565b604080519182526020820184905233917f49c082cd7a2d84c4820fb8ea8b7cd2a0dac8bac51b973cfc358260a859b3c9599190a361065f60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b6040519081529081906020820190565b0390f35b63bb2875c360e01b5f5260045ffd5b61069b915060203d602011610230576102228183610d15565b5f61053a565b88036106b75750506106b292611779565b6105ba565b90919087036106ca57506106b292611407565b907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168703610704576106b293611208565b6106b293610f95565b61072791955060203d602011610230576102228183610d15565b935f6104fe565b61074891965060203d602011610230576102228183610d15565b945f6104a6565b610768915060203d602011610230576102228183610d15565b5f610450565b61078891945060203d602011610230576102228183610d15565b925f610425565b6231010160e51b5f5260045ffd5b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685146103c9565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685146103c2565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685146103bb565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685146103b4565b630d753d9b60e31b5f5260045ffd5b631f2a200560e01b5f5260045ffd5b63428637bb60e11b5f5260045ffd5b631ab7da6b60e01b5f5260045ffd5b633ee5aeb560e01b5f5260045ffd5b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f57610950610d7c565b600180546001600160a01b03199081169091555f80549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461015f575f36600319011261015f57600154336001600160a01b0390911603610a0d57600180546001600160a01b03199081169091555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f575f546040516001600160a01b039091168152602090f35b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f576001546040516001600160a01b039091168152602090f35b3461015f57602036600319011261015f57610c64610149565b610c6c610d7c565b60018060a01b0316806bffffffffffffffffffffffff60a01b600154161760015560018060a01b035f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff821117610d3757604052565b610d01565b9081602091031261015f575190565b6040513d5f823e3d90fd5b634e487b7160e01b5f52601160045260245ffd5b91908203918211610d7757565b610d56565b5f546001600160a01b03163303610a0d57565b916040519163a9059cbb60e01b5f5260018060a01b031660045260245260205f60448180865af160015f5114811615610ded575b604091909152155b610dd25750565b635274afe760e01b5f526001600160a01b031660045260245ffd5b6001811516610e03573d15833b15151616610dc3565b503d5f823e3d90fd5b6040516323b872dd60e01b5f9081526001600160a01b039384166004529290931660245260449390935260209060648180865af160015f5114811615610e5d575b6040919091525f60605215610dcb565b6001811516610e03573d15833b15151616610e4d565b9060608282031261015f5780601f8301121561015f5760405191610e98606084610d15565b82906060810192831161015f57905b828210610eb45750505090565b8151815260209182019101610ea7565b5f80916060604051610ed68282610d15565b3690376040516020810191634feb9cbd60e01b83526024820152306044820152606060a4606483013760a48152610f0e60c482610d15565b5190827f00000000000000000000000000000000000000000000000000000000000000005af13d15610f8d573d9067ffffffffffffffff8211610d375760405191610f63601f8201601f191660200184610d15565b82523d5f602084013e5b15610f885780602080610f8593518301019101610e73565b90565b611ca5565b606090610f6d565b92919280611144575b5080611079575b5081610faf575050565b6110449160209161100c7f00000000000000000000000000000000000000000000000000000000000000009161100684847f0000000000000000000000000000000000000000000000000000000000000000611cfb565b83611dc7565b915f604051809681958294630f7c084960e21b845260048401606090939291936080810194600182525f602083015260408201520152565b03926001600160a01b03165af180156102375761105e5750565b6110769060203d602011610230576102228183610d15565b50565b602061110d917f00000000000000000000000000000000000000000000000000000000000000006110cb82827f0000000000000000000000000000000000000000000000000000000000000000611cfb565b6110d58583611dc7565b915f604051809681958294635320bf6b60e11b8452600484016060909392919360808101945f82526003602083015260408201520152565b03926001600160a01b03165af180156102375715610fa55761113d9060203d602011610230576102228183610d15565b505f610fa5565b7f000000000000000000000000000000000000000000000000000000000000000061119082827f0000000000000000000000000000000000000000000000000000000000000000611cfb565b6001600160a01b0316906111a48482611dc7565b823b1561015f57604051630f7c084960e21b81525f600482018190526002602483015260448201939093526064810191909152918290608490829084905af180156102375715610f9e57806111fc5f61120293610d15565b8061023c565b5f610f9e565b92919280611344575b5080611279575b5081611222575050565b6110449160209161100c7f00000000000000000000000000000000000000000000000000000000000000009161100684847f0000000000000000000000000000000000000000000000000000000000000000611cfb565b602061130d917f00000000000000000000000000000000000000000000000000000000000000006112cb82827f0000000000000000000000000000000000000000000000000000000000000000611cfb565b6112d58583611dc7565b915f604051809681958294635320bf6b60e11b8452600484016060909392919360808101945f82526002602083015260408201520152565b03926001600160a01b03165af1801561023757156112185761133d9060203d602011610230576102228183610d15565b505f611218565b60206113d08261135a5f9464e8d4a51000900490565b6113a67f000000000000000000000000000000000000000000000000000000000000000092837f0000000000000000000000000000000000000000000000000000000000000000611cfb565b604051638d7ef9bb60e01b8152306004820152602481019190915293849283919082906044820190565b03926001600160a01b03165af180156102375715611211576114009060203d602011610230576102228183610d15565b505f611211565b806115ea575b5080611417575050565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b038116939192602084602481885afa938415610237575f946115c4575b5060206114cc917f00000000000000000000000000000000000000000000000000000000000000006114c282827f0000000000000000000000000000000000000000000000000000000000000000611cfb565b6112d58683611dc7565b03926001600160a01b03165af18015610237576115a7575b506040516370a0823160e01b815230600482015293602090859060249082905afa80156102375761152560209461155892611044975f916115905750610d6a565b92611552847f00000000000000000000000000000000000000000000000000000000000000008095611cfb565b83611def565b915f604051809681958294630f7c084960e21b8452600484016060909392919360808101945f82526001602083015260408201520152565b61069b9150873d8911610230576102228183610d15565b6115bf9060203d602011610230576102228183610d15565b6114e4565b6114cc9194506115e2602091823d8411610230576102228183610d15565b94915061146f565b6040516370a0823160e01b8152306004820152907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03811691602084602481865afa938415610237575f94611751575b5060206116588261135a5f9464e8d4a51000900490565b03926001600160a01b03165af1801561023757611734575b506040516370a0823160e01b815230600482015291602090839060249082905afa918215610237576116e6936020936116af925f9161171d5750610d6a565b906116dc827f00000000000000000000000000000000000000000000000000000000000000008093611cfb565b6115588683611def565b03926001600160a01b03165af18015610237571561140d576117169060203d602011610230576102228183610d15565b505f61140d565b61069b9150853d8711610230576102228183610d15565b61174c9060203d602011610230576102228183610d15565b611670565b5f919450611658611770602092833d8511610230576102228183610d15565b95925050611641565b8061193f575b5080611789575050565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b038116939192602084602481885afa938415610237575f94611919575b50602061183e917f000000000000000000000000000000000000000000000000000000000000000061183482827f0000000000000000000000000000000000000000000000000000000000000000611cfb565b61100c8683611dc7565b03926001600160a01b03165af18015610237576118fc575b506040516370a0823160e01b815230600482015293602090859060249082905afa8015610237576118976020946118c492611044975f916115905750610d6a565b92611552847f00000000000000000000000000000000000000000000000000000000000000008095611cfb565b915f604051809681958294635320bf6b60e11b845260048401606090939291936080810194600282525f602083015260408201520152565b6119149060203d602011610230576102228183610d15565b611856565b61183e919450611937602091823d8411610230576102228183610d15565b9491506117e1565b60206119d3917f000000000000000000000000000000000000000000000000000000000000000061199182827f0000000000000000000000000000000000000000000000000000000000000000611cfb565b61199b8683611e1b565b915f604051809681958294635320bf6b60e11b845260048401606090939291936080810194600182525f602083015260408201520152565b03926001600160a01b03165af18015610237571561177f57611a039060203d602011610230576102228183610d15565b505f61177f565b91909180611bda575b5081611a1d575050565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b038116939192909190602084602481885afa938415610237575f94611bb2575b50611ad09160209161100c7f00000000000000000000000000000000000000000000000000000000000000009161100684847f0000000000000000000000000000000000000000000000000000000000000000611cfb565b03926001600160a01b03165af1801561023757611b95575b506040516370a0823160e01b815230600482015292602090849060249082905afa90811561023757611b28602093611044935f968791611b7e5750610d6a565b611b54817f00000000000000000000000000000000000000000000000000000000000000008094611cfb565b604051634acc893b60e11b8152306004820152602481019190915293849283919082906044820190565b61069b9150863d8811610230576102228183610d15565b611bad9060203d602011610230576102228183610d15565b611ae8565b602091945091611bd1611ad093833d8511610230576102228183610d15565b94915091611a78565b6020611c6e917f0000000000000000000000000000000000000000000000000000000000000000611c2c82827f0000000000000000000000000000000000000000000000000000000000000000611cfb565b611c368583611e1b565b915f604051809681958294635320bf6b60e11b8452600484016060909392919360808101945f82526001602083015260408201520152565b03926001600160a01b03165af180156102375715611a1357611c9e9060203d602011610230576102228183610d15565b505f611a13565b8051906004821015611cf65760405162461bcd60e51b815260206004820152601960248201527f5a61704f75743a207661756c742063616c6c206661696c6564000000000000006044820152606490fd5b602001fd5b60405163095ea7b360e01b5f9081526001600160a01b03841660045260248590529193929160209060448180885af19060015f5114821615611da5575b60405215611d4557505050565b611d4f8184611e27565b15611d875790611d5f9183611e8c565b15611d675750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b635274afe760e01b5f9081526001600160a01b038416600452602490fd5b90843b15153d15161690611d38565b81810292918115918404141715610d7757565b64e8d4a5100090049061271003906127108211610d775761271091611deb91611db4565b0490565b611dff9064e8d4a5100090611db4565b9061271003906127108211610d775761271091611deb91611db4565b611dff90600190611db4565b60405163095ea7b360e01b5f9081526001600160a01b03909316600452602483905290929160209060448180875af19260015f5114841615611e6a575b50604052565b60018492941516611e83573b15153d151616915f611e64565b833d5f823e3d90fd5b92916040519163095ea7b360e01b5f5260018060a01b031660045260245260205f60448180875af19260015f5114841615611e6a575060405256fea2646970667358221220be8eb3dd55e5ce3fd48c970ee554e17ef901d3dbf2701d388589d54c6b9b261d64736f6c634300081b0033000000000000000000000000c5c6cb88598203f3652e531dbb1128ff52f386210000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000f6e72db5454dd049d0788e411b06cfaf16853042000000000000000000000000bebc44782c7db0a1a60cb6fe97d0b483032ff1c7000000000000000000000000ed279fdd11ca84beef15af5d39bb4d4bee23f0ca0000000000000000000000004dece678ceceb27446b35c672dc7d61f30bad69e000000000000000000000000390f3595bca2df7d23783dfd126427cceb997bf4
Deployed Bytecode
0x60806040526004361015610011575f80fd5b5f3560e01c806301681a6214610144578063087eb2b41461013f57806316063ec01461013a5780632d7882201461013557806363a6b1da14610130578063703bafd51461012b578063715018a61461012657806379ba5097146101215780637a4b1f561461011c578063877705ee1461011757806389a30271146101125780638da5cb5b1461010d578063c54e44eb14610108578063cf59d56314610103578063d44bd1e5146100fe578063e0bab4c4146100f9578063e30c3978146100f4578063f2fde38b146100ef5763fbfa77cf146100ea575f80fd5b610cbd565b610c4b565b610c23565b610bdf565b610b9b565b610b57565b610b13565b610aec565b610aa8565b610a64565b610a20565b61099b565b610938565b6108f4565b6108b0565b6102ce565b61028a565b610246565b61018f565b600435906001600160a01b038216820361015f57565b5f80fd5b602435906001600160a01b038216820361015f57565b604435906001600160a01b038216820361015f57565b3461015f57602036600319011261015f576101a8610149565b6101b0610d7c565b6040516370a0823160e01b81523060048201526001600160a01b039190911690602081602481855afa908115610237575f91610208575b50806101ef57005b5f54610206926001600160a01b0390911690610d8f565b005b61022a915060203d602011610230575b6102228183610d15565b810190610d3c565b5f6101e7565b503d610218565b610d4b565b5f91031261015f57565b3461015f575f36600319011261015f576040517f000000000000000000000000ed279fdd11ca84beef15af5d39bb4d4bee23f0ca6001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e6001600160a01b03168152602090f35b3461015f5761012036600319011261015f576004356102eb610163565b906102f4610179565b9160643591608435366101041161015f576101043560027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0054146108a15760027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00554211610892576101f48111610883578115610874576001600160a01b03851615610865576001600160a01b03928316927f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f1683811491828015610833575b8015610801575b80156107cf575b801561079d575b1561078f576103fa8430337f000000000000000000000000c5c6cb88598203f3652e531dbb1128ff52f38621610e0c565b6040516370a0823160e01b815230600482015292602084602481895afa938415610237575f9461076e575b506040516370a0823160e01b8152306004820152602081602481875afa908115610237575f9161074f575b506040516370a0823160e01b8152306004820152936001600160a01b037f0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba016602086602481845afa958615610237575f9661072e575b506040516370a0823160e01b8152306004820152926001600160a01b037f000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e169290602085602481875afa948515610237575f9561070d575b506105088a610ec4565b506040516370a0823160e01b815230600482015291602090839060249082905afa801561023757610540925f91610682575b50610d6a565b6040516370a0823160e01b81523060048201529096602082602481865afa801561023757610574925f916106825750610d6a565b6040516370a0823160e01b81523060048201529093602082602481875afa8015610237576105a8925f916106825750610d6a565b93156106a15750506105ba9350611a0a565b6040516370a0823160e01b815230600482015290602082602481875afa8015610237576105ed925f916106825750610d6a565b928310610673576106028361066f9584610d8f565b604080519182526020820184905233917f49c082cd7a2d84c4820fb8ea8b7cd2a0dac8bac51b973cfc358260a859b3c9599190a361065f60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b6040519081529081906020820190565b0390f35b63bb2875c360e01b5f5260045ffd5b61069b915060203d602011610230576102228183610d15565b5f61053a565b88036106b75750506106b292611779565b6105ba565b90919087036106ca57506106b292611407565b907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b03168703610704576106b293611208565b6106b293610f95565b61072791955060203d602011610230576102228183610d15565b935f6104fe565b61074891965060203d602011610230576102228183610d15565b945f6104a6565b610768915060203d602011610230576102228183610d15565b5f610450565b61078891945060203d602011610230576102228183610d15565b925f610425565b6231010160e51b5f5260045ffd5b507f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec76001600160a01b031685146103c9565b507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b031685146103c2565b507f000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e6001600160a01b031685146103bb565b507f0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba06001600160a01b031685146103b4565b630d753d9b60e31b5f5260045ffd5b631f2a200560e01b5f5260045ffd5b63428637bb60e11b5f5260045ffd5b631ab7da6b60e01b5f5260045ffd5b633ee5aeb560e01b5f5260045ffd5b3461015f575f36600319011261015f576040517f000000000000000000000000bebc44782c7db0a1a60cb6fe97d0b483032ff1c76001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f000000000000000000000000c5c6cb88598203f3652e531dbb1128ff52f386216001600160a01b03168152602090f35b3461015f575f36600319011261015f57610950610d7c565b600180546001600160a01b03199081169091555f80549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461015f575f36600319011261015f57600154336001600160a01b0390911603610a0d57600180546001600160a01b03199081169091555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b3461015f575f36600319011261015f576040517f000000000000000000000000f6e72db5454dd049d0788e411b06cfaf168530426001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f000000000000000000000000390f3595bca2df7d23783dfd126427cceb997bf46001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b03168152602090f35b3461015f575f36600319011261015f575f546040516001600160a01b039091168152602090f35b3461015f575f36600319011261015f576040517f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec76001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba06001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f0000000000000000000000004dece678ceceb27446b35c672dc7d61f30bad69e6001600160a01b03168152602090f35b3461015f575f36600319011261015f576040517f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f6001600160a01b03168152602090f35b3461015f575f36600319011261015f576001546040516001600160a01b039091168152602090f35b3461015f57602036600319011261015f57610c64610149565b610c6c610d7c565b60018060a01b0316806bffffffffffffffffffffffff60a01b600154161760015560018060a01b035f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b3461015f575f36600319011261015f576040517f000000000000000000000000c5c6cb88598203f3652e531dbb1128ff52f386216001600160a01b03168152602090f35b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff821117610d3757604052565b610d01565b9081602091031261015f575190565b6040513d5f823e3d90fd5b634e487b7160e01b5f52601160045260245ffd5b91908203918211610d7757565b610d56565b5f546001600160a01b03163303610a0d57565b916040519163a9059cbb60e01b5f5260018060a01b031660045260245260205f60448180865af160015f5114811615610ded575b604091909152155b610dd25750565b635274afe760e01b5f526001600160a01b031660045260245ffd5b6001811516610e03573d15833b15151616610dc3565b503d5f823e3d90fd5b6040516323b872dd60e01b5f9081526001600160a01b039384166004529290931660245260449390935260209060648180865af160015f5114811615610e5d575b6040919091525f60605215610dcb565b6001811516610e03573d15833b15151616610e4d565b9060608282031261015f5780601f8301121561015f5760405191610e98606084610d15565b82906060810192831161015f57905b828210610eb45750505090565b8151815260209182019101610ea7565b5f80916060604051610ed68282610d15565b3690376040516020810191634feb9cbd60e01b83526024820152306044820152606060a4606483013760a48152610f0e60c482610d15565b5190827f000000000000000000000000c5c6cb88598203f3652e531dbb1128ff52f386215af13d15610f8d573d9067ffffffffffffffff8211610d375760405191610f63601f8201601f191660200184610d15565b82523d5f602084013e5b15610f885780602080610f8593518301019101610e73565b90565b611ca5565b606090610f6d565b92919280611144575b5080611079575b5081610faf575050565b6110449160209161100c7f000000000000000000000000390f3595bca2df7d23783dfd126427cceb997bf49161100684847f000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e611cfb565b83611dc7565b915f604051809681958294630f7c084960e21b845260048401606090939291936080810194600182525f602083015260408201520152565b03926001600160a01b03165af180156102375761105e5750565b6110769060203d602011610230576102228183610d15565b50565b602061110d917f000000000000000000000000ed279fdd11ca84beef15af5d39bb4d4bee23f0ca6110cb82827f0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0611cfb565b6110d58583611dc7565b915f604051809681958294635320bf6b60e11b8452600484016060909392919360808101945f82526003602083015260408201520152565b03926001600160a01b03165af180156102375715610fa55761113d9060203d602011610230576102228183610d15565b505f610fa5565b7f000000000000000000000000bebc44782c7db0a1a60cb6fe97d0b483032ff1c761119082827f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f611cfb565b6001600160a01b0316906111a48482611dc7565b823b1561015f57604051630f7c084960e21b81525f600482018190526002602483015260448201939093526064810191909152918290608490829084905af180156102375715610f9e57806111fc5f61120293610d15565b8061023c565b5f610f9e565b92919280611344575b5080611279575b5081611222575050565b6110449160209161100c7f0000000000000000000000004dece678ceceb27446b35c672dc7d61f30bad69e9161100684847f000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e611cfb565b602061130d917f000000000000000000000000ed279fdd11ca84beef15af5d39bb4d4bee23f0ca6112cb82827f0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0611cfb565b6112d58583611dc7565b915f604051809681958294635320bf6b60e11b8452600484016060909392919360808101945f82526002602083015260408201520152565b03926001600160a01b03165af1801561023757156112185761133d9060203d602011610230576102228183610d15565b505f611218565b60206113d08261135a5f9464e8d4a51000900490565b6113a67f000000000000000000000000f6e72db5454dd049d0788e411b06cfaf1685304292837f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f611cfb565b604051638d7ef9bb60e01b8152306004820152602481019190915293849283919082906044820190565b03926001600160a01b03165af180156102375715611211576114009060203d602011610230576102228183610d15565b505f611211565b806115ea575b5080611417575050565b6040516370a0823160e01b81523060048201527f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b038116939192602084602481885afa938415610237575f946115c4575b5060206114cc917f000000000000000000000000ed279fdd11ca84beef15af5d39bb4d4bee23f0ca6114c282827f0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0611cfb565b6112d58683611dc7565b03926001600160a01b03165af18015610237576115a7575b506040516370a0823160e01b815230600482015293602090859060249082905afa80156102375761152560209461155892611044975f916115905750610d6a565b92611552847f0000000000000000000000004dece678ceceb27446b35c672dc7d61f30bad69e8095611cfb565b83611def565b915f604051809681958294630f7c084960e21b8452600484016060909392919360808101945f82526001602083015260408201520152565b61069b9150873d8911610230576102228183610d15565b6115bf9060203d602011610230576102228183610d15565b6114e4565b6114cc9194506115e2602091823d8411610230576102228183610d15565b94915061146f565b6040516370a0823160e01b8152306004820152907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b03811691602084602481865afa938415610237575f94611751575b5060206116588261135a5f9464e8d4a51000900490565b03926001600160a01b03165af1801561023757611734575b506040516370a0823160e01b815230600482015291602090839060249082905afa918215610237576116e6936020936116af925f9161171d5750610d6a565b906116dc827f0000000000000000000000004dece678ceceb27446b35c672dc7d61f30bad69e8093611cfb565b6115588683611def565b03926001600160a01b03165af18015610237571561140d576117169060203d602011610230576102228183610d15565b505f61140d565b61069b9150853d8711610230576102228183610d15565b61174c9060203d602011610230576102228183610d15565b611670565b5f919450611658611770602092833d8511610230576102228183610d15565b95925050611641565b8061193f575b5080611789575050565b6040516370a0823160e01b81523060048201527f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b038116939192602084602481885afa938415610237575f94611919575b50602061183e917f0000000000000000000000004dece678ceceb27446b35c672dc7d61f30bad69e61183482827f000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e611cfb565b61100c8683611dc7565b03926001600160a01b03165af18015610237576118fc575b506040516370a0823160e01b815230600482015293602090859060249082905afa8015610237576118976020946118c492611044975f916115905750610d6a565b92611552847f000000000000000000000000ed279fdd11ca84beef15af5d39bb4d4bee23f0ca8095611cfb565b915f604051809681958294635320bf6b60e11b845260048401606090939291936080810194600282525f602083015260408201520152565b6119149060203d602011610230576102228183610d15565b611856565b61183e919450611937602091823d8411610230576102228183610d15565b9491506117e1565b60206119d3917f000000000000000000000000ed279fdd11ca84beef15af5d39bb4d4bee23f0ca61199182827f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f611cfb565b61199b8683611e1b565b915f604051809681958294635320bf6b60e11b845260048401606090939291936080810194600182525f602083015260408201520152565b03926001600160a01b03165af18015610237571561177f57611a039060203d602011610230576102228183610d15565b505f61177f565b91909180611bda575b5081611a1d575050565b6040516370a0823160e01b81523060048201527f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b038116939192909190602084602481885afa938415610237575f94611bb2575b50611ad09160209161100c7f0000000000000000000000004dece678ceceb27446b35c672dc7d61f30bad69e9161100684847f000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e611cfb565b03926001600160a01b03165af1801561023757611b95575b506040516370a0823160e01b815230600482015292602090849060249082905afa90811561023757611b28602093611044935f968791611b7e5750610d6a565b611b54817f000000000000000000000000f6e72db5454dd049d0788e411b06cfaf168530428094611cfb565b604051634acc893b60e11b8152306004820152602481019190915293849283919082906044820190565b61069b9150863d8811610230576102228183610d15565b611bad9060203d602011610230576102228183610d15565b611ae8565b602091945091611bd1611ad093833d8511610230576102228183610d15565b94915091611a78565b6020611c6e917f000000000000000000000000ed279fdd11ca84beef15af5d39bb4d4bee23f0ca611c2c82827f0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0611cfb565b611c368583611e1b565b915f604051809681958294635320bf6b60e11b8452600484016060909392919360808101945f82526001602083015260408201520152565b03926001600160a01b03165af180156102375715611a1357611c9e9060203d602011610230576102228183610d15565b505f611a13565b8051906004821015611cf65760405162461bcd60e51b815260206004820152601960248201527f5a61704f75743a207661756c742063616c6c206661696c6564000000000000006044820152606490fd5b602001fd5b60405163095ea7b360e01b5f9081526001600160a01b03841660045260248590529193929160209060448180885af19060015f5114821615611da5575b60405215611d4557505050565b611d4f8184611e27565b15611d875790611d5f9183611e8c565b15611d675750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b635274afe760e01b5f9081526001600160a01b038416600452602490fd5b90843b15153d15161690611d38565b81810292918115918404141715610d7757565b64e8d4a5100090049061271003906127108211610d775761271091611deb91611db4565b0490565b611dff9064e8d4a5100090611db4565b9061271003906127108211610d775761271091611deb91611db4565b611dff90600190611db4565b60405163095ea7b360e01b5f9081526001600160a01b03909316600452602483905290929160209060448180875af19260015f5114841615611e6a575b50604052565b60018492941516611e83573b15153d151616915f611e64565b833d5f823e3d90fd5b92916040519163095ea7b360e01b5f5260018060a01b031660045260245260205f60448180875af19260015f5114841615611e6a575060405256fea2646970667358221220be8eb3dd55e5ce3fd48c970ee554e17ef901d3dbf2701d388589d54c6b9b261d64736f6c634300081b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c5c6cb88598203f3652e531dbb1128ff52f386210000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000f6e72db5454dd049d0788e411b06cfaf16853042000000000000000000000000bebc44782c7db0a1a60cb6fe97d0b483032ff1c7000000000000000000000000ed279fdd11ca84beef15af5d39bb4d4bee23f0ca0000000000000000000000004dece678ceceb27446b35c672dc7d61f30bad69e000000000000000000000000390f3595bca2df7d23783dfd126427cceb997bf4
-----Decoded View---------------
Arg [0] : _vault (address): 0xc5c6cB88598203f3652E531dbb1128Ff52F38621
Arg [1] : _dai (address): 0x6B175474E89094C44Da98b954EedeAC495271d0F
Arg [2] : _lusd (address): 0x5f98805A4E8be255a32880FDeC7F6728C6568bA0
Arg [3] : _crvusd (address): 0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E
Arg [4] : _usdc (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [5] : _usdt (address): 0xdAC17F958D2ee523a2206206994597C13D831ec7
Arg [6] : _lightPsm (address): 0xf6e72Db5454dd049d0788e411b06CfAF16853042
Arg [7] : _curve3Pool (address): 0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7
Arg [8] : _curveLusdPool (address): 0xEd279fDD11cA84bEef15AF5D39BB4d4bEE23F0cA
Arg [9] : _curveCrvUsdUsdc (address): 0x4DEcE678ceceb27446b35C672dC7d61F30bAD69E
Arg [10] : _curveCrvUsdUsdt (address): 0x390f3595bCa2Df7d23783dFd126427CCeb997BF4
-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 000000000000000000000000c5c6cb88598203f3652e531dbb1128ff52f38621
Arg [1] : 0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f
Arg [2] : 0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0
Arg [3] : 000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e
Arg [4] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [5] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [6] : 000000000000000000000000f6e72db5454dd049d0788e411b06cfaf16853042
Arg [7] : 000000000000000000000000bebc44782c7db0a1a60cb6fe97d0b483032ff1c7
Arg [8] : 000000000000000000000000ed279fdd11ca84beef15af5d39bb4d4bee23f0ca
Arg [9] : 0000000000000000000000004dece678ceceb27446b35c672dc7d61f30bad69e
Arg [10] : 000000000000000000000000390f3595bca2df7d23783dfd126427cceb997bf4
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.