Source Code
Latest 8 from a total of 8 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Deposit | 9486750 | 102 days ago | IN | 0 ETH | 0.00000135 | ||||
| Deposit | 9486713 | 102 days ago | IN | 0 ETH | 0.00000135 | ||||
| Deposit | 9486638 | 102 days ago | IN | 0 ETH | 0.00000186 | ||||
| Deposit | 9486626 | 102 days ago | IN | 0 ETH | 0.00000135 | ||||
| Deposit | 4551809 | 159 days ago | IN | 0 ETH | 0 | ||||
| Deposit | 4551791 | 159 days ago | IN | 0 ETH | 0 | ||||
| Deposit | 4551775 | 159 days ago | IN | 0 ETH | 0 | ||||
| Deposit | 4551695 | 159 days ago | IN | 0 ETH | 0 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
KatanaReceiver
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity)
/**
*Submitted for verification at KatanaScan.com on 2025-08-04
*/
// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.18 ^0.8.0 ^0.8.1 ^0.8.23;
// lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
/**
* @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);
}
// lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)
/**
* @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.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
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].
*
* CAUTION: See Security Considerations above.
*/
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);
}
// lib/openzeppelin-contracts/contracts/utils/Address.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
/**
* @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);
}
}
}
// lib/openzeppelin-contracts/contracts/utils/Context.sol
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
/**
* @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;
}
}
// lib/tokenized-strategy-periphery/src/utils/Governance.sol
contract Governance {
/// @notice Emitted when the governance address is updated.
event GovernanceTransferred(
address indexed previousGovernance,
address indexed newGovernance
);
modifier onlyGovernance() {
_checkGovernance();
_;
}
/// @notice Checks if the msg sender is the governance.
function _checkGovernance() internal view virtual {
require(governance == msg.sender, "!governance");
}
/// @notice Address that can set the default base fee and provider
address public governance;
constructor(address _governance) {
governance = _governance;
emit GovernanceTransferred(address(0), _governance);
}
/**
* @notice Sets a new address as the governance of the contract.
* @dev Throws if the caller is not current governance.
* @param _newGovernance The new governance address.
*/
function transferGovernance(
address _newGovernance
) external virtual onlyGovernance {
require(_newGovernance != address(0), "ZERO ADDRESS");
address oldGovernance = governance;
governance = _newGovernance;
emit GovernanceTransferred(oldGovernance, _newGovernance);
}
}
// lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
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);
}
// lib/tokenized-strategy-periphery/src/utils/Governance2Step.sol
contract Governance2Step is Governance {
/// @notice Emitted when the pending governance address is set.
event UpdatePendingGovernance(address indexed newPendingGovernance);
/// @notice Address that is set to take over governance.
address public pendingGovernance;
constructor(address _governance) Governance(_governance) {}
/**
* @notice Sets a new address as the `pendingGovernance` of the contract.
* @dev Throws if the caller is not current governance.
* @param _newGovernance The new governance address.
*/
function transferGovernance(
address _newGovernance
) external virtual override onlyGovernance {
require(_newGovernance != address(0), "ZERO ADDRESS");
pendingGovernance = _newGovernance;
emit UpdatePendingGovernance(_newGovernance);
}
/**
* @notice Allows the `pendingGovernance` to accept the role.
*/
function acceptGovernance() external virtual {
require(msg.sender == pendingGovernance, "!pending governance");
emit GovernanceTransferred(governance, msg.sender);
governance = msg.sender;
pendingGovernance = address(0);
}
}
// lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4626.sol)
/**
* @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in
* https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].
*
* _Available since v4.7._
*/
interface IERC4626 is IERC20, IERC20Metadata {
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(
address indexed sender,
address indexed receiver,
address indexed owner,
uint256 assets,
uint256 shares
);
/**
* @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
*
* - MUST be an ERC-20 token contract.
* - MUST NOT revert.
*/
function asset() external view returns (address assetTokenAddress);
/**
* @dev Returns the total amount of the underlying asset that is “managed” by Vault.
*
* - SHOULD include any compounding that occurs from yield.
* - MUST be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT revert.
*/
function totalAssets() external view returns (uint256 totalManagedAssets);
/**
* @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToShares(uint256 assets) external view returns (uint256 shares);
/**
* @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToAssets(uint256 shares) external view returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
* through a deposit call.
*
* - MUST return a limited value if receiver is subject to some deposit limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
* - MUST NOT revert.
*/
function maxDeposit(address receiver) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
* call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
* in the same transaction.
* - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
* deposit would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewDeposit(uint256 assets) external view returns (uint256 shares);
/**
* @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* deposit execution, and are accounted for during deposit.
* - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function deposit(uint256 assets, address receiver) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
* - MUST return a limited value if receiver is subject to some mint limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
* - MUST NOT revert.
*/
function maxMint(address receiver) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
* in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
* same transaction.
* - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
* would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by minting.
*/
function previewMint(uint256 shares) external view returns (uint256 assets);
/**
* @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
* execution, and are accounted for during mint.
* - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function mint(uint256 shares, address receiver) external returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
* Vault, through a withdraw call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxWithdraw(address owner) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
* call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
* called
* in the same transaction.
* - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
* the withdrawal would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewWithdraw(uint256 assets) external view returns (uint256 shares);
/**
* @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* withdraw execution, and are accounted for during withdraw.
* - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
* through a redeem call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxRedeem(address owner) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
* in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
* same transaction.
* - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
* redemption would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by redeeming.
*/
function previewRedeem(uint256 shares) external view returns (uint256 assets);
/**
* @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* redeem execution, and are accounted for during redeem.
* - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}
// lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.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}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* 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 ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => 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 override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override 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 override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override 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 `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` 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 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* 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 `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `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.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` 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.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}
// lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.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));
}
}
// lib/tokenized-strategy-periphery/lib/yearn-vaults-v3/contracts/interfaces/IVault.sol
interface IVault is IERC4626 {
// STRATEGY EVENTS
event StrategyChanged(address indexed strategy, uint256 change_type);
event StrategyReported(
address indexed strategy,
uint256 gain,
uint256 loss,
uint256 current_debt,
uint256 protocol_fees,
uint256 total_fees,
uint256 total_refunds
);
// DEBT MANAGEMENT EVENTS
event DebtUpdated(
address indexed strategy,
uint256 current_debt,
uint256 new_debt
);
// ROLE UPDATES
event RoleSet(address indexed account, uint256 role);
event UpdateFutureRoleManager(address indexed future_role_manager);
event UpdateRoleManager(address indexed role_manager);
event UpdateAccountant(address indexed accountant);
event UpdateDefaultQueue(address[] new_default_queue);
event UpdateUseDefaultQueue(bool use_default_queue);
event UpdatedMaxDebtForStrategy(
address indexed sender,
address indexed strategy,
uint256 new_debt
);
event UpdateAutoAllocate(bool auto_allocate);
event UpdateDepositLimit(uint256 deposit_limit);
event UpdateMinimumTotalIdle(uint256 minimum_total_idle);
event UpdateProfitMaxUnlockTime(uint256 profit_max_unlock_time);
event DebtPurchased(address indexed strategy, uint256 amount);
event Shutdown();
struct StrategyParams {
uint256 activation;
uint256 last_report;
uint256 current_debt;
uint256 max_debt;
}
function FACTORY() external view returns (uint256);
function strategies(address) external view returns (StrategyParams memory);
function default_queue(uint256) external view returns (address);
function use_default_queue() external view returns (bool);
function auto_allocate() external view returns (bool);
function minimum_total_idle() external view returns (uint256);
function deposit_limit() external view returns (uint256);
function deposit_limit_module() external view returns (address);
function withdraw_limit_module() external view returns (address);
function accountant() external view returns (address);
function roles(address) external view returns (uint256);
function role_manager() external view returns (address);
function future_role_manager() external view returns (address);
function isShutdown() external view returns (bool);
function nonces(address) external view returns (uint256);
function initialize(
address,
string memory,
string memory,
address,
uint256
) external;
function setName(string memory) external;
function setSymbol(string memory) external;
function set_accountant(address new_accountant) external;
function set_default_queue(address[] memory new_default_queue) external;
function set_use_default_queue(bool) external;
function set_auto_allocate(bool) external;
function set_deposit_limit(uint256 deposit_limit) external;
function set_deposit_limit(
uint256 deposit_limit,
bool should_override
) external;
function set_deposit_limit_module(
address new_deposit_limit_module
) external;
function set_deposit_limit_module(
address new_deposit_limit_module,
bool should_override
) external;
function set_withdraw_limit_module(
address new_withdraw_limit_module
) external;
function set_minimum_total_idle(uint256 minimum_total_idle) external;
function setProfitMaxUnlockTime(
uint256 new_profit_max_unlock_time
) external;
function set_role(address account, uint256 role) external;
function add_role(address account, uint256 role) external;
function remove_role(address account, uint256 role) external;
function transfer_role_manager(address role_manager) external;
function accept_role_manager() external;
function unlockedShares() external view returns (uint256);
function pricePerShare() external view returns (uint256);
function get_default_queue() external view returns (address[] memory);
function process_report(
address strategy
) external returns (uint256, uint256);
function buy_debt(address strategy, uint256 amount) external;
function add_strategy(address new_strategy) external;
function revoke_strategy(address strategy) external;
function force_revoke_strategy(address strategy) external;
function update_max_debt_for_strategy(
address strategy,
uint256 new_max_debt
) external;
function update_debt(
address strategy,
uint256 target_debt
) external returns (uint256);
function update_debt(
address strategy,
uint256 target_debt,
uint256 max_loss
) external returns (uint256);
function shutdown_vault() external;
function totalIdle() external view returns (uint256);
function totalDebt() external view returns (uint256);
function apiVersion() external view returns (string memory);
function assess_share_of_unrealised_losses(
address strategy,
uint256 assets_needed
) external view returns (uint256);
function profitMaxUnlockTime() external view returns (uint256);
function fullProfitUnlockDate() external view returns (uint256);
function profitUnlockingRate() external view returns (uint256);
function lastProfitUpdate() external view returns (uint256);
//// NON-STANDARD ERC-4626 FUNCTIONS \\\\
function withdraw(
uint256 assets,
address receiver,
address owner,
uint256 max_loss
) external returns (uint256);
function withdraw(
uint256 assets,
address receiver,
address owner,
uint256 max_loss,
address[] memory strategies
) external returns (uint256);
function redeem(
uint256 shares,
address receiver,
address owner,
uint256 max_loss
) external returns (uint256);
function redeem(
uint256 shares,
address receiver,
address owner,
uint256 max_loss,
address[] memory strategies
) external returns (uint256);
function maxWithdraw(
address owner,
uint256 max_loss
) external view returns (uint256);
function maxWithdraw(
address owner,
uint256 max_loss,
address[] memory strategies
) external view returns (uint256);
function maxRedeem(
address owner,
uint256 max_loss
) external view returns (uint256);
function maxRedeem(
address owner,
uint256 max_loss,
address[] memory strategies
) external view returns (uint256);
//// NON-STANDARD ERC-20 FUNCTIONS \\\\
function DOMAIN_SEPARATOR() external view returns (bytes32);
function permit(
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external returns (bool);
}
// src/KatanaReceiver.sol
/// Receives tokens from STB vaults. Deposits into the Katana Yearn vault and
/// disperses them to the recipients.
contract KatanaReceiver is Governance2Step {
using SafeERC20 for ERC20;
using SafeERC20 for IVault;
event VaultSet(address indexed asset, address indexed vault);
mapping(address => address) public vaults;
constructor(address _owner) Governance2Step(_owner) {}
function deposit(address _asset) public {
address vault = vaults[_asset];
require(vault != address(0), "Vault not found");
uint256 balance = ERC20(_asset).balanceOf(address(this));
require(balance > 0, "No balance");
_deposit(_asset, vault, balance);
}
function _deposit(
address _asset,
address _vault,
uint256 _balance
) internal {
ERC20(_asset).forceApprove(_vault, _balance);
IVault(_vault).deposit(_balance, address(this));
}
function setVault(address _asset, address _vault) external onlyGovernance {
vaults[_asset] = _vault;
emit VaultSet(_asset, _vault);
}
function disperse(
address _asset,
address[] calldata _recipients,
uint256[] calldata _values
) external onlyGovernance {
IVault vault = IVault(vaults[_asset]);
require(address(vault) != address(0), "Vault not found");
uint256 balance = ERC20(_asset).balanceOf(address(this));
if (balance > 0) {
_deposit(_asset, address(vault), balance);
}
require(_recipients.length == _values.length, "Invalid length");
for (uint256 i = 0; i < _recipients.length; i++) {
vault.safeTransfer(_recipients[i], _values[i]);
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernance","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernance","type":"address"}],"name":"GovernanceTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newPendingGovernance","type":"address"}],"name":"UpdatePendingGovernance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"vault","type":"address"}],"name":"VaultSet","type":"event"},{"inputs":[],"name":"acceptGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"address[]","name":"_recipients","type":"address[]"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"}],"name":"disperse","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGovernance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"name":"setVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newGovernance","type":"address"}],"name":"transferGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"vaults","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561000f575f80fd5b50604051610d1d380380610d1d83398101604081905261002e9161007f565b5f80546001600160a01b0319166001600160a01b038316908117825560405183928392917f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce80908290a35050506100ac565b5f6020828403121561008f575f80fd5b81516001600160a01b03811681146100a5575f80fd5b9392505050565b610c64806100b95f395ff3fe608060405234801561000f575f80fd5b5060043610610085575f3560e01c8063c87b1ae311610058578063c87b1ae3146100fc578063d38bfff41461010f578063f340fa0114610122578063f39c38a014610135575f80fd5b8063238efcbc146100895780635aa6e67514610093578063714ccf7b146100c1578063a622ee7c146100d4575b5f80fd5b610091610148565b005b5f546100a5906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b6100916100cf366004610a61565b6101f3565b6100a56100e2366004610a92565b60026020525f90815260409020546001600160a01b031681565b61009161010a366004610afa565b610251565b61009161011d366004610a92565b6103e5565b610091610130366004610a92565b61047b565b6001546100a5906001600160a01b031681565b6001546001600160a01b0316331461019d5760405162461bcd60e51b81526020600482015260136024820152722170656e64696e6720676f7665726e616e636560681b60448201526064015b60405180910390fd5b5f805460405133926001600160a01b03909216917f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce8091a35f80546001600160a01b03199081163317909155600180549091169055565b6101fb61058a565b6001600160a01b038281165f8181526002602052604080822080546001600160a01b0319169486169485179055517f8800deb8c31293b539eaf5391fcc88280dc58f015c043d65dd5b72a0979a1dd19190a35050565b61025961058a565b6001600160a01b038086165f9081526002602052604090205416806102b25760405162461bcd60e51b815260206004820152600f60248201526e15985d5b1d081b9bdd08199bdd5b99608a1b6044820152606401610194565b6040516370a0823160e01b81523060048201525f906001600160a01b038816906370a0823190602401602060405180830381865afa1580156102f6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061031a9190610b75565b9050801561032d5761032d8783836105d3565b84831461036d5760405162461bcd60e51b815260206004820152600e60248201526d092dcecc2d8d2c840d8cadccee8d60931b6044820152606401610194565b5f5b858110156103db576103d387878381811061038c5761038c610b8c565b90506020020160208101906103a19190610a92565b8686848181106103b3576103b3610b8c565b90506020020135856001600160a01b031661065b9092919063ffffffff16565b60010161036f565b5050505050505050565b6103ed61058a565b6001600160a01b0381166104325760405162461bcd60e51b815260206004820152600c60248201526b5a45524f204144445245535360a01b6044820152606401610194565b600180546001600160a01b0319166001600160a01b0383169081179091556040517fa443b483867b0f9db5b03913474dd21935ac5ba70fa6c94e3423ba9be157c44b905f90a250565b6001600160a01b038082165f9081526002602052604090205416806104d45760405162461bcd60e51b815260206004820152600f60248201526e15985d5b1d081b9bdd08199bdd5b99608a1b6044820152606401610194565b6040516370a0823160e01b81523060048201525f906001600160a01b038416906370a0823190602401602060405180830381865afa158015610518573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061053c9190610b75565b90505f811161057a5760405162461bcd60e51b815260206004820152600a6024820152694e6f2062616c616e636560b01b6044820152606401610194565b6105858383836105d3565b505050565b5f546001600160a01b031633146105d15760405162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b6044820152606401610194565b565b6105e76001600160a01b03841683836106be565b604051636e553f6560e01b8152600481018290523060248201526001600160a01b03831690636e553f65906044016020604051808303815f875af1158015610631573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106559190610b75565b50505050565b6040516001600160a01b03831660248201526044810182905261058590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610748565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261070f848261081b565b610655576040516001600160a01b03841660248201525f604482015261074290859063095ea7b360e01b90606401610687565b61065584825b5f61079c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166108bc9092919063ffffffff16565b905080515f14806107bc5750808060200190518101906107bc9190610ba0565b6105855760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610194565b5f805f846001600160a01b0316846040516108369190610be1565b5f604051808303815f865af19150503d805f811461086f576040519150601f19603f3d011682016040523d82523d5f602084013e610874565b606091505b509150915081801561089e57508051158061089e57508080602001905181019061089e9190610ba0565b80156108b357506001600160a01b0385163b15155b95945050505050565b60606108ca84845f856108d2565b949350505050565b6060824710156109335760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610194565b5f80866001600160a01b0316858760405161094e9190610be1565b5f6040518083038185875af1925050503d805f8114610988576040519150601f19603f3d011682016040523d82523d5f602084013e61098d565b606091505b509150915061099e878383876109a9565b979650505050505050565b60608315610a175782515f03610a10576001600160a01b0385163b610a105760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610194565b50816108ca565b6108ca8383815115610a2c5781518083602001fd5b8060405162461bcd60e51b81526004016101949190610bfc565b80356001600160a01b0381168114610a5c575f80fd5b919050565b5f8060408385031215610a72575f80fd5b610a7b83610a46565b9150610a8960208401610a46565b90509250929050565b5f60208284031215610aa2575f80fd5b610aab82610a46565b9392505050565b5f8083601f840112610ac2575f80fd5b50813567ffffffffffffffff811115610ad9575f80fd5b6020830191508360208260051b8501011115610af3575f80fd5b9250929050565b5f805f805f60608688031215610b0e575f80fd5b610b1786610a46565b9450602086013567ffffffffffffffff80821115610b33575f80fd5b610b3f89838a01610ab2565b90965094506040880135915080821115610b57575f80fd5b50610b6488828901610ab2565b969995985093965092949392505050565b5f60208284031215610b85575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215610bb0575f80fd5b81518015158114610aab575f80fd5b5f5b83811015610bd9578181015183820152602001610bc1565b50505f910152565b5f8251610bf2818460208701610bbf565b9190910192915050565b602081525f8251806020840152610c1a816040850160208701610bbf565b601f01601f1916919091016040019291505056fea26469706673582212209e9a3fbe8c3b2104a6f54d0435b8ef745341a5adef9d1a0129ff6e7036cee45764736f6c63430008170033000000000000000000000000e6ad5a88f5da0f276c903d9ac2647a937c917162
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610085575f3560e01c8063c87b1ae311610058578063c87b1ae3146100fc578063d38bfff41461010f578063f340fa0114610122578063f39c38a014610135575f80fd5b8063238efcbc146100895780635aa6e67514610093578063714ccf7b146100c1578063a622ee7c146100d4575b5f80fd5b610091610148565b005b5f546100a5906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b6100916100cf366004610a61565b6101f3565b6100a56100e2366004610a92565b60026020525f90815260409020546001600160a01b031681565b61009161010a366004610afa565b610251565b61009161011d366004610a92565b6103e5565b610091610130366004610a92565b61047b565b6001546100a5906001600160a01b031681565b6001546001600160a01b0316331461019d5760405162461bcd60e51b81526020600482015260136024820152722170656e64696e6720676f7665726e616e636560681b60448201526064015b60405180910390fd5b5f805460405133926001600160a01b03909216917f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce8091a35f80546001600160a01b03199081163317909155600180549091169055565b6101fb61058a565b6001600160a01b038281165f8181526002602052604080822080546001600160a01b0319169486169485179055517f8800deb8c31293b539eaf5391fcc88280dc58f015c043d65dd5b72a0979a1dd19190a35050565b61025961058a565b6001600160a01b038086165f9081526002602052604090205416806102b25760405162461bcd60e51b815260206004820152600f60248201526e15985d5b1d081b9bdd08199bdd5b99608a1b6044820152606401610194565b6040516370a0823160e01b81523060048201525f906001600160a01b038816906370a0823190602401602060405180830381865afa1580156102f6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061031a9190610b75565b9050801561032d5761032d8783836105d3565b84831461036d5760405162461bcd60e51b815260206004820152600e60248201526d092dcecc2d8d2c840d8cadccee8d60931b6044820152606401610194565b5f5b858110156103db576103d387878381811061038c5761038c610b8c565b90506020020160208101906103a19190610a92565b8686848181106103b3576103b3610b8c565b90506020020135856001600160a01b031661065b9092919063ffffffff16565b60010161036f565b5050505050505050565b6103ed61058a565b6001600160a01b0381166104325760405162461bcd60e51b815260206004820152600c60248201526b5a45524f204144445245535360a01b6044820152606401610194565b600180546001600160a01b0319166001600160a01b0383169081179091556040517fa443b483867b0f9db5b03913474dd21935ac5ba70fa6c94e3423ba9be157c44b905f90a250565b6001600160a01b038082165f9081526002602052604090205416806104d45760405162461bcd60e51b815260206004820152600f60248201526e15985d5b1d081b9bdd08199bdd5b99608a1b6044820152606401610194565b6040516370a0823160e01b81523060048201525f906001600160a01b038416906370a0823190602401602060405180830381865afa158015610518573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061053c9190610b75565b90505f811161057a5760405162461bcd60e51b815260206004820152600a6024820152694e6f2062616c616e636560b01b6044820152606401610194565b6105858383836105d3565b505050565b5f546001600160a01b031633146105d15760405162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b6044820152606401610194565b565b6105e76001600160a01b03841683836106be565b604051636e553f6560e01b8152600481018290523060248201526001600160a01b03831690636e553f65906044016020604051808303815f875af1158015610631573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106559190610b75565b50505050565b6040516001600160a01b03831660248201526044810182905261058590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610748565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261070f848261081b565b610655576040516001600160a01b03841660248201525f604482015261074290859063095ea7b360e01b90606401610687565b61065584825b5f61079c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166108bc9092919063ffffffff16565b905080515f14806107bc5750808060200190518101906107bc9190610ba0565b6105855760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610194565b5f805f846001600160a01b0316846040516108369190610be1565b5f604051808303815f865af19150503d805f811461086f576040519150601f19603f3d011682016040523d82523d5f602084013e610874565b606091505b509150915081801561089e57508051158061089e57508080602001905181019061089e9190610ba0565b80156108b357506001600160a01b0385163b15155b95945050505050565b60606108ca84845f856108d2565b949350505050565b6060824710156109335760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610194565b5f80866001600160a01b0316858760405161094e9190610be1565b5f6040518083038185875af1925050503d805f8114610988576040519150601f19603f3d011682016040523d82523d5f602084013e61098d565b606091505b509150915061099e878383876109a9565b979650505050505050565b60608315610a175782515f03610a10576001600160a01b0385163b610a105760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610194565b50816108ca565b6108ca8383815115610a2c5781518083602001fd5b8060405162461bcd60e51b81526004016101949190610bfc565b80356001600160a01b0381168114610a5c575f80fd5b919050565b5f8060408385031215610a72575f80fd5b610a7b83610a46565b9150610a8960208401610a46565b90509250929050565b5f60208284031215610aa2575f80fd5b610aab82610a46565b9392505050565b5f8083601f840112610ac2575f80fd5b50813567ffffffffffffffff811115610ad9575f80fd5b6020830191508360208260051b8501011115610af3575f80fd5b9250929050565b5f805f805f60608688031215610b0e575f80fd5b610b1786610a46565b9450602086013567ffffffffffffffff80821115610b33575f80fd5b610b3f89838a01610ab2565b90965094506040880135915080821115610b57575f80fd5b50610b6488828901610ab2565b969995985093965092949392505050565b5f60208284031215610b85575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215610bb0575f80fd5b81518015158114610aab575f80fd5b5f5b83811015610bd9578181015183820152602001610bc1565b50505f910152565b5f8251610bf2818460208701610bbf565b9190910192915050565b602081525f8251806020840152610c1a816040850160208701610bbf565b601f01601f1916919091016040019291505056fea26469706673582212209e9a3fbe8c3b2104a6f54d0435b8ef745341a5adef9d1a0129ff6e7036cee45764736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e6ad5a88f5da0f276c903d9ac2647a937c917162
-----Decoded View---------------
Arg [0] : _owner (address): 0xe6ad5A88f5da0F276C903d9Ac2647A937c917162
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000e6ad5a88f5da0f276c903d9ac2647a937c917162
Deployed Bytecode Sourcemap
60779:1668:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20512:267;;;:::i;:::-;;18058:25;;;;;-1:-1:-1;;;;;18058:25:0;;;;;;-1:-1:-1;;;;;178:32:1;;;160:51;;148:2;133:18;18058:25:0;;;;;;;61631:156;;;;;;:::i;:::-;;:::i;60965:41::-;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;60965:41:0;;;61795:649;;;;;;:::i;:::-;;:::i;20136:283::-;;;;;;:::i;:::-;;:::i;61077:306::-;;;;;;:::i;:::-;;:::i;19812:32::-;;;;;-1:-1:-1;;;;;19812:32:0;;;20512:267;20590:17;;-1:-1:-1;;;;;20590:17:0;20576:10;:31;20568:63;;;;-1:-1:-1;;;20568:63:0;;2282:2:1;20568:63:0;;;2264:21:1;2321:2;2301:18;;;2294:30;-1:-1:-1;;;2340:18:1;;;2333:49;2399:18;;20568:63:0;;;;;;;;;20671:10;;;20649:45;;20683:10;;-1:-1:-1;;;;;20671:10:0;;;;20649:45;;;20707:10;:23;;-1:-1:-1;;;;;;20707:23:0;;;20720:10;20707:23;;;;;20741:30;;;;;;;20512:267::o;61631:156::-;17754:18;:16;:18::i;:::-;-1:-1:-1;;;;;61716:14:0;;::::1;;::::0;;;:6:::1;:14;::::0;;;;;:23;;-1:-1:-1;;;;;;61716:23:0::1;::::0;;::::1;::::0;;::::1;::::0;;61755:24;::::1;::::0;61716:14;61755:24:::1;61631:156:::0;;:::o;61795:649::-;17754:18;:16;:18::i;:::-;-1:-1:-1;;;;;61980:14:0;;::::1;61958:12;61980:14:::0;;;:6:::1;:14;::::0;;;;;::::1;::::0;62006:56:::1;;;::::0;-1:-1:-1;;;62006:56:0;;2630:2:1;62006:56:0::1;::::0;::::1;2612:21:1::0;2669:2;2649:18;;;2642:30;-1:-1:-1;;;2688:18:1;;;2681:45;2743:18;;62006:56:0::1;2428:339:1::0;62006:56:0::1;62093:38;::::0;-1:-1:-1;;;62093:38:0;;62125:4:::1;62093:38;::::0;::::1;160:51:1::0;62075:15:0::1;::::0;-1:-1:-1;;;;;62093:23:0;::::1;::::0;::::1;::::0;133:18:1;;62093:38:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62075:56:::0;-1:-1:-1;62146:11:0;;62142:85:::1;;62174:41;62183:6;62199:5;62207:7;62174:8;:41::i;:::-;62247:36:::0;;::::1;62239:63;;;::::0;-1:-1:-1;;;62239:63:0;;3163:2:1;62239:63:0::1;::::0;::::1;3145:21:1::0;3202:2;3182:18;;;3175:30;-1:-1:-1;;;3221:18:1;;;3214:44;3275:18;;62239:63:0::1;2961:338:1::0;62239:63:0::1;62320:9;62315:122;62335:22:::0;;::::1;62315:122;;;62379:46;62398:11;;62410:1;62398:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;62414:7;;62422:1;62414:10;;;;;;;:::i;:::-;;;;;;;62379:5;-1:-1:-1::0;;;;;62379:18:0::1;;;:46;;;;;:::i;:::-;62359:3;;62315:122;;;;61947:497;;61795:649:::0;;;;;:::o;20136:283::-;17754:18;:16;:18::i;:::-;-1:-1:-1;;;;;20264:28:0;::::1;20256:53;;;::::0;-1:-1:-1;;;20256:53:0;;3638:2:1;20256:53:0::1;::::0;::::1;3620:21:1::0;3677:2;3657:18;;;3650:30;-1:-1:-1;;;3696:18:1;;;3689:42;3748:18;;20256:53:0::1;3436:336:1::0;20256:53:0::1;20320:17;:34:::0;;-1:-1:-1;;;;;;20320:34:0::1;-1:-1:-1::0;;;;;20320:34:0;::::1;::::0;;::::1;::::0;;;20372:39:::1;::::0;::::1;::::0;-1:-1:-1;;20372:39:0::1;20136:283:::0;:::o;61077:306::-;-1:-1:-1;;;;;61144:14:0;;;61128:13;61144:14;;;:6;:14;;;;;;;;61169:47;;;;-1:-1:-1;;;61169:47:0;;2630:2:1;61169:47:0;;;2612:21:1;2669:2;2649:18;;;2642:30;-1:-1:-1;;;2688:18:1;;;2681:45;2743:18;;61169:47:0;2428:339:1;61169:47:0;61247:38;;-1:-1:-1;;;61247:38:0;;61279:4;61247:38;;;160:51:1;61229:15:0;;-1:-1:-1;;;;;61247:23:0;;;;;133:18:1;;61247:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61229:56;;61314:1;61304:7;:11;61296:34;;;;-1:-1:-1;;;61296:34:0;;3979:2:1;61296:34:0;;;3961:21:1;4018:2;3998:18;;;3991:30;-1:-1:-1;;;4037:18:1;;;4030:40;4087:18;;61296:34:0;3777:334:1;61296:34:0;61343:32;61352:6;61360:5;61367:7;61343:8;:32::i;:::-;61117:266;;61077:306;:::o;17861:117::-;17930:10;;-1:-1:-1;;;;;17930:10:0;17944;17930:24;17922:48;;;;-1:-1:-1;;;17922:48:0;;4318:2:1;17922:48:0;;;4300:21:1;4357:2;4337:18;;;4330:30;-1:-1:-1;;;4376:18:1;;;4369:41;4427:18;;17922:48:0;4116:335:1;17922:48:0;17861:117::o;61391:232::-;61513:44;-1:-1:-1;;;;;61513:26:0;;61540:6;61548:8;61513:26;:44::i;:::-;61568:47;;-1:-1:-1;;;61568:47:0;;;;;4630:25:1;;;61609:4:0;4671:18:1;;;4664:60;-1:-1:-1;;;;;61568:22:0;;;;;4603:18:1;;61568:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;61391:232;;;:::o;47095:177::-;47205:58;;-1:-1:-1;;;;;4927:32:1;;47205:58:0;;;4909:51:1;4976:18;;;4969:34;;;47178:86:0;;47198:5;;-1:-1:-1;;;47228:23:0;4882:18:1;;47205:58:0;;;;-1:-1:-1;;47205:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;47205:58:0;-1:-1:-1;;;;;;47205:58:0;;;;;;;;;;47178:19;:86::i;49989:417::-;50105:62;;;-1:-1:-1;;;;;4927:32:1;;50105:62:0;;;4909:51:1;4976:18;;;;4969:34;;;50105:62:0;;;;;;;;;;4882:18:1;;;;50105:62:0;;;;;;;;-1:-1:-1;;;;;50105:62:0;-1:-1:-1;;;50105:62:0;;;50185:44;50209:5;50105:62;50185:23;:44::i;:::-;50180:219;;50273:58;;-1:-1:-1;;;;;5212:32:1;;50273:58:0;;;5194:51:1;50329:1:0;5261:18:1;;;5254:45;50246:86:0;;50266:5;;-1:-1:-1;;;50296:22:0;5167:18:1;;50273:58:0;5014:291:1;50246:86:0;50347:40;50367:5;50374:12;51441:649;51865:23;51891:69;51919:4;51891:69;;;;;;;;;;;;;;;;;51899:5;-1:-1:-1;;;;;51891:27:0;;;:69;;;;;:::i;:::-;51865:95;;51979:10;:17;52000:1;51979:22;:56;;;;52016:10;52005:30;;;;;;;;;;;;:::i;:::-;51971:111;;;;-1:-1:-1;;;51971:111:0;;5794:2:1;51971:111:0;;;5776:21:1;5833:2;5813:18;;;5806:30;5872:34;5852:18;;;5845:62;-1:-1:-1;;;5923:18:1;;;5916:40;5973:19;;51971:111:0;5592:406:1;52601:602:0;52684:4;52991:12;53005:23;53040:5;-1:-1:-1;;;;;53032:19:0;53052:4;53032:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52990:67;;;;53088:7;:69;;;;-1:-1:-1;53100:17:0;;:22;;:56;;;53137:10;53126:30;;;;;;;;;;;;:::i;:::-;53088:107;;;;-1:-1:-1;;;;;;8576:19:0;;;:23;;53161:34;53068:127;52601:602;-1:-1:-1;;;;;52601:602:0:o;11036:229::-;11173:12;11205:52;11227:6;11235:4;11241:1;11244:12;11205:21;:52::i;:::-;11198:59;11036:229;-1:-1:-1;;;;11036:229:0:o;12122:455::-;12292:12;12350:5;12325:21;:30;;12317:81;;;;-1:-1:-1;;;12317:81:0;;6752:2:1;12317:81:0;;;6734:21:1;6791:2;6771:18;;;6764:30;6830:34;6810:18;;;6803:62;-1:-1:-1;;;6881:18:1;;;6874:36;6927:19;;12317:81:0;6550:402:1;12317:81:0;12410:12;12424:23;12451:6;-1:-1:-1;;;;;12451:11:0;12470:5;12477:4;12451:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12409:73;;;;12500:69;12527:6;12535:7;12544:10;12556:12;12500:26;:69::i;:::-;12493:76;12122:455;-1:-1:-1;;;;;;;12122:455:0:o;14695:644::-;14880:12;14909:7;14905:427;;;14937:10;:17;14958:1;14937:22;14933:290;;-1:-1:-1;;;;;8576:19:0;;;15147:60;;;;-1:-1:-1;;;15147:60:0;;7159:2:1;15147:60:0;;;7141:21:1;7198:2;7178:18;;;7171:30;7237:31;7217:18;;;7210:59;7286:18;;15147:60:0;6957:353:1;15147:60:0;-1:-1:-1;15244:10:0;15237:17;;14905:427;15287:33;15295:10;15307:12;16042:17;;:21;16038:388;;16274:10;16268:17;16331:15;16318:10;16314:2;16310:19;16303:44;16038:388;16401:12;16394:20;;-1:-1:-1;;;16394:20:0;;;;;;;;:::i;222:173:1:-;290:20;;-1:-1:-1;;;;;339:31:1;;329:42;;319:70;;385:1;382;375:12;319:70;222:173;;;:::o;400:260::-;468:6;476;529:2;517:9;508:7;504:23;500:32;497:52;;;545:1;542;535:12;497:52;568:29;587:9;568:29;:::i;:::-;558:39;;616:38;650:2;639:9;635:18;616:38;:::i;:::-;606:48;;400:260;;;;;:::o;665:186::-;724:6;777:2;765:9;756:7;752:23;748:32;745:52;;;793:1;790;783:12;745:52;816:29;835:9;816:29;:::i;:::-;806:39;665:186;-1:-1:-1;;;665:186:1:o;856:367::-;919:8;929:6;983:3;976:4;968:6;964:17;960:27;950:55;;1001:1;998;991:12;950:55;-1:-1:-1;1024:20:1;;1067:18;1056:30;;1053:50;;;1099:1;1096;1089:12;1053:50;1136:4;1128:6;1124:17;1112:29;;1196:3;1189:4;1179:6;1176:1;1172:14;1164:6;1160:27;1156:38;1153:47;1150:67;;;1213:1;1210;1203:12;1150:67;856:367;;;;;:::o;1228:847::-;1359:6;1367;1375;1383;1391;1444:2;1432:9;1423:7;1419:23;1415:32;1412:52;;;1460:1;1457;1450:12;1412:52;1483:29;1502:9;1483:29;:::i;:::-;1473:39;;1563:2;1552:9;1548:18;1535:32;1586:18;1627:2;1619:6;1616:14;1613:34;;;1643:1;1640;1633:12;1613:34;1682:70;1744:7;1735:6;1724:9;1720:22;1682:70;:::i;:::-;1771:8;;-1:-1:-1;1656:96:1;-1:-1:-1;1859:2:1;1844:18;;1831:32;;-1:-1:-1;1875:16:1;;;1872:36;;;1904:1;1901;1894:12;1872:36;;1943:72;2007:7;1996:8;1985:9;1981:24;1943:72;:::i;:::-;1228:847;;;;-1:-1:-1;1228:847:1;;-1:-1:-1;2034:8:1;;1917:98;1228:847;-1:-1:-1;;;1228:847:1:o;2772:184::-;2842:6;2895:2;2883:9;2874:7;2870:23;2866:32;2863:52;;;2911:1;2908;2901:12;2863:52;-1:-1:-1;2934:16:1;;2772:184;-1:-1:-1;2772:184:1:o;3304:127::-;3365:10;3360:3;3356:20;3353:1;3346:31;3396:4;3393:1;3386:15;3420:4;3417:1;3410:15;5310:277;5377:6;5430:2;5418:9;5409:7;5405:23;5401:32;5398:52;;;5446:1;5443;5436:12;5398:52;5478:9;5472:16;5531:5;5524:13;5517:21;5510:5;5507:32;5497:60;;5553:1;5550;5543:12;6003:250;6088:1;6098:113;6112:6;6109:1;6106:13;6098:113;;;6188:11;;;6182:18;6169:11;;;6162:39;6134:2;6127:10;6098:113;;;-1:-1:-1;;6245:1:1;6227:16;;6220:27;6003:250::o;6258:287::-;6387:3;6425:6;6419:13;6441:66;6500:6;6495:3;6488:4;6480:6;6476:17;6441:66;:::i;:::-;6523:16;;;;;6258:287;-1:-1:-1;;6258:287:1:o;7315:396::-;7464:2;7453:9;7446:21;7427:4;7496:6;7490:13;7539:6;7534:2;7523:9;7519:18;7512:34;7555:79;7627:6;7622:2;7611:9;7607:18;7602:2;7594:6;7590:15;7555:79;:::i;:::-;7695:2;7674:15;-1:-1:-1;;7670:29:1;7655:45;;;;7702:2;7651:54;;7315:396;-1:-1:-1;;7315:396:1:o
Swarm Source
ipfs://9e9a3fbe8c3b2104a6f54d0435b8ef745341a5adef9d1a0129ff6e7036cee457
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.