Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 9 from a total of 9 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Unstake | 21557185 | 413 days ago | IN | 0 ETH | 0.00361708 | ||||
| Unstake | 21554968 | 414 days ago | IN | 0 ETH | 0.00287777 | ||||
| Unstake | 21550362 | 414 days ago | IN | 0 ETH | 0.00257274 | ||||
| Unstake | 21512853 | 420 days ago | IN | 0 ETH | 0.00210228 | ||||
| Unstake | 21512848 | 420 days ago | IN | 0 ETH | 0.00167697 | ||||
| Stake | 21469678 | 426 days ago | IN | 0.0032 ETH | 0.00616044 | ||||
| Stake | 21469636 | 426 days ago | IN | 0.0031 ETH | 0.00619336 | ||||
| Stake | 21469504 | 426 days ago | IN | 0.003 ETH | 0.00683377 | ||||
| Add Vault | 21469173 | 426 days ago | IN | 0 ETH | 0.00079345 |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
LiquidityManager
Compiler Version
v0.8.27+commit.40a35a09
Optimization Enabled:
Yes with 100 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.27;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IERC4626Partial} from "../IERC4626Partial.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
contract LiquidityManager is ERC20, Ownable, ReentrancyGuard {
using EnumerableSet for EnumerableSet.Bytes32Set;
uint256 public allocatedAssets;
uint256 public totalAssets;
struct Vault {
uint8 weight;
address vault;
}
EnumerableSet.Bytes32Set private _vaults;
uint256 public totalWeight;
address private immutable _self;
constructor()
ERC20("Test", "Test")
Ownable(msg.sender) {
_self = address(this);
}
function getVaultCount() external view returns (uint256) {
return _vaults.length();
}
function getVaultAt(uint256 index) external view returns (Vault memory) {
require(index < _vaults.length(), "Index out of bounds");
return _bytes32ToVault(_vaults.at(index));
}
// Helper function to convert Vault struct to bytes32
function _vaultToBytes32(Vault memory vault) internal pure returns (bytes32) {
return bytes32((uint256(uint8(vault.weight)) << 160) | uint160(vault.vault));
}
// Helper function to convert bytes32 to Vault struct
function _bytes32ToVault(bytes32 data) internal pure returns (Vault memory) {
uint8 weight = uint8(uint256(data) >> 160);
address vault = address(uint160(uint256(data)));
return Vault(weight, vault);
}
function addVault(address vault, uint8 weight) external onlyOwner {
Vault memory newVault = Vault(weight, vault);
require(_vaults.add(_vaultToBytes32(newVault)), "addVault: Vault already exists");
totalWeight += weight;
emit VaultAdded(vault);
}
function removeVault(uint256 index) external onlyOwner {
Vault memory vaultToRemove = _bytes32ToVault(_vaults.at(index));
require(_vaults.remove(_vaultToBytes32(vaultToRemove)), "removeVault: Vault does not exist");
totalWeight -= vaultToRemove.weight;
uint256 assets = IERC4626Partial(vaultToRemove.vault).totalAssets();
if (assets > 0) {
IERC4626Partial(vaultToRemove.vault).withdraw(assets, _self, _self);
totalAssets -= assets;
}
emit VaultRemoved(vaultToRemove.vault);
}
function stake() external payable nonReentrant {
require(msg.value > 0, "stake: Invalid amount");
require(totalWeight > 0, "stake: Total weight is 0");
uint256 amount = msg.value;
uint256 count = _vaults.length();
for (uint i = 0; i < count; i++) {
Vault memory v = _bytes32ToVault(_vaults.at(i));
uint256 portion = (amount * v.weight) / totalWeight;
IERC4626Partial vault = IERC4626Partial(v.vault);
address asset = vault.asset();
uint256 valueBefore = vault.getValueInEth(asset);
vault.deposit{value: portion}(portion, _self);
uint256 valueAfter = vault.getValueInEth(asset);
uint256 assets = vault.totalAssets();
if (assets > 0 && valueAfter > valueBefore) {
// Use a scale factor of 1e18 for precision
uint256 SCALE = 1e18;
uint256 delta = valueAfter - valueBefore;
// Calculate ratio with scaling
uint256 scaledRatio = (delta * SCALE) / assets;
// Calculate shares maintaining precision
uint256 shares = (scaledRatio * portion) / SCALE;
// Ensure minimum share amount
shares = shares > 0 ? shares : portion;
_mint(msg.sender, shares);
} else {
// If no assets yet, use 1:1 ratio
_mint(msg.sender, portion);
}
}
totalAssets += amount;
emit Staked(msg.sender, msg.value);
}
function unstake(uint256 shares) external nonReentrant {
require(shares > 0, "unstake: Invalid amount");
require(totalWeight > 0, "unstake: Total weight is 0");
require(balanceOf(msg.sender) >= shares, "unstake: Insufficient balance");
_burn(msg.sender, shares);
uint256 assets = 0;
uint256 count = _vaults.length();
uint256 SCALE = 1e18;
for (uint i = 0; i < count; i++) {
Vault memory v = _bytes32ToVault(_vaults.at(i));
// Calculate portion with scaling to prevent precision loss
uint256 portion = (shares * v.weight * SCALE) / totalWeight;
IERC4626Partial vault = IERC4626Partial(v.vault);
uint256 assetsBefore = _self.balance;
// Withdraw scaled portion
vault.withdraw(portion / SCALE, _self, _self);
uint256 assetsAfter = _self.balance;
assets += assetsAfter - assetsBefore;
}
totalAssets -= assets;
payable(msg.sender).transfer(assets);
emit Unstaked(msg.sender, assets);
}
event Staked(address indexed account, uint256 amount);
event Unstaked(address indexed account, uint256 amount);
event VaultAdded(address indexed vault);
event VaultRemoved(address indexed vault);
}// 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) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard ERC-20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC-721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC-1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC-20
* applications.
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Skips emitting an {Approval} event indicating an allowance update. This is not
* required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
_totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
*
* ```solidity
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC-20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @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.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/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @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].
*/
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;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
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
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// 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 v5.1.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.20;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position is the index of the value in the `values` array plus 1.
// Position 0 is used to mean a value is not in the set.
mapping(bytes32 value => uint256) _positions;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We cache the value's position to prevent multiple reads from the same storage slot
uint256 position = set._positions[value];
if (position != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the lastValue to the index where the value to delete is
set._values[valueIndex] = lastValue;
// Update the tracked position of the lastValue (that was just moved)
set._positions[lastValue] = position;
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the tracked position for the deleted slot
delete set._positions[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._positions[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.27;
import { IOracle } from "./IOracle.sol";
interface IERC4626Partial is IOracle {
function asset() external view returns (address);
function deposit(uint256 assets, address receiver) external payable returns (uint256 shares);
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
function totalAssets() external view returns (uint256);
event Deposit(address indexed sender, address indexed owner, uint256 assets);
event Withdraw(address indexed sender, uint256 assets);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.27;
interface IOracle {
function getValueInEth(address token) external returns (uint256);
}{
"optimizer": {
"enabled": true,
"runs": 100
},
"viaIR": true,
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","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":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"}],"name":"VaultAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"}],"name":"VaultRemoved","type":"event"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"uint8","name":"weight","type":"uint8"}],"name":"addVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allocatedAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getVaultAt","outputs":[{"components":[{"internalType":"uint8","name":"weight","type":"uint8"},{"internalType":"address","name":"vault","type":"address"}],"internalType":"struct LiquidityManager.Vault","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVaultCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"removeVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a0604052346103595761001161035e565b61001961035e565b81516001600160401b03811161026457600354600181811c9116801561034f575b602082101461024457601f81116102ea575b50602092601f8211600114610285579281929360009261027a575b50508160011b916000199060031b1c1916176003555b80516001600160401b03811161026457600454600181811c9116801561025a575b602082101461024457601f81116101df575b50602091601f821160011461017b57918192600092610170575b50508160011b916000199060031b1c1916176004555b331561015a5760058054336001600160a01b03198216811790925560405191906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3600160065530608052611616908161038f8239608051818181610298015281816107e70152610c870152f35b631e4fbdf760e01b600052600060045260246000fd5b0151905038806100ca565b601f198216926004600052806000209160005b8581106101c7575083600195106101ae575b505050811b016004556100e0565b015160001960f88460031b161c191690553880806101a0565b9192602060018192868501518155019401920161018e565b60046000527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b601f830160051c8101916020841061023a575b601f0160051c01905b81811061022e57506100b0565b60008155600101610221565b9091508190610218565b634e487b7160e01b600052602260045260246000fd5b90607f169061009e565b634e487b7160e01b600052604160045260246000fd5b015190503880610067565b601f198216936003600052806000209160005b8681106102d257508360019596106102b9575b505050811b0160035561007d565b015160001960f88460031b161c191690553880806102ab565b91926020600181928685015181550194019201610298565b60036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b601f830160051c81019160208410610345575b601f0160051c01905b818110610339575061004c565b6000815560010161032c565b9091508190610323565b90607f169061003a565b600080fd5b60408051919082016001600160401b0381118382101761026457604052600482526315195cdd60e21b602083015256fe608080604052600436101561001357600080fd5b60003560e01c90816301e1d114146111855750806306fdde03146110c7578063095ea7b31461104157806318160ddd1461102357806323b872dd14610f365780632e17de7814610bf1578063313ce56714610bd557806336cd2b1114610bb75780633a4b66f1146107bd57806370a0823114610783578063715018a61461072657806374d4e491146107085780637a98742d146106775780637a9b27d01461058c5780638da5cb5b1461056357806395d89b411461045c57806396c82e571461043e578063a9059cbb1461040d578063dd62ed3e146103bc578063eaadd976146101955763f2fde38b1461010657600080fd5b346101905760203660031901126101905761011f6111e9565b61012761140b565b6001600160a01b0316801561017a57600580546001600160a01b0319811683179091556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b631e4fbdf760e01b600052600060045260246000fd5b600080fd5b34610190576020366003190112610190576101ae61140b565b6101c86101bc600435611434565b90549060031b1c61138e565b805160208201516101f09160ff60a01b60a09190911b166001600160a01b03909116176114ef565b1561036d578061020860ff6020935116600b5461129c565b600b550180516040516278744560e21b815290602090829060049082906001600160a01b03165afa90811561032c57600091610338575b5080610278575b50516001600160a01b03167fe71f3a50e5ad81964f352c411f1d45e35438ecd1acecef59ac81d9fbbf6cbc0a600080a2005b8151604051632d182be560e21b8152600481018390526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301819052604483015290929160209184916064918391600091165af1801561032c576102f9575b6102f0915060085461129c565b60085581610246565b6020823d602011610324575b8161031260209383611247565b81010312610190576102f091506102e3565b3d9150610305565b6040513d6000823e3d90fd5b906020823d602011610365575b8161035260209383611247565b810103126103625750518261023f565b80fd5b3d9150610345565b60405162461bcd60e51b815260206004820152602160248201527f72656d6f76655661756c743a205661756c7420646f6573206e6f7420657869736044820152601d60fa1b6064820152608490fd5b34610190576040366003190112610190576103d56111e9565b6103dd6111ff565b6001600160a01b039182166000908152600160209081526040808320949093168252928352819020549051908152f35b34610190576040366003190112610190576104336104296111e9565b60243590336112cf565b602060405160018152f35b34610190576000366003190112610190576020600b54604051908152f35b346101905760003660031901126101905760405160006004548060011c90600181168015610559575b6020831081146105455782855290811561052157506001146104c2575b6104be836104b281850382611247565b604051918291826111a0565b0390f35b600460009081527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b939250905b808210610507575090915081016020016104b26104a2565b9192600181602092548385880101520191019092916104ef565b60ff191660208086019190915291151560051b840190910191506104b290506104a2565b634e487b7160e01b84526022600452602484fd5b91607f1691610485565b34610190576000366003190112610190576005546040516001600160a01b039091168152602090f35b34610190576040366003190112610190576105a56111e9565b60243560ff8116809103610190576105bb61140b565b6105f76105f2604051936105ce85611215565b8385526001600160a01b0316602090940184905260a083901b60ff60a01b16841790565b61147d565b156106325761060890600b546112a9565b600b557f7b7ef7a864d96a85497a1ed846adb39940dd6ccef678ff6ac8d55505e09b8cc4600080a2005b60405162461bcd60e51b815260206004820152601e60248201527f6164645661756c743a205661756c7420616c72656164792065786973747300006044820152606490fd5b34610190576020366003190112610190576004356106936112b6565b506009548110156106cd576106ac6101bc604092611434565b8151815160ff1681526020918201516001600160a01b031691810191909152f35b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b6044820152606490fd5b34610190576000366003190112610190576020600954604051908152f35b346101905760003660031901126101905761073f61140b565b600580546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b34610190576020366003190112610190576001600160a01b036107a46111e9565b1660005260006020526020604060002054604051908152f35b6000366003190112610190576107d161136c565b3415610b7a57600b5415610b3a576009546000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316905b80831061085a57610824346008546112a9565b6008556040513481527f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d60203392a26001600655005b6108666101bc84611434565b9261088161087860ff86511634611269565b600b549061127c565b6020948501516040516338d52e0f60e01b81526001600160a01b039091169581600481895afa90811561032c57600091610af5575b506040516335827fa160e21b81526001600160a01b0390911660048201819052956020826024816000855af191821561032c57600092610ac2575b50604051636e553f6560e01b815283600482015286602482015260208160448187865af1801561032c57600090610a92575b5050604051966335827fa160e21b885260048801526020876024816000855af196871561032c57600097610a5e575b509560206004959697604051968780926278744560e21b82525afa94851561032c57600095610a2b575b5084151580610a22575b15610a0d57906109959161129c565b90670de0b6b3a7640000820291808304670de0b6b3a764000014901517156109f757670de0b6b3a76400006109d8826109d36001976109e89661127c565b611269565b049081156109f057505b336113bf565b019190610811565b90506109e2565b634e487b7160e01b600052601160045260246000fd5b505060019250610a1d90336113bf565b6109e8565b50818111610986565b90946020823d8211610a56575b81610a4560209383611247565b81010312610362575051938761097c565b3d9150610a38565b966020883d8211610a8a575b81610a7760209383611247565b8101031261036257509551956020610952565b3d9150610a6a565b6020823d8211610aba575b81610aaa60209383611247565b8101031261036257505188610923565b3d9150610a9d565b90916020823d8211610aed575b81610adc60209383611247565b8101031261036257505190876108f1565b3d9150610acf565b6020813d8211610b32575b81610b0d60209383611247565b81010312610b2e5751906001600160a01b03821682036103625750866108b6565b5080fd5b3d9150610b00565b60405162461bcd60e51b815260206004820152601860248201527707374616b653a20546f74616c2077656967687420697320360441b6044820152606490fd5b60405162461bcd60e51b81526020600482015260156024820152741cdd185ad94e88125b9d985b1a5908185b5bdd5b9d605a1b6044820152606490fd5b34610190576000366003190112610190576020600754604051908152f35b3461019057600036600319011261019057602060405160128152f35b3461019057602036600319011261019057600435610c0d61136c565b8015610ef757600b5415610eb2573360005260006020528060406000205410610e6d573315610e5757600033815280602052604081205491808310610e3e578083338452836020520360408320558060025403600255816040518281526000805160206115c183398151915260203392a3819060095483917f00000000000000000000000000000000000000000000000000000000000000005b828410610d22578585610cbc8160085461129c565b6008558180828015610d18575b8280929181923390f115610d0b576040519081527f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f7560203392a2600160065580f35b50604051903d90823e3d90fd5b6108fc9150610cc9565b90919293610d326101bc86611434565b610d4060ff82511685611269565b670de0b6b3a7640000810290808204670de0b6b3a76400001490151715610e2a57602084610d728193600b549061127c565b93820151604051632d182be560e21b8152670de0b6b3a764000090950460048601526001600160a01b038281166024870152938416604486015290319392839160649183918d91165af18015610e1f57610de9575b50600191610dd9610ddf92853161129c565b906112a9565b9401929190610ca7565b916020833d8211610e17575b81610e0260209383611247565b81010312610e135791506001610dc7565b8780fd5b3d9150610df5565b6040513d8a823e3d90fd5b634e487b7160e01b88526011600452602488fd5b60649263391434e360e21b835233600452602452604452fd5b634b637e8f60e11b600052600060045260246000fd5b60405162461bcd60e51b815260206004820152601d60248201527f756e7374616b653a20496e73756666696369656e742062616c616e63650000006044820152606490fd5b60405162461bcd60e51b815260206004820152601a60248201527f756e7374616b653a20546f74616c2077656967687420697320300000000000006044820152606490fd5b60405162461bcd60e51b81526020600482015260176024820152761d5b9cdd185ad94e88125b9d985b1a5908185b5bdd5b9d604a1b6044820152606490fd5b3461019057606036600319011261019057610f4f6111e9565b610f576111ff565b6001600160a01b0382166000818152600160208181526040808420338552909152909120549193604435939290918101610f97575b5061043393506112cf565b838110611006578415610ff0573315610fda57610433946000526001602052604060002060018060a01b0333166000526020528360406000209103905584610f8c565b634a1406b160e11b600052600060045260246000fd5b63e602df0560e01b600052600060045260246000fd5b8390637dc7a0d960e11b6000523360045260245260445260646000fd5b34610190576000366003190112610190576020600254604051908152f35b346101905760403660031901126101905761105a6111e9565b602435903315610ff0576001600160a01b0316908115610fda57336000526001602052604060002082600052602052806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b346101905760003660031901126101905760405160006003548060011c9060018116801561117b575b60208310811461054557828552908115610521575060011461111c576104be836104b281850382611247565b600360009081527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b939250905b808210611161575090915081016020016104b26104a2565b919260018160209254838588010152019101909291611149565b91607f16916110f0565b34610190576000366003190112610190576020906008548152f35b91909160208152825180602083015260005b8181106111d3575060409293506000838284010152601f8019910116010190565b80602080928701015160408286010152016111b2565b600435906001600160a01b038216820361019057565b602435906001600160a01b038216820361019057565b6040810190811067ffffffffffffffff82111761123157604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff82111761123157604052565b818102929181159184041417156109f757565b8115611286570490565b634e487b7160e01b600052601260045260246000fd5b919082039182116109f757565b919082018092116109f757565b604051906112c382611215565b60006020838281520152565b6001600160a01b0316908115610e57576001600160a01b031691821561135657600082815280602052604081205482811061133c5791604082826000805160206115c1833981519152958760209652828652038282205586815280845220818154019055604051908152a3565b916064928463391434e360e21b8452600452602452604452fd5b63ec442f0560e01b600052600060045260246000fd5b60026006541461137d576002600655565b633ee5aeb560e01b60005260046000fd5b6113966112b6565b50604051906113a482611215565b60a081901c60ff1682526001600160a01b0316602082015290565b6001600160a01b0316908115611356576113db816002546112a9565b6002556000805160206115c1833981519152602060009284845283825260408420818154019055604051908152a3565b6005546001600160a01b0316330361141f57565b63118cdaa760e01b6000523360045260246000fd5b60095481101561144f57600960005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b805482101561144f5760005260206000200190600090565b80600052600a602052604060002054156000146114e957600954600160401b811015611231576114d06114b98260018594016009556009611465565b819391549060031b91821b91600019901b19161790565b905560095490600052600a602052604060002055600190565b50600090565b6000818152600a602052604090205480156115b95760001981018181116109f7576009546000198101919082116109f75781810361157f575b50505060095480156115695760001901611543816009611465565b8154906000199060031b1b19169055600955600052600a60205260006040812055600190565b634e487b7160e01b600052603160045260246000fd5b6115a16115906114b9936009611465565b90549060031b1c9283926009611465565b9055600052600a602052604060002055388080611528565b505060009056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212206436e5ed6d22c61a60fc0199f2ea6e28cc108d50b93909cf15c7231b8de372a164736f6c634300081b0033
Deployed Bytecode
0x608080604052600436101561001357600080fd5b60003560e01c90816301e1d114146111855750806306fdde03146110c7578063095ea7b31461104157806318160ddd1461102357806323b872dd14610f365780632e17de7814610bf1578063313ce56714610bd557806336cd2b1114610bb75780633a4b66f1146107bd57806370a0823114610783578063715018a61461072657806374d4e491146107085780637a98742d146106775780637a9b27d01461058c5780638da5cb5b1461056357806395d89b411461045c57806396c82e571461043e578063a9059cbb1461040d578063dd62ed3e146103bc578063eaadd976146101955763f2fde38b1461010657600080fd5b346101905760203660031901126101905761011f6111e9565b61012761140b565b6001600160a01b0316801561017a57600580546001600160a01b0319811683179091556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b631e4fbdf760e01b600052600060045260246000fd5b600080fd5b34610190576020366003190112610190576101ae61140b565b6101c86101bc600435611434565b90549060031b1c61138e565b805160208201516101f09160ff60a01b60a09190911b166001600160a01b03909116176114ef565b1561036d578061020860ff6020935116600b5461129c565b600b550180516040516278744560e21b815290602090829060049082906001600160a01b03165afa90811561032c57600091610338575b5080610278575b50516001600160a01b03167fe71f3a50e5ad81964f352c411f1d45e35438ecd1acecef59ac81d9fbbf6cbc0a600080a2005b8151604051632d182be560e21b8152600481018390526001600160a01b037f00000000000000000000000008156a3ce454dfc8a8a8dc96360f9cf30b69fd3e811660248301819052604483015290929160209184916064918391600091165af1801561032c576102f9575b6102f0915060085461129c565b60085581610246565b6020823d602011610324575b8161031260209383611247565b81010312610190576102f091506102e3565b3d9150610305565b6040513d6000823e3d90fd5b906020823d602011610365575b8161035260209383611247565b810103126103625750518261023f565b80fd5b3d9150610345565b60405162461bcd60e51b815260206004820152602160248201527f72656d6f76655661756c743a205661756c7420646f6573206e6f7420657869736044820152601d60fa1b6064820152608490fd5b34610190576040366003190112610190576103d56111e9565b6103dd6111ff565b6001600160a01b039182166000908152600160209081526040808320949093168252928352819020549051908152f35b34610190576040366003190112610190576104336104296111e9565b60243590336112cf565b602060405160018152f35b34610190576000366003190112610190576020600b54604051908152f35b346101905760003660031901126101905760405160006004548060011c90600181168015610559575b6020831081146105455782855290811561052157506001146104c2575b6104be836104b281850382611247565b604051918291826111a0565b0390f35b600460009081527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b939250905b808210610507575090915081016020016104b26104a2565b9192600181602092548385880101520191019092916104ef565b60ff191660208086019190915291151560051b840190910191506104b290506104a2565b634e487b7160e01b84526022600452602484fd5b91607f1691610485565b34610190576000366003190112610190576005546040516001600160a01b039091168152602090f35b34610190576040366003190112610190576105a56111e9565b60243560ff8116809103610190576105bb61140b565b6105f76105f2604051936105ce85611215565b8385526001600160a01b0316602090940184905260a083901b60ff60a01b16841790565b61147d565b156106325761060890600b546112a9565b600b557f7b7ef7a864d96a85497a1ed846adb39940dd6ccef678ff6ac8d55505e09b8cc4600080a2005b60405162461bcd60e51b815260206004820152601e60248201527f6164645661756c743a205661756c7420616c72656164792065786973747300006044820152606490fd5b34610190576020366003190112610190576004356106936112b6565b506009548110156106cd576106ac6101bc604092611434565b8151815160ff1681526020918201516001600160a01b031691810191909152f35b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b6044820152606490fd5b34610190576000366003190112610190576020600954604051908152f35b346101905760003660031901126101905761073f61140b565b600580546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b34610190576020366003190112610190576001600160a01b036107a46111e9565b1660005260006020526020604060002054604051908152f35b6000366003190112610190576107d161136c565b3415610b7a57600b5415610b3a576009546000907f00000000000000000000000008156a3ce454dfc8a8a8dc96360f9cf30b69fd3e6001600160a01b0316905b80831061085a57610824346008546112a9565b6008556040513481527f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d60203392a26001600655005b6108666101bc84611434565b9261088161087860ff86511634611269565b600b549061127c565b6020948501516040516338d52e0f60e01b81526001600160a01b039091169581600481895afa90811561032c57600091610af5575b506040516335827fa160e21b81526001600160a01b0390911660048201819052956020826024816000855af191821561032c57600092610ac2575b50604051636e553f6560e01b815283600482015286602482015260208160448187865af1801561032c57600090610a92575b5050604051966335827fa160e21b885260048801526020876024816000855af196871561032c57600097610a5e575b509560206004959697604051968780926278744560e21b82525afa94851561032c57600095610a2b575b5084151580610a22575b15610a0d57906109959161129c565b90670de0b6b3a7640000820291808304670de0b6b3a764000014901517156109f757670de0b6b3a76400006109d8826109d36001976109e89661127c565b611269565b049081156109f057505b336113bf565b019190610811565b90506109e2565b634e487b7160e01b600052601160045260246000fd5b505060019250610a1d90336113bf565b6109e8565b50818111610986565b90946020823d8211610a56575b81610a4560209383611247565b81010312610362575051938761097c565b3d9150610a38565b966020883d8211610a8a575b81610a7760209383611247565b8101031261036257509551956020610952565b3d9150610a6a565b6020823d8211610aba575b81610aaa60209383611247565b8101031261036257505188610923565b3d9150610a9d565b90916020823d8211610aed575b81610adc60209383611247565b8101031261036257505190876108f1565b3d9150610acf565b6020813d8211610b32575b81610b0d60209383611247565b81010312610b2e5751906001600160a01b03821682036103625750866108b6565b5080fd5b3d9150610b00565b60405162461bcd60e51b815260206004820152601860248201527707374616b653a20546f74616c2077656967687420697320360441b6044820152606490fd5b60405162461bcd60e51b81526020600482015260156024820152741cdd185ad94e88125b9d985b1a5908185b5bdd5b9d605a1b6044820152606490fd5b34610190576000366003190112610190576020600754604051908152f35b3461019057600036600319011261019057602060405160128152f35b3461019057602036600319011261019057600435610c0d61136c565b8015610ef757600b5415610eb2573360005260006020528060406000205410610e6d573315610e5757600033815280602052604081205491808310610e3e578083338452836020520360408320558060025403600255816040518281526000805160206115c183398151915260203392a3819060095483917f00000000000000000000000008156a3ce454dfc8a8a8dc96360f9cf30b69fd3e5b828410610d22578585610cbc8160085461129c565b6008558180828015610d18575b8280929181923390f115610d0b576040519081527f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f7560203392a2600160065580f35b50604051903d90823e3d90fd5b6108fc9150610cc9565b90919293610d326101bc86611434565b610d4060ff82511685611269565b670de0b6b3a7640000810290808204670de0b6b3a76400001490151715610e2a57602084610d728193600b549061127c565b93820151604051632d182be560e21b8152670de0b6b3a764000090950460048601526001600160a01b038281166024870152938416604486015290319392839160649183918d91165af18015610e1f57610de9575b50600191610dd9610ddf92853161129c565b906112a9565b9401929190610ca7565b916020833d8211610e17575b81610e0260209383611247565b81010312610e135791506001610dc7565b8780fd5b3d9150610df5565b6040513d8a823e3d90fd5b634e487b7160e01b88526011600452602488fd5b60649263391434e360e21b835233600452602452604452fd5b634b637e8f60e11b600052600060045260246000fd5b60405162461bcd60e51b815260206004820152601d60248201527f756e7374616b653a20496e73756666696369656e742062616c616e63650000006044820152606490fd5b60405162461bcd60e51b815260206004820152601a60248201527f756e7374616b653a20546f74616c2077656967687420697320300000000000006044820152606490fd5b60405162461bcd60e51b81526020600482015260176024820152761d5b9cdd185ad94e88125b9d985b1a5908185b5bdd5b9d604a1b6044820152606490fd5b3461019057606036600319011261019057610f4f6111e9565b610f576111ff565b6001600160a01b0382166000818152600160208181526040808420338552909152909120549193604435939290918101610f97575b5061043393506112cf565b838110611006578415610ff0573315610fda57610433946000526001602052604060002060018060a01b0333166000526020528360406000209103905584610f8c565b634a1406b160e11b600052600060045260246000fd5b63e602df0560e01b600052600060045260246000fd5b8390637dc7a0d960e11b6000523360045260245260445260646000fd5b34610190576000366003190112610190576020600254604051908152f35b346101905760403660031901126101905761105a6111e9565b602435903315610ff0576001600160a01b0316908115610fda57336000526001602052604060002082600052602052806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b346101905760003660031901126101905760405160006003548060011c9060018116801561117b575b60208310811461054557828552908115610521575060011461111c576104be836104b281850382611247565b600360009081527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b939250905b808210611161575090915081016020016104b26104a2565b919260018160209254838588010152019101909291611149565b91607f16916110f0565b34610190576000366003190112610190576020906008548152f35b91909160208152825180602083015260005b8181106111d3575060409293506000838284010152601f8019910116010190565b80602080928701015160408286010152016111b2565b600435906001600160a01b038216820361019057565b602435906001600160a01b038216820361019057565b6040810190811067ffffffffffffffff82111761123157604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff82111761123157604052565b818102929181159184041417156109f757565b8115611286570490565b634e487b7160e01b600052601260045260246000fd5b919082039182116109f757565b919082018092116109f757565b604051906112c382611215565b60006020838281520152565b6001600160a01b0316908115610e57576001600160a01b031691821561135657600082815280602052604081205482811061133c5791604082826000805160206115c1833981519152958760209652828652038282205586815280845220818154019055604051908152a3565b916064928463391434e360e21b8452600452602452604452fd5b63ec442f0560e01b600052600060045260246000fd5b60026006541461137d576002600655565b633ee5aeb560e01b60005260046000fd5b6113966112b6565b50604051906113a482611215565b60a081901c60ff1682526001600160a01b0316602082015290565b6001600160a01b0316908115611356576113db816002546112a9565b6002556000805160206115c1833981519152602060009284845283825260408420818154019055604051908152a3565b6005546001600160a01b0316330361141f57565b63118cdaa760e01b6000523360045260246000fd5b60095481101561144f57600960005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b805482101561144f5760005260206000200190600090565b80600052600a602052604060002054156000146114e957600954600160401b811015611231576114d06114b98260018594016009556009611465565b819391549060031b91821b91600019901b19161790565b905560095490600052600a602052604060002055600190565b50600090565b6000818152600a602052604090205480156115b95760001981018181116109f7576009546000198101919082116109f75781810361157f575b50505060095480156115695760001901611543816009611465565b8154906000199060031b1b19169055600955600052600a60205260006040812055600190565b634e487b7160e01b600052603160045260246000fd5b6115a16115906114b9936009611465565b90549060031b1c9283926009611465565b9055600052600a602052604060002055388080611528565b505060009056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212206436e5ed6d22c61a60fc0199f2ea6e28cc108d50b93909cf15c7231b8de372a164736f6c634300081b0033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
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.