Source Code
Latest 25 from a total of 1,689 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Forward Withdraw... | 50692745 | 15 hrs ago | IN | 0 MON | 0.19623409 | ||||
| Forward Native W... | 50572593 | 28 hrs ago | IN | 0 MON | 0.17861661 | ||||
| Forward Native W... | 50459437 | 40 hrs ago | IN | 0 MON | 0.15851409 | ||||
| Forward Native W... | 50377737 | 2 days ago | IN | 0 MON | 0.15827051 | ||||
| Forward Deposit ... | 49515679 | 6 days ago | IN | 0 MON | 0.19667466 | ||||
| Forward Native W... | 49514965 | 6 days ago | IN | 0 MON | 0.19637672 | ||||
| Forward Deposit ... | 49514701 | 6 days ago | IN | 0 MON | 0.19746455 | ||||
| Forward Deposit ... | 49309242 | 7 days ago | IN | 0 MON | 0.16942122 | ||||
| Forward Native W... | 49295688 | 7 days ago | IN | 0 MON | 0.23625607 | ||||
| Forward Native W... | 49294836 | 7 days ago | IN | 0 MON | 0.18319606 | ||||
| Forward Deposit ... | 49231843 | 7 days ago | IN | 0 MON | 0.17805528 | ||||
| Forward Deposit ... | 49172678 | 7 days ago | IN | 0 MON | 0.22130215 | ||||
| Forward Deposit ... | 49172158 | 7 days ago | IN | 0 MON | 0.20938192 | ||||
| Forward Native W... | 49172037 | 7 days ago | IN | 0 MON | 0.2257567 | ||||
| Forward Deposit ... | 49168971 | 7 days ago | IN | 0 MON | 0.22132663 | ||||
| Forward Deposit ... | 49168846 | 7 days ago | IN | 0 MON | 0.22866206 | ||||
| Forward Native W... | 49126776 | 7 days ago | IN | 0 MON | 0.1566303 | ||||
| Forward Native W... | 49126756 | 7 days ago | IN | 0 MON | 0.19320076 | ||||
| Forward Native W... | 48919079 | 8 days ago | IN | 0 MON | 0.2366859 | ||||
| Forward Withdraw... | 48892820 | 8 days ago | IN | 0 MON | 0.13039033 | ||||
| Forward Withdraw... | 48892699 | 8 days ago | IN | 0 MON | 0.13039033 | ||||
| Forward Withdraw... | 48890691 | 9 days ago | IN | 0 MON | 0.15185073 | ||||
| Forward Native W... | 48886762 | 9 days ago | IN | 0 MON | 0.15854125 | ||||
| Forward Native W... | 48886680 | 9 days ago | IN | 0 MON | 0.18623231 | ||||
| Forward Native W... | 48857641 | 9 days ago | IN | 0 MON | 0.17522109 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 50815999 | 1 hr ago | 100 MON | ||||
| 50815999 | 1 hr ago | 100 MON | ||||
| 50739924 | 9 hrs ago | 42.85021785 MON | ||||
| 50739924 | 9 hrs ago | 42.85021785 MON | ||||
| 50726472 | 11 hrs ago | 350.21768004 MON | ||||
| 50726472 | 11 hrs ago | 350.21768004 MON | ||||
| 50726442 | 11 hrs ago | 352.43080853 MON | ||||
| 50726442 | 11 hrs ago | 352.43080853 MON | ||||
| 50706173 | 13 hrs ago | 1 MON | ||||
| 50706173 | 13 hrs ago | 1 MON | ||||
| 50690521 | 15 hrs ago | 500 MON | ||||
| 50690521 | 15 hrs ago | 500 MON | ||||
| 50649954 | 19 hrs ago | 3,131.52089066 MON | ||||
| 50649954 | 19 hrs ago | 3,131.52089066 MON | ||||
| 50649924 | 19 hrs ago | 3,131.52089066 MON | ||||
| 50649924 | 19 hrs ago | 3,131.52089066 MON | ||||
| 50649875 | 19 hrs ago | 930 MON | ||||
| 50649875 | 19 hrs ago | 930 MON | ||||
| 50643062 | 20 hrs ago | 332.31156125 MON | ||||
| 50643062 | 20 hrs ago | 332.31156125 MON | ||||
| 50641679 | 20 hrs ago | 800 MON | ||||
| 50641679 | 20 hrs ago | 800 MON | ||||
| 50638611 | 21 hrs ago | 21.41148235 MON | ||||
| 50638611 | 21 hrs ago | 21.41148235 MON | ||||
| 50638466 | 21 hrs ago | 42.81370598 MON |
Loading...
Loading
Contract Name:
ICHIVaultDepositGuard
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.4;
import { IICHIVaultDepositGuard } from "../interfaces/IICHIVaultDepositGuard.sol";
import { IICHIVaultFactory } from "../interfaces/IICHIVaultFactory.sol";
import { IICHIVault } from "../interfaces/IICHIVault.sol";
import { IWRAPPED_NATIVE } from "../interfaces/IWRAPPED_NATIVE.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract ICHIVaultDepositGuard is IICHIVaultDepositGuard, ReentrancyGuard {
using SafeERC20 for IERC20;
address public immutable override ICHIVaultFactory;
address public immutable override WRAPPED_NATIVE;
address private constant NULL_ADDRESS = address(0);
/// @notice Constructs the IICHIVaultDepositGuard contract.
/// @param _ICHIVaultFactory The address of the ICHIVaultFactory.
constructor(address _ICHIVaultFactory, address _WRAPPED_NATIVE) {
require(_ICHIVaultFactory != NULL_ADDRESS, "DG.constructor: zero address");
ICHIVaultFactory = _ICHIVaultFactory;
WRAPPED_NATIVE = _WRAPPED_NATIVE;
emit Deployed(_ICHIVaultFactory, _WRAPPED_NATIVE);
}
receive() external payable {
assert(msg.sender == WRAPPED_NATIVE); // only accept ETH via fallback from the WRAPPED_NATIVE contract
}
/// @inheritdoc IICHIVaultDepositGuard
function forwardDepositToICHIVault(
address vault,
address vaultDeployer,
address token,
uint256 amount,
uint256 minimumProceeds,
address to
) external override nonReentrant returns (uint256 vaultTokens) {
vaultTokens = _forwardDeposit(vault, vaultDeployer, token, amount, minimumProceeds, to, false);
}
/// @inheritdoc IICHIVaultDepositGuard
function forwardNativeDepositToICHIVault(
address vault,
address vaultDeployer,
uint256 minimumProceeds,
address to
) external payable override nonReentrant returns (uint256 vaultTokens) {
uint256 nativeAmount = msg.value;
IWRAPPED_NATIVE(WRAPPED_NATIVE).deposit{ value: nativeAmount }();
vaultTokens = _forwardDeposit(vault, vaultDeployer, WRAPPED_NATIVE, nativeAmount, minimumProceeds, to, true);
}
/// @inheritdoc IICHIVaultDepositGuard
function forwardWithdrawFromICHIVault(
address vault,
address vaultDeployer,
uint256 shares,
address to,
uint256 minAmount0,
uint256 minAmount1
) external override nonReentrant returns (uint256 amount0, uint256 amount1) {
(amount0, amount1) = _forwardWithdraw(vault, vaultDeployer, shares, to, minAmount0, minAmount1, false);
}
/// @inheritdoc IICHIVaultDepositGuard
function forwardNativeWithdrawFromICHIVault(
address vault,
address vaultDeployer,
uint256 shares,
address to,
uint256 minAmount0,
uint256 minAmount1
) external override nonReentrant returns (uint256 amount0, uint256 amount1) {
(amount0, amount1) = _forwardWithdraw(vault, vaultDeployer, shares, to, minAmount0, minAmount1, true);
}
/// @inheritdoc IICHIVaultDepositGuard
function vaultKey(
address vaultDeployer,
address token0,
address token1,
bool allowToken0,
bool allowToken1
) public view override returns (bytes32 key) {
key = IICHIVaultFactory(ICHIVaultFactory).genKey(vaultDeployer, token0, token1, allowToken0, allowToken1);
}
function _forwardDeposit(
address vault,
address vaultDeployer,
address token,
uint256 amount,
uint256 minimumProceeds,
address to,
bool depositNative
) private returns (uint256 vaultTokens) {
_validateRecipient(to);
(IICHIVault ichiVault, address token0, address token1) = _validateVault(vault, vaultDeployer, depositNative);
require(token == token0 || token == token1, "Invalid token");
if (token == token0) {
require(ichiVault.allowToken0(), "Token0 deposits not allowed");
} else {
require(ichiVault.allowToken1(), "Token1 deposits not allowed");
}
// if deposit is a native deposit then we don't need to transfer WRAPPED_NATIVE
// since this contract receives WRAPPED_NATIVE amount on successful WRAPPED_NATIVE#deposit
if (!depositNative) {
IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
}
IERC20(token).safeIncreaseAllowance(vault, amount);
uint256 token0Amount = token == token0 ? amount : 0;
uint256 token1Amount = token == token1 ? amount : 0;
vaultTokens = ichiVault.deposit(token0Amount, token1Amount, to);
require(vaultTokens >= minimumProceeds, "Slippage too great. Try again.");
emit DepositForwarded(msg.sender, vault, token, amount, vaultTokens, to);
}
function _forwardWithdraw(
address vault,
address vaultDeployer,
uint256 shares,
address to,
uint256 minAmount0,
uint256 minAmount1,
bool withdrawNative
) private returns (uint256 amount0, uint256 amount1) {
_validateRecipient(to);
(IICHIVault ichiVault, address token0, address token1) = _validateVault(vault, vaultDeployer, withdrawNative);
// - sender must grant the guard an allowance for the vault share token
// - the guard can then transfer those share tokens to itself
// - the guard then approves the vault an allowance in order to burn shares and withdraw from the vault
IERC20(vault).safeTransferFrom(msg.sender, address(this), shares);
if (withdrawNative) {
// the vault temporarily custodies the withdrawn amounts
(amount0, amount1) = ichiVault.withdraw(shares, address(this));
if (token0 == WRAPPED_NATIVE) {
IWRAPPED_NATIVE(WRAPPED_NATIVE).withdraw(amount0);
payable(to).transfer(amount0);
IERC20(token1).safeTransfer(to, amount1);
} else {
IWRAPPED_NATIVE(WRAPPED_NATIVE).withdraw(amount1);
payable(to).transfer(amount1);
IERC20(token0).safeTransfer(to, amount0);
}
} else {
(amount0, amount1) = ichiVault.withdraw(shares, to);
}
require(amount0 >= minAmount0 && amount1 >= minAmount1, "Insufficient out");
}
function _validateRecipient(address to) private pure {
require(to != NULL_ADDRESS, "Invalid to");
}
function _validateVault(
address vault,
address vaultDeployer,
bool validateNative
) private view returns (IICHIVault ichiVault, address token0, address token1) {
ichiVault = IICHIVault(vault);
token0 = ichiVault.token0();
token1 = ichiVault.token1();
if (validateNative) {
require(token0 == WRAPPED_NATIVE || token1 == WRAPPED_NATIVE, "Native vault");
}
bytes32 factoryVaultKey = vaultKey(
vaultDeployer,
token0,
token1,
ichiVault.allowToken0(),
ichiVault.allowToken1()
);
require(IICHIVaultFactory(ICHIVaultFactory).getICHIVault(factoryVaultKey) == vault, "Invalid vault");
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @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 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].
*/
abstract contract ReentrancyGuard {
// 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;
uint256 private _status;
constructor() {
_status = _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();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _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 _status == _ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface 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 amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 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 {
using Address for address;
/**
* @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 {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @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 {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @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.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), 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 data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), 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 data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.4;
interface IICHIVault {
function ichiVaultFactory() external view returns (address);
function pool() external view returns (address);
function token0() external view returns (address);
function allowToken0() external view returns (bool);
function token1() external view returns (address);
function allowToken1() external view returns (bool);
function fee() external view returns (uint24);
function tickSpacing() external view returns (int24);
function ammFeeRecipient() external view returns(address);
function farmingContract() external view returns(address);
function affiliate() external view returns (address);
function baseLower() external view returns (int24);
function baseUpper() external view returns (int24);
function limitLower() external view returns (int24);
function limitUpper() external view returns (int24);
/// @notice NFT ID of the base position. If 0, the base position is not initialized.
function basePositionId() external view returns (uint256);
/// @notice NFT ID of the limit position. If 0, the limit position is not initialized.
function limitPositionId() external view returns (uint256);
function deposit0Max() external view returns (uint256);
function deposit1Max() external view returns (uint256);
function hysteresis() external view returns (uint256);
function twapPeriod() external view returns (uint32);
function auxTwapPeriod() external view returns (uint32);
function getTotalAmounts() external view returns (uint256, uint256);
function getBasePosition() external view returns (uint128, uint256, uint256);
function getLimitPosition() external view returns (uint128, uint256, uint256);
function deposit(uint256, uint256, address) external returns (uint256);
function withdraw(uint256, address) external returns (uint256, uint256);
function currentTick() external view returns (int24);
function resetAllowances() external;
function collectRewards() external;
function rebalance(
int24 _baseLower,
int24 _baseUpper,
int24 _limitLower,
int24 _limitUpper,
int256 swapQuantity
) external;
function collectFees() external returns (uint256 fees0, uint256 fees1);
function setDepositMax(uint256 _deposit0Max, uint256 _deposit1Max) external;
function setHysteresis(uint256 _hysteresis) external;
function setAmmFeeRecipient(address _ammFeeRecipient) external;
function setAffiliate(address _affiliate) external;
function setTwapPeriod(uint32 newTwapPeriod) external;
function setAuxTwapPeriod(uint32 newAuxTwapPeriod) external;
function setFarmingContract(address _farmingContract) external;
event DeployICHIVault(
address indexed sender,
address indexed pool,
bool allowToken0,
bool allowToken1,
address owner,
uint256 twapPeriod
);
event SetTwapPeriod(address sender, uint32 newTwapPeriod);
event SetAuxTwapPeriod(address sender, uint32 newAuxTwapPeriod);
event Deposit(
address indexed sender,
address indexed to,
uint256 shares,
uint256 amount0,
uint256 amount1,
// --- Added state data ---
address pool, // Pool address
uint256 totalAmount0, // Total vault amount0 after deposit
uint256 totalAmount1, // Total vault amount1 after deposit
uint256 totalSupply, // Total vault shares after deposit
int24 currentTick, // Current pool tick
uint160 sqrtPriceX96 // Current pool sqrt price
);
event Withdraw(
address indexed sender,
address indexed to,
uint256 shares,
uint256 amount0,
uint256 amount1,
// --- Added state data ---
address pool, // Pool address
uint256 totalAmount0, // Total vault amount0 after withdraw
uint256 totalAmount1, // Total vault amount1 after withdraw
uint256 totalSupply, // Total vault shares after withdraw
int24 currentTick, // Current pool tick
uint160 sqrtPriceX96 // Current pool sqrt price
);
event Rebalance(
int24 tick,
uint256 totalAmount0,
uint256 totalAmount1,
uint256 feeAmount0,
uint256 feeAmount1,
uint256 totalSupply,
// --- Added state data ---
address pool, // Pool address
uint160 sqrtPriceX96 // Current pool sqrt price
);
event CollectFees(
address indexed sender,
uint256 feeAmount0,
uint256 feeAmount1,
// --- Added state data ---
address pool, // Pool address
uint256 totalSupply, // Vault total supply
int24 currentTick, // Current tick from pool
uint256 totalAmount0, // Vault total amount0
uint256 totalAmount1, // Vault total amount1
uint160 sqrtPriceX96 // Sqrt price from pool
);
event RewardsCollected(uint256 reward, uint256 bonusReward);
event Hysteresis(address indexed sender, uint256 hysteresis);
event DepositMax(address indexed sender, uint256 deposit0Max, uint256 deposit1Max);
// event AmmFeeRecipient(address indexed sender, address ammFeeRecipient);
event Affiliate(address indexed sender, address affiliate);
event FarmingContract(address indexed sender, address farmingContract);
event VaultTransfer(
address indexed from,
address indexed to,
uint256 value,
address pool, // Pool address
uint256 totalSupply, // Vault total supply
int24 currentTick, // Current tick from pool
uint256 totalAmount0, // Vault total amount0
uint256 totalAmount1, // Vault total amount1
uint160 sqrtPriceX96 // Sqrt price from pool
);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.4;
interface IICHIVaultDepositGuard {
/// @notice Emitted when the contract is deployed.
/// @param _ICHIVaultFactory Address of the ICHIVaultFactory.
/// @param _WETH Address of the Wrapped ETH token.
event Deployed(address _ICHIVaultFactory, address _WETH);
/// @notice Emitted when a deposit is forwarded to an ICHIVault.
/// @param sender The address initiating the deposit.
/// @param vault The ICHIVault receiving the deposit.
/// @param token The token being deposited.
/// @param amount The amount of the token being deposited.
/// @param shares The amount of shares issued in the vault as a result of the deposit.
/// @param to The address receiving the vault shares.
event DepositForwarded(
address indexed sender,
address indexed vault,
address indexed token,
uint256 amount,
uint256 shares,
address to
);
/// @notice Retrieves the address of the ICHIVaultFactory.
/// @return Address of the ICHIVaultFactory.
function ICHIVaultFactory() external view returns (address);
/// @notice Retrieves the address of the Wrapped Native Token (e.g., WETH).
/// @return Address of the Wrapped Native Token.
function WRAPPED_NATIVE() external view returns (address);
/// @notice Forwards a deposit to the specified ICHIVault after input validation.
/// @dev Emits a DepositForwarded event upon success.
/// @param vault The address of the ICHIVault to deposit into.
/// @param vaultDeployer The address of the vault deployer.
/// @param token The address of the token being deposited.
/// @param amount The amount of the token being deposited.
/// @param minimumProceeds The minimum amount of vault tokens to be received.
/// @param to The address to receive the vault tokens.
/// @return vaultTokens The number of vault tokens received.
function forwardDepositToICHIVault(
address vault,
address vaultDeployer,
address token,
uint256 amount,
uint256 minimumProceeds,
address to
) external returns (uint256 vaultTokens);
/// @notice Forwards a native currency (e.g., ETH) deposit to an ICHIVault.
/// @dev Converts the native currency to Wrapped Native Token before deposit.
/// @param vault The address of the ICHIVault to deposit into.
/// @param vaultDeployer The address of the vault deployer.
/// @param minimumProceeds The minimum amount of vault tokens to be received.
/// @param to The address to receive the vault tokens.
/// @return vaultTokens The number of vault tokens received.
function forwardNativeDepositToICHIVault(
address vault,
address vaultDeployer,
uint256 minimumProceeds,
address to
) external payable returns (uint256 vaultTokens);
/// @notice Forwards a request to withdraw from an ICHIVault.
/// @param vault The address of the ICHIVault to withdraw from.
/// @param vaultDeployer The address of the vault deployer.
/// @param shares The amount of shares to withdraw.
/// @param to The address to receive the withdrawn tokens.
/// @param minAmount0 The minimum amount of token0 expected to receive.
/// @param minAmount1 The minimum amount of token1 expected to receive.
/// @return amount0 The amount of token0 received.
/// @return amount1 The amount of token1 received.
function forwardWithdrawFromICHIVault(
address vault,
address vaultDeployer,
uint256 shares,
address to,
uint256 minAmount0,
uint256 minAmount1
) external returns (uint256 amount0, uint256 amount1);
/// @notice Forwards a request to withdraw native currency from an ICHIVault.
/// @dev Converts the Wrapped Native Tokens back to native currency on withdrawal.
/// @param vault The address of the ICHIVault to withdraw from.
/// @param vaultDeployer The address of the vault deployer.
/// @param shares The amount of shares to withdraw.
/// @param to The address to receive the withdrawn native currency.
/// @param minAmount0 The minimum amount of token0 expected to receive.
/// @param minAmount1 The minimum amount of token1 expected to receive.
/// @return amount0 The amount of token0 received.
/// @return amount1 The amount of token1 received.
function forwardNativeWithdrawFromICHIVault(
address vault,
address vaultDeployer,
uint256 shares,
address to,
uint256 minAmount0,
uint256 minAmount1
) external returns (uint256 amount0, uint256 amount1);
/// @notice Computes the unique key for a vault based on given parameters.
/// @param vaultDeployer The address of the vault deployer.
/// @param token0 The address of the first token in the vault.
/// @param token1 The address of the second token in the vault.
/// @param allowToken0 Boolean indicating if token0 is allowed in the vault.
/// @param allowToken1 Boolean indicating if token1 is allowed in the vault.
/// @return key The computed unique key for the vault.
function vaultKey(
address vaultDeployer,
address token0,
address token1,
bool allowToken0,
bool allowToken1
) external view returns (bytes32 key);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.4;
interface IICHIVaultFactory {
event FeeRecipient(address indexed sender, address feeRecipient);
event AmmFee(address indexed sender, uint256 ammFee);
event BaseFee(address indexed sender, uint256 baseFee);
event BaseFeeSplit(address indexed sender, uint256 baseFeeSplit);
event DeployICHIVaultFactory(address indexed sender, address algebraFactory);
event ICHIVaultCreated(
address indexed sender,
address indexed ichiVault,
address tokenA,
address tokenB,
bool allowTokenA,
bool allowTokenB,
uint256 count,
uint24 fee,
address token0,
address token1,
uint8 decimals0,
uint8 decimals1
);
function getICHIVault(bytes32 vaultKey) external view returns(address);
function algebraFactory() external view returns (address);
function nftManager() external view returns (address);
function farmingCenter() external view returns (address);
function incentiveMaker() external view returns (address);
function ammName() external view returns (string memory);
function feeRecipient() external view returns (address);
function ammFee() external view returns (uint256);
function baseFee() external view returns (uint256);
function baseFeeSplit() external view returns (uint256);
function setFeeRecipient(address _feeRecipient) external;
function setAmmFee(uint256 _ammFee) external;
function setBaseFee(uint256 _baseFee) external;
function setBaseFeeSplit(uint256 _baseFeeSplit) external;
function createICHIVault(
address tokenA,
bool allowTokenA,
address tokenB,
bool allowTokenB
) external returns (address ichiVault);
function genKey(
address deployer,
address token0,
address token1,
bool allowToken0,
bool allowToken1
) external pure returns (bytes32 key);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.4;
interface IWRAPPED_NATIVE {
function deposit() external payable;
function transfer(address to, uint value) external returns (bool);
function withdraw(uint) external;
}{
"metadata": {
"bytecodeHash": "none"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"viaIR": true,
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_ICHIVaultFactory","type":"address"},{"internalType":"address","name":"_WRAPPED_NATIVE","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_ICHIVaultFactory","type":"address"},{"indexed":false,"internalType":"address","name":"_WETH","type":"address"}],"name":"Deployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"DepositForwarded","type":"event"},{"inputs":[],"name":"ICHIVaultFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WRAPPED_NATIVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"vaultDeployer","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minimumProceeds","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"forwardDepositToICHIVault","outputs":[{"internalType":"uint256","name":"vaultTokens","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"vaultDeployer","type":"address"},{"internalType":"uint256","name":"minimumProceeds","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"forwardNativeDepositToICHIVault","outputs":[{"internalType":"uint256","name":"vaultTokens","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"vaultDeployer","type":"address"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"minAmount0","type":"uint256"},{"internalType":"uint256","name":"minAmount1","type":"uint256"}],"name":"forwardNativeWithdrawFromICHIVault","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"vaultDeployer","type":"address"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"minAmount0","type":"uint256"},{"internalType":"uint256","name":"minAmount1","type":"uint256"}],"name":"forwardWithdrawFromICHIVault","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vaultDeployer","type":"address"},{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"bool","name":"allowToken0","type":"bool"},{"internalType":"bool","name":"allowToken1","type":"bool"}],"name":"vaultKey","outputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60c034610132576117a390601f38839003908101601f19168201906001600160401b03821183831017610137578083916040958694855283398101031261013257610055602061004e8361014d565b920161014d565b60016000556001600160a01b038281169290919083156100ee5760805260a081905283519283521660208201527f09e48df7857bd0c1e0d31bb8a85d42cf1874817895f171c917f6ee2cea73ec20908290a15161164190816101628239608051818181610c5401528181610eec015261137d015260a051818181601f0152818160d10152818161014101528181610623015261152a0152f35b845162461bcd60e51b815260206004820152601c60248201527f44472e636f6e7374727563746f723a207a65726f2061646472657373000000006044820152606490fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b03821682036101325756fe60406080815260049081361015610064575b50361561001d57600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361004f57005b600190634e487b7160e01b6000525260246000fd5b600090813560e01c80631a0e8cdf14610c8357806356e6004b14610c405780635d123e3f14610875578063770b2479146108155780638f44f0ee146105915780639b6470e3146101045763d999984d146100be5750610011565b34610100578160031936011261010057517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5080fd5b50608036600319011261010057610119610d6f565b91610122610d8a565b6001600160a01b03606435818116810361058d5761013e610e00565b817f00000000000000000000000000000000000000000000000000000000000000001692833b15610589578551630d0e30db60e41b815285818a8134895af1801561057f57610568575b5061019d839161019784611241565b886114c4565b91921685149384801561055d575b1561052a5784156104a0578751631fde87bb60e21b81526020818c818786165afa90811561049557600091610467575b5015610424575b875194636eb1769f60e11b8652308b870152818a169586602482015260209a8b826044818c5afa918215610419576000926103ea575b503482018092116103d5578a5163095ea7b360e01b818e01526001600160a01b0390911660248201526044810191909152999a6102d49a90948c94879491939092600092919061027f9061027981606481015b03601f198101835282610e80565b8c610fcd565b829083146103cf575034925b818391168b1483146103c9575034925b8c51638dbdbe6d60e01b815288810191825260208201949094526001600160a01b039095166040860152919b8c94859391849160600190565b0393165af19687156103be5760009761038c575b50604435871061034957508451348152602081018790526001600160a01b03909116604082015260019392919033907f425e9f077f9db249ef795bd139f30608e86b0b6c06f049e167ddee551b8c891d9080606081015b0390a45551908152f35b855162461bcd60e51b8152908101889052601e60248201527f536c69707061676520746f6f2067726561742e2054727920616761696e2e00006044820152606490fd5b90968882813d83116103b7575b6103a38183610e80565b810103126103b457505195386102e8565b80fd5b503d610399565b86513d6000823e3d90fd5b9261029b565b9261028b565b60118d634e487b7160e01b6000525260246000fd5b90918c82813d8311610412575b6104018183610e80565b810103126103b45750519038610218565b503d6103f7565b8b513d6000823e3d90fd5b875162461bcd60e51b81526020818c0152601b60248201527f546f6b656e30206465706f73697473206e6f7420616c6c6f77656400000000006044820152606490fd5b610488915060203d811161048e575b6104808183610e80565b810190610f5a565b386101db565b503d610476565b89513d6000823e3d90fd5b875162df906d60e61b81526020818c818786165afa9081156104955760009161050c575b506101e257875162461bcd60e51b81526020818c0152601b60248201527f546f6b656e31206465706f73697473206e6f7420616c6c6f77656400000000006044820152606490fd5b610524915060203d811161048e576104808183610e80565b386104c4565b875162461bcd60e51b81526020818c0152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606490fd5b5080821686146101ab565b83919561057761019d92610e56565b959150610188565b87513d88823e3d90fd5b8480fd5b8380fd5b50913461010057610607916105c991846105aa36610db6565b9591936105ba9991959399610e00565b6105c385611241565b836114c4565b9290996105e38160018060a01b0396309088339116610f72565b8151627b8a6760e11b81528981019182523060208301529b8c918291604090910190565b03818b878196165af198891561080b57889a899a6107d6575b507f0000000000000000000000000000000000000000000000000000000000000000841690841680820361073e5750803b1561010057818b60248a8f8490519586948593632e1a7d4d60e01b85528401525af1801561073457908291610720575b50808b8015610716575b828092918192888a1690f11561070b57509187916106a99316611200565b8510159081610700575b50156106ca57506001905582519182526020820152f35b606490602086519162461bcd60e51b8352820152601060248201526f125b9cdd59999a58da595b9d081bdd5d60821b6044820152fd5b9050831015386106b3565b8a51903d90823e3d90fd5b6108fc915061068b565b61072990610e56565b6103b4578038610681565b8c513d84823e3d90fd5b93919250803b156107d257888a60248a8f8490519586948593632e1a7d4d60e01b85528401525af180156107c857908a9392916107b5575b50818080948193829082156107ab575b891690f1156107a0575061079b918891611200565b6106a9565b8951903d90823e3d90fd5b6108fc9150610786565b6107c0919250610e56565b879038610776565b8c513d8b823e3d90fd5b8880fd5b9099506107fa919a508b3d8d11610804575b6107f28183610e80565b8101906111ea565b9990999838610620565b503d6107e8565b8b513d8a823e3d90fd5b50346101005760a03660031901126101005761082f610d6f565b610837610d8a565b61083f610da0565b90606435928315158403610871576084359586151587036103b457509161086a939160209693610ea2565b9051908152f35b8580fd5b50346101005760c03660031901126101005761088f610d6f565b90610898610d8a565b926108a1610da0565b60a435946001600160a01b039060643590828816880361058957826108d881926108c9610e00565b6108d28b611241565b896112a2565b9291939096169516851493848015610c35575b15610c02578415610b79578751631fde87bb60e21b81526020818d818786165afa908115610b6f578891610b51575b5015610b0e575b61092d84303389610f72565b875194636eb1769f60e11b8652308c870152818a169586602482015260209a8b826044818c5afa918215610b04578a92610ad1575b50868201809211610abd578a5163095ea7b360e01b818e01526001600160a01b03909116602482015260448101919091529a9b999a610a039a948c948e94919390928b9291906109b990610279816064810161026b565b15610ab5578088935b168a03610aae578b51638dbdbe6d60e01b8152878101938452602084018990526001600160a01b03959095166040840152939b8c9485939091849160600190565b0393165af1968715610aa4578597610a75575b50608435871061034957508451908152602081018690526001600160a01b0390971660408801529495939492936001939033907f425e9f077f9db249ef795bd139f30608e86b0b6c06f049e167ddee551b8c891d90806060810161033f565b9096508781813d8311610a9d575b610a8d8183610e80565b8101031261058957519538610a16565b503d610a83565b86513d87823e3d90fd5b819261029b565b8082936109c2565b50634e487b7160e01b895260118d52602489fd5b9091508b81813d8311610afd575b610ae98183610e80565b81010312610af957519038610962565b8980fd5b503d610adf565b8b513d8c823e3d90fd5b875162461bcd60e51b81526020818d0152601b60248201527f546f6b656e30206465706f73697473206e6f7420616c6c6f77656400000000006044820152606490fd5b610b69915060203d811161048e576104808183610e80565b3861091a565b89513d8a823e3d90fd5b875162df906d60e61b81526020818d818786165afa908115610b6f578891610be4575b5061092157875162461bcd60e51b81526020818d0152601b60248201527f546f6b656e31206465706f73697473206e6f7420616c6c6f77656400000000006044820152606490fd5b610bfc915060203d811161048e576104808183610e80565b38610b9c565b875162461bcd60e51b81526020818d0152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606490fd5b5080821686146108eb565b5034610100578160031936011261010057517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5091346101005781610cbb91610d0a9385610c9d36610db6565b96919493610cac9a919a610e00565b610cb586611241565b846112a2565b5090936001600160a01b039150610cd9908490309033908516610f72565b8551627b8a6760e11b81528881019384526001600160a01b03909516602084015293998a9485939091849160400190565b0393165af1938415610d655783958495610d40575b5085101590816107005750156106ca57506001905582519182526020820152f35b909450610d5b919550863d8811610804576107f28183610e80565b9490949338610d1f565b86513d85823e3d90fd5b600435906001600160a01b0382168203610d8557565b600080fd5b602435906001600160a01b0382168203610d8557565b604435906001600160a01b0382168203610d8557565b60c0906003190112610d85576001600160a01b03906004358281168103610d8557916024358181168103610d855791604435916064359081168103610d8557906084359060a43590565b600260005414610e11576002600055565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b67ffffffffffffffff8111610e6a57604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff821117610e6a57604052565b6040516306a5272960e11b81526001600160a01b039182166004820152918116602483015291821660448201529115156064830152911515608482015290602090829060a49082907f0000000000000000000000000000000000000000000000000000000000000000165afa908115610f4e57600091610f20575090565b906020823d8211610f46575b81610f3960209383610e80565b810103126103b457505190565b3d9150610f2c565b6040513d6000823e3d90fd5b90816020910312610d8557518015158103610d855790565b6040516323b872dd60e01b60208201526001600160a01b03928316602482015292909116604483015260648083019390935291815260a081019181831067ffffffffffffffff841117610e6a57610fcb92604052610fcd565b565b6040805167ffffffffffffffff94936001600160a01b03909316929091820185811183821017610e6a576040526020928383527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564848401526000808386829551910182855af1903d15611109573d9687116110f55761106d9495966040519061105f88601f19601f8401160183610e80565b81528093873d92013e611116565b8051908282159283156110dd575b505050156110865750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b6110ed9350820181019101610f5a565b38828161107b565b634e487b7160e01b83526041600452602483fd5b915061106d939495506060915b91929015611178575081511561112a575090565b3b156111335790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b82519091501561118b5750805190602001fd5b6040519062461bcd60e51b82528160208060048301528251908160248401526000935b8285106111d1575050604492506000838284010152601f80199101168101030190fd5b84810182015186860160440152938101938593506111ae565b9190826040910312610d85576020825192015190565b60405163a9059cbb60e01b60208201526001600160a01b03929092166024830152604480830193909352918152610fcb9161123c606483610e80565b610fcd565b6001600160a01b03161561125157565b60405162461bcd60e51b815260206004820152600a602482015269496e76616c696420746f60b01b6044820152606490fd5b90816020910312610d8557516001600160a01b0381168103610d855790565b60408051630dfe168160e01b81526001600160a01b0392831694909392909160049160209190828785818b5afa9687156114b95760009761149a575b50815163d21220a760e01b815287848287818d5afa91821561148f5790869291600092611470575b508198868c875195868092631fde87bb60e21b82525afa9384156103be57908894939291600094611451575b50878d88519687809262df906d60e61b82525afa94851561144657906113649594939291600095611427575b50610ea2565b825190635030961560e01b8252858201528381602481857f0000000000000000000000000000000000000000000000000000000000000000165afa90811561141c57908992916000916113ef575b5016036113be57505050565b5162461bcd60e51b815291820152600d60248201526c125b9d985b1a59081d985d5b1d609a1b604482015260649150fd5b61140f9150853d8711611415575b6114078183610e80565b810190611283565b386113b2565b503d6113fd565b83513d6000823e3d90fd5b61143f919550893d8b1161048e576104808183610e80565b933861135e565b87513d6000823e3d90fd5b611469919450883d8a1161048e576104808183610e80565b9238611332565b611488919250863d8811611415576114078183610e80565b9038611306565b84513d6000823e3d90fd5b6114b2919750833d8511611415576114078183610e80565b95386112de565b82513d6000823e3d90fd5b60408051630dfe168160e01b81526001600160a01b0392831694909392909160049160209190828785818b5afa9687156114b957600097611615575b50815163d21220a760e01b815287848287818d5afa91821561148f576000926115f6575b508197837f00000000000000000000000000000000000000000000000000000000000000001680858416149081156115ea575b50156115b8578451631fde87bb60e21b8152929190868489818f5afa9384156103be579088949392916000946114515750878d88519687809262df906d60e61b82525afa948515611446579061136495949392916000956114275750610ea2565b845162461bcd60e51b8152808801879052600c60248201526b13985d1a5d99481d985d5b1d60a21b6044820152606490fd5b90508484161438611557565b61160e919250853d8711611415576114078183610e80565b9038611524565b61162d919750833d8511611415576114078183610e80565b953861150056fea164736f6c6343000814000a000000000000000000000000a6ceef2a9b7b080f62ea2f73f2271214f0d928f80000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a
Deployed Bytecode
0x60406080815260049081361015610064575b50361561001d57600080fd5b7f0000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a6001600160a01b0316330361004f57005b600190634e487b7160e01b6000525260246000fd5b600090813560e01c80631a0e8cdf14610c8357806356e6004b14610c405780635d123e3f14610875578063770b2479146108155780638f44f0ee146105915780639b6470e3146101045763d999984d146100be5750610011565b34610100578160031936011261010057517f0000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a6001600160a01b03168152602090f35b5080fd5b50608036600319011261010057610119610d6f565b91610122610d8a565b6001600160a01b03606435818116810361058d5761013e610e00565b817f0000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a1692833b15610589578551630d0e30db60e41b815285818a8134895af1801561057f57610568575b5061019d839161019784611241565b886114c4565b91921685149384801561055d575b1561052a5784156104a0578751631fde87bb60e21b81526020818c818786165afa90811561049557600091610467575b5015610424575b875194636eb1769f60e11b8652308b870152818a169586602482015260209a8b826044818c5afa918215610419576000926103ea575b503482018092116103d5578a5163095ea7b360e01b818e01526001600160a01b0390911660248201526044810191909152999a6102d49a90948c94879491939092600092919061027f9061027981606481015b03601f198101835282610e80565b8c610fcd565b829083146103cf575034925b818391168b1483146103c9575034925b8c51638dbdbe6d60e01b815288810191825260208201949094526001600160a01b039095166040860152919b8c94859391849160600190565b0393165af19687156103be5760009761038c575b50604435871061034957508451348152602081018790526001600160a01b03909116604082015260019392919033907f425e9f077f9db249ef795bd139f30608e86b0b6c06f049e167ddee551b8c891d9080606081015b0390a45551908152f35b855162461bcd60e51b8152908101889052601e60248201527f536c69707061676520746f6f2067726561742e2054727920616761696e2e00006044820152606490fd5b90968882813d83116103b7575b6103a38183610e80565b810103126103b457505195386102e8565b80fd5b503d610399565b86513d6000823e3d90fd5b9261029b565b9261028b565b60118d634e487b7160e01b6000525260246000fd5b90918c82813d8311610412575b6104018183610e80565b810103126103b45750519038610218565b503d6103f7565b8b513d6000823e3d90fd5b875162461bcd60e51b81526020818c0152601b60248201527f546f6b656e30206465706f73697473206e6f7420616c6c6f77656400000000006044820152606490fd5b610488915060203d811161048e575b6104808183610e80565b810190610f5a565b386101db565b503d610476565b89513d6000823e3d90fd5b875162df906d60e61b81526020818c818786165afa9081156104955760009161050c575b506101e257875162461bcd60e51b81526020818c0152601b60248201527f546f6b656e31206465706f73697473206e6f7420616c6c6f77656400000000006044820152606490fd5b610524915060203d811161048e576104808183610e80565b386104c4565b875162461bcd60e51b81526020818c0152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606490fd5b5080821686146101ab565b83919561057761019d92610e56565b959150610188565b87513d88823e3d90fd5b8480fd5b8380fd5b50913461010057610607916105c991846105aa36610db6565b9591936105ba9991959399610e00565b6105c385611241565b836114c4565b9290996105e38160018060a01b0396309088339116610f72565b8151627b8a6760e11b81528981019182523060208301529b8c918291604090910190565b03818b878196165af198891561080b57889a899a6107d6575b507f0000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a841690841680820361073e5750803b1561010057818b60248a8f8490519586948593632e1a7d4d60e01b85528401525af1801561073457908291610720575b50808b8015610716575b828092918192888a1690f11561070b57509187916106a99316611200565b8510159081610700575b50156106ca57506001905582519182526020820152f35b606490602086519162461bcd60e51b8352820152601060248201526f125b9cdd59999a58da595b9d081bdd5d60821b6044820152fd5b9050831015386106b3565b8a51903d90823e3d90fd5b6108fc915061068b565b61072990610e56565b6103b4578038610681565b8c513d84823e3d90fd5b93919250803b156107d257888a60248a8f8490519586948593632e1a7d4d60e01b85528401525af180156107c857908a9392916107b5575b50818080948193829082156107ab575b891690f1156107a0575061079b918891611200565b6106a9565b8951903d90823e3d90fd5b6108fc9150610786565b6107c0919250610e56565b879038610776565b8c513d8b823e3d90fd5b8880fd5b9099506107fa919a508b3d8d11610804575b6107f28183610e80565b8101906111ea565b9990999838610620565b503d6107e8565b8b513d8a823e3d90fd5b50346101005760a03660031901126101005761082f610d6f565b610837610d8a565b61083f610da0565b90606435928315158403610871576084359586151587036103b457509161086a939160209693610ea2565b9051908152f35b8580fd5b50346101005760c03660031901126101005761088f610d6f565b90610898610d8a565b926108a1610da0565b60a435946001600160a01b039060643590828816880361058957826108d881926108c9610e00565b6108d28b611241565b896112a2565b9291939096169516851493848015610c35575b15610c02578415610b79578751631fde87bb60e21b81526020818d818786165afa908115610b6f578891610b51575b5015610b0e575b61092d84303389610f72565b875194636eb1769f60e11b8652308c870152818a169586602482015260209a8b826044818c5afa918215610b04578a92610ad1575b50868201809211610abd578a5163095ea7b360e01b818e01526001600160a01b03909116602482015260448101919091529a9b999a610a039a948c948e94919390928b9291906109b990610279816064810161026b565b15610ab5578088935b168a03610aae578b51638dbdbe6d60e01b8152878101938452602084018990526001600160a01b03959095166040840152939b8c9485939091849160600190565b0393165af1968715610aa4578597610a75575b50608435871061034957508451908152602081018690526001600160a01b0390971660408801529495939492936001939033907f425e9f077f9db249ef795bd139f30608e86b0b6c06f049e167ddee551b8c891d90806060810161033f565b9096508781813d8311610a9d575b610a8d8183610e80565b8101031261058957519538610a16565b503d610a83565b86513d87823e3d90fd5b819261029b565b8082936109c2565b50634e487b7160e01b895260118d52602489fd5b9091508b81813d8311610afd575b610ae98183610e80565b81010312610af957519038610962565b8980fd5b503d610adf565b8b513d8c823e3d90fd5b875162461bcd60e51b81526020818d0152601b60248201527f546f6b656e30206465706f73697473206e6f7420616c6c6f77656400000000006044820152606490fd5b610b69915060203d811161048e576104808183610e80565b3861091a565b89513d8a823e3d90fd5b875162df906d60e61b81526020818d818786165afa908115610b6f578891610be4575b5061092157875162461bcd60e51b81526020818d0152601b60248201527f546f6b656e31206465706f73697473206e6f7420616c6c6f77656400000000006044820152606490fd5b610bfc915060203d811161048e576104808183610e80565b38610b9c565b875162461bcd60e51b81526020818d0152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606490fd5b5080821686146108eb565b5034610100578160031936011261010057517f000000000000000000000000a6ceef2a9b7b080f62ea2f73f2271214f0d928f86001600160a01b03168152602090f35b5091346101005781610cbb91610d0a9385610c9d36610db6565b96919493610cac9a919a610e00565b610cb586611241565b846112a2565b5090936001600160a01b039150610cd9908490309033908516610f72565b8551627b8a6760e11b81528881019384526001600160a01b03909516602084015293998a9485939091849160400190565b0393165af1938415610d655783958495610d40575b5085101590816107005750156106ca57506001905582519182526020820152f35b909450610d5b919550863d8811610804576107f28183610e80565b9490949338610d1f565b86513d85823e3d90fd5b600435906001600160a01b0382168203610d8557565b600080fd5b602435906001600160a01b0382168203610d8557565b604435906001600160a01b0382168203610d8557565b60c0906003190112610d85576001600160a01b03906004358281168103610d8557916024358181168103610d855791604435916064359081168103610d8557906084359060a43590565b600260005414610e11576002600055565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b67ffffffffffffffff8111610e6a57604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff821117610e6a57604052565b6040516306a5272960e11b81526001600160a01b039182166004820152918116602483015291821660448201529115156064830152911515608482015290602090829060a49082907f000000000000000000000000a6ceef2a9b7b080f62ea2f73f2271214f0d928f8165afa908115610f4e57600091610f20575090565b906020823d8211610f46575b81610f3960209383610e80565b810103126103b457505190565b3d9150610f2c565b6040513d6000823e3d90fd5b90816020910312610d8557518015158103610d855790565b6040516323b872dd60e01b60208201526001600160a01b03928316602482015292909116604483015260648083019390935291815260a081019181831067ffffffffffffffff841117610e6a57610fcb92604052610fcd565b565b6040805167ffffffffffffffff94936001600160a01b03909316929091820185811183821017610e6a576040526020928383527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564848401526000808386829551910182855af1903d15611109573d9687116110f55761106d9495966040519061105f88601f19601f8401160183610e80565b81528093873d92013e611116565b8051908282159283156110dd575b505050156110865750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b6110ed9350820181019101610f5a565b38828161107b565b634e487b7160e01b83526041600452602483fd5b915061106d939495506060915b91929015611178575081511561112a575090565b3b156111335790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b82519091501561118b5750805190602001fd5b6040519062461bcd60e51b82528160208060048301528251908160248401526000935b8285106111d1575050604492506000838284010152601f80199101168101030190fd5b84810182015186860160440152938101938593506111ae565b9190826040910312610d85576020825192015190565b60405163a9059cbb60e01b60208201526001600160a01b03929092166024830152604480830193909352918152610fcb9161123c606483610e80565b610fcd565b6001600160a01b03161561125157565b60405162461bcd60e51b815260206004820152600a602482015269496e76616c696420746f60b01b6044820152606490fd5b90816020910312610d8557516001600160a01b0381168103610d855790565b60408051630dfe168160e01b81526001600160a01b0392831694909392909160049160209190828785818b5afa9687156114b95760009761149a575b50815163d21220a760e01b815287848287818d5afa91821561148f5790869291600092611470575b508198868c875195868092631fde87bb60e21b82525afa9384156103be57908894939291600094611451575b50878d88519687809262df906d60e61b82525afa94851561144657906113649594939291600095611427575b50610ea2565b825190635030961560e01b8252858201528381602481857f000000000000000000000000a6ceef2a9b7b080f62ea2f73f2271214f0d928f8165afa90811561141c57908992916000916113ef575b5016036113be57505050565b5162461bcd60e51b815291820152600d60248201526c125b9d985b1a59081d985d5b1d609a1b604482015260649150fd5b61140f9150853d8711611415575b6114078183610e80565b810190611283565b386113b2565b503d6113fd565b83513d6000823e3d90fd5b61143f919550893d8b1161048e576104808183610e80565b933861135e565b87513d6000823e3d90fd5b611469919450883d8a1161048e576104808183610e80565b9238611332565b611488919250863d8811611415576114078183610e80565b9038611306565b84513d6000823e3d90fd5b6114b2919750833d8511611415576114078183610e80565b95386112de565b82513d6000823e3d90fd5b60408051630dfe168160e01b81526001600160a01b0392831694909392909160049160209190828785818b5afa9687156114b957600097611615575b50815163d21220a760e01b815287848287818d5afa91821561148f576000926115f6575b508197837f0000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a1680858416149081156115ea575b50156115b8578451631fde87bb60e21b8152929190868489818f5afa9384156103be579088949392916000946114515750878d88519687809262df906d60e61b82525afa948515611446579061136495949392916000956114275750610ea2565b845162461bcd60e51b8152808801879052600c60248201526b13985d1a5d99481d985d5b1d60a21b6044820152606490fd5b90508484161438611557565b61160e919250853d8711611415576114078183610e80565b9038611524565b61162d919750833d8511611415576114078183610e80565b953861150056fea164736f6c6343000814000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a6ceef2a9b7b080f62ea2f73f2271214f0d928f80000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a
-----Decoded View---------------
Arg [0] : _ICHIVaultFactory (address): 0xA6cEEf2a9b7B080F62ea2F73F2271214F0d928F8
Arg [1] : _WRAPPED_NATIVE (address): 0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000a6ceef2a9b7b080f62ea2f73f2271214f0d928f8
Arg [1] : 0000000000000000000000003bd359c1119da7da1d913d1c4d2b7c461115433a
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in MON
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.