Overview
S Balance
0 S
S Value
-More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
434374 | 18 days ago | Contract Creation | 0 S |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
FluidWalletImplementation
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 10000000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; import { IERC721 } from "@openzeppelin/contracts/interfaces/IERC721.sol"; import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol"; import { SafeTransfer } from "../../../libraries/safeTransfer.sol"; import { Clones } from "@openzeppelin/contracts/proxy/Clones.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { IFluidVaultFactory } from "../../../protocols/vault/interfaces/iVaultFactory.sol"; import { IFluidVaultT1 } from "../../../protocols/vault/interfaces/iVaultT1.sol"; import { IFluidVault } from "../../../protocols/vault/interfaces/iVault.sol"; interface IFluidWalletFactory { function WALLET_PROXY() external view returns(address); } interface InstaFlashReceiverInterface { function executeOperation( address[] calldata assets, uint256[] calldata amounts, uint256[] calldata premiums, address initiator, bytes calldata _data ) external returns (bool); } abstract contract FluidWalletVariables { /***********************************| | Constants/Immutables | |__________________________________*/ string public constant VERSION = "1.1.0"; address public constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; uint256 internal constant X32 = 0xffffffff; address public immutable VAULT_FACTORY; address public immutable FLUID_WALLET_FACTORY; /***********************************| | Slot 0 | |__________________________________*/ /// @dev owner address of this wallet. It is initialized while deploying the wallet for the user. address public owner; /***********************************| | Slot 1 | |__________________________________*/ /// @dev transient allow hash used to signal allowing certain entry into methods such as executeOperation etc. bytes32 internal _transientAllowHash; function _resetTransientStorage() internal { assembly { sstore(1, 1) // Store 1 in the transient storage 1 } } } contract FluidWalletErrorsAndEvents { error FluidWallet__NotAllowed(); error FluidWallet__ToHexDigit(); error FluidWallet__Unauthorized(); event Executed( address indexed owner, uint256 indexed tokenId ); event ExecutedCast(address indexed owner); struct Action { address target; bytes data; uint256 value; uint8 operation; } } contract FluidWalletImplementation is FluidWalletVariables, FluidWalletErrorsAndEvents { constructor( address vaultFactory_, address fluidWalletFactory_ ) { VAULT_FACTORY = vaultFactory_; FLUID_WALLET_FACTORY = fluidWalletFactory_; } /// @dev ERC721 callback used Fluid Vault Factory and executes actions encoded in `data_` /// Caller should be Fluid Wallet Factory. /// @param operator_ operator_ caller to transfer the the given token ID /// @param from_ from_ previous owner of the given token ID /// @param tokenId_ tokenId_ id of the ERC721 /// @param data_ data bytes containing the `abi.encoded()` actions that are executed like in `Action[]` & `owner` function onERC721Received( address operator_, address from_, uint256 tokenId_, bytes calldata data_ ) external returns (bytes4) { if (msg.sender != address(VAULT_FACTORY)) revert FluidWallet__NotAllowed(); if (operator_ != from_) revert FluidWallet__NotAllowed(); if (operator_ != FLUID_WALLET_FACTORY) revert FluidWallet__NotAllowed(); (address owner_, Action[] memory actions_) = abi.decode(data_, (address, Action[])); /// @dev validate owner by computing wallet address. _validateOwner(owner_); /// @dev execute actions. _executeActions(actions_); /// @dev reset _transientAllowHash to prevent reentrancy _resetTransientStorage(); // Transfer tokenId back to main owner if (IERC721(VAULT_FACTORY).ownerOf(tokenId_) == address(this)) { IERC721(VAULT_FACTORY).transferFrom(address(this), owner_, tokenId_); } // sweep vault specific tokens to owner address _sweepTokens(owner_, tokenId_); emit Executed(owner_, tokenId_); return this.onERC721Received.selector; } function cast( Action[] memory actions_ ) public { /// @dev validate owner by computing wallet address. _validateOwner(msg.sender); /// @dev execute actions. _executeActions(actions_); /// @dev reset _transientAllowHash to prevent reentrancy _resetTransientStorage(); emit ExecutedCast(msg.sender); } /***********************************| | FLASHLOAN CALLBACK | |__________________________________*/ /// @dev callback used by Instadapp Flashloan Aggregator, executes operations while owning /// the flashloaned amounts. `data_` must contain actions, one of them must pay back flashloan // /// @param assets_ assets_ received a flashloan for // /// @param amounts_ flashloaned amounts for each asset // /// @param premiums_ fees to pay for the flashloan /// @param initiator_ flashloan initiator -> must be this contract /// @param data_ data bytes containing the `abi.encoded()` actions that are executed like in `CastParams.actions` function executeOperation( address[] calldata /* assets */, uint256[] calldata /* amounts */, uint256[] calldata /* premiums */, address initiator_, bytes calldata data_ ) external returns (bool) { if ( !(_transientAllowHash == bytes32(keccak256(abi.encode(data_, block.timestamp))) && initiator_ == address(this)) ) { revert FluidWallet__Unauthorized(); } _executeActions(abi.decode(data_, (Action[]))); return true; } /***********************************| | INTERNAL HELPERS | |__________________________________*/ /// @notice Calculating the slot ID for Liquidity contract for single mapping function _calculateStorageSlotUintMapping(uint256 slot_, uint key_) internal pure returns (bytes32) { return keccak256(abi.encode(key_, slot_)); } struct VaultConstants { address supplyToken0; address supplyToken1; address borrowToken0; address borrowToken1; } function _sweepTokens(address owner_, uint256 tokenId_) internal { uint256 tokenConfig_ = IFluidVaultFactory(VAULT_FACTORY).readFromStorage(_calculateStorageSlotUintMapping(3, tokenId_)); address vaultAddress_ = IFluidVaultFactory(VAULT_FACTORY).getVaultAddress((tokenConfig_ >> 192) & X32); VaultConstants memory constants_ = _getVaultConstants(vaultAddress_); _flushTokens(constants_.supplyToken0, owner_); _flushTokens(constants_.supplyToken1, owner_); _flushTokens(constants_.borrowToken0, owner_); _flushTokens(constants_.borrowToken1, owner_); } function _getVaultConstants(address vault_) internal view returns (VaultConstants memory constants_) { if (vault_.code.length == 0) { return constants_; } try IFluidVault(vault_).TYPE() returns (uint256 type_) { IFluidVault.ConstantViews memory vaultConstants_ = IFluidVault(vault_).constantsView(); constants_.supplyToken0 = vaultConstants_.supplyToken.token0; constants_.supplyToken1 = vaultConstants_.supplyToken.token1; constants_.borrowToken0 = vaultConstants_.borrowToken.token0; constants_.borrowToken1 = vaultConstants_.borrowToken.token1; } catch { IFluidVaultT1.ConstantViews memory vaultConstants_ = IFluidVaultT1(vault_).constantsView(); constants_.supplyToken0 = vaultConstants_.supplyToken; constants_.supplyToken1 = address(0); constants_.borrowToken0 = vaultConstants_.borrowToken; constants_.borrowToken1 = address(0); } } function _flushTokens(address token_, address owner_) internal { if (token_ == address(0)) return; if (token_ == ETH_ADDRESS) { uint256 balance_ = address(this).balance; if (balance_ > 0) SafeTransfer.safeTransferNative(payable(owner_), balance_); } else { uint256 balance_ = IERC20(token_).balanceOf(address(this)); if (balance_ > 0) SafeTransfer.safeTransfer(token_, owner_, balance_); } } /// @dev validate `owner` by recomputing fluid address. function _validateOwner(address owner_) internal view { address wallet_ = Clones.predictDeterministicAddress( IFluidWalletFactory(FLUID_WALLET_FACTORY).WALLET_PROXY(), keccak256(abi.encode(owner_)), FLUID_WALLET_FACTORY ); if (wallet_ != address(this)) revert FluidWallet__NotAllowed(); } /// @dev executes `actions_` with respective target, calldata, operation etc. function _executeActions(Action[] memory actions_) internal { uint256 actionsLength_ = actions_.length; for (uint256 i; i < actionsLength_; ) { Action memory action_ = actions_[i]; // execute action bool success_; bytes memory result_; if (action_.operation == 0) { // call (operation = 0) // low-level call will return success true also if action target is not even a contract. // we do not explicitly check for this, default interaction is via UI which can check and handle this. // Also applies to delegatecall etc. (success_, result_) = action_.target.call{ value: action_.value }(action_.data); // handle action failure right after external call to better detect out of gas errors if (!success_) { _handleActionFailure(i, result_); } } else if (action_.operation == 1) { // delegatecall (operation = 1) (success_, result_) = action_.target.delegatecall(action_.data); // reset _transientAllowHash to make sure it can not be set up in any way for reentrancy _resetTransientStorage(); // handle action failure right after external call to better detect out of gas errors if (!success_) { _handleActionFailure(i, result_); } } else if (action_.operation == 2) { // flashloan (operation = 2) // flashloan is always executed via .call, flashloan aggregator uses `msg.sender`, so .delegatecall // wouldn't send funds to this contract but rather to the original sender. bytes memory data_ = action_.data; assembly { data_ := add(data_, 4) // Skip function selector (4 bytes) } // get actions data from calldata action_.data. Only supports InstaFlashAggregatorInterface (, , , data_, ) = abi.decode(data_, (address[], uint256[], uint256, bytes, bytes)); // set allowHash to signal allowed entry into executeOperation() _transientAllowHash = bytes32( keccak256(abi.encode(data_, block.timestamp)) ); // handle action failure right after external call to better detect out of gas errors (success_, result_) = action_.target.call{ value: action_.value }(action_.data); if (!success_) { _handleActionFailure(i, result_); } // reset _transientAllowHash to prevent reentrancy during actions execution _resetTransientStorage(); } else { // either operation does not exist or the id was not set according to what the action wants to execute revert(string.concat(Strings.toString(i), "_FLUID__INVALID_ID_OR_OPERATION")); } unchecked { ++i; } } } /// @dev handles failure of an action execution depending on error cause, /// decoding and reverting with `result_` as reason string. function _handleActionFailure(uint256 i_, bytes memory result_) internal pure { revert(string.concat(Strings.toString(i_), _getRevertReasonFromReturnedData(result_))); } uint256 internal constant REVERT_REASON_MAX_LENGTH = 250; /// @dev Get the revert reason from the returnedData (supports Panic, Error & Custom Errors). /// Based on https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/ethereum-contracts/contracts/libs/CallUtils.sol /// This is needed in order to provide some human-readable revert message from a call. /// @param returnedData_ revert data of the call /// @return reason_ revert reason function _getRevertReasonFromReturnedData( bytes memory returnedData_ ) internal pure returns (string memory reason_) { if (returnedData_.length < 4) { // case 1: catch all return "_REASON_NOT_DEFINED"; } bytes4 errorSelector_; assembly { errorSelector_ := mload(add(returnedData_, 0x20)) } if (errorSelector_ == bytes4(0x4e487b71)) { // case 2: Panic(uint256), selector 0x4e487b71 (Defined since 0.8.0) // ref: https://docs.soliditylang.org/en/v0.8.0/control-structures.html#panic-via-assert-and-error-via-require) // convert last byte to hex digits -> string to decode the panic code bytes memory result_ = new bytes(2); result_[0] = _toHexDigit(uint8(returnedData_[returnedData_.length - 1]) / 16); result_[1] = _toHexDigit(uint8(returnedData_[returnedData_.length - 1]) % 16); reason_ = string.concat("_TARGET_PANICKED: 0x", string(result_)); } else if (errorSelector_ == bytes4(0x08c379a0)) { // case 3: Error(string), selector 0x08c379a0 (Defined at least since 0.7.0) // based on https://ethereum.stackexchange.com/a/83577 assembly { returnedData_ := add(returnedData_, 0x04) } reason_ = string.concat("_", abi.decode(returnedData_, (string))); } else { // case 4: Custom errors (Defined since 0.8.0) // convert bytes4 selector to string, params are ignored... // based on https://ethereum.stackexchange.com/a/111876 bytes memory result_ = new bytes(8); for (uint256 i; i < 4; ) { // use unchecked as i is < 4 and division. also errorSelector can not underflow unchecked { result_[2 * i] = _toHexDigit(uint8(errorSelector_[i]) / 16); result_[2 * i + 1] = _toHexDigit(uint8(errorSelector_[i]) % 16); ++i; } } reason_ = string.concat("_CUSTOM_ERROR: 0x", string(result_)); } { // truncate reason_ string to REVERT_REASON_MAX_LENGTH for reserveGas used to ensure Cast event is emitted if (bytes(reason_).length > REVERT_REASON_MAX_LENGTH) { bytes memory reasonBytes_ = bytes(reason_); uint256 maxLength_ = REVERT_REASON_MAX_LENGTH + 1; // cheaper than <= in each loop bytes memory truncatedRevertReason_ = new bytes(maxLength_); for (uint256 i; i < maxLength_; ) { truncatedRevertReason_[i] = reasonBytes_[i]; unchecked { ++i; } } reason_ = string(truncatedRevertReason_); } } } /// @dev used to convert bytes4 selector to string function _toHexDigit(uint8 d) internal pure returns (bytes1) { // use unchecked as the operations with d can not over / underflow unchecked { if (d < 10) { return bytes1(uint8(bytes1("0")) + d); } if (d < 16) { return bytes1(uint8(bytes1("a")) + d - 10); } } revert FluidWallet__ToHexDigit(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol) pragma solidity ^0.8.0; import "../token/ERC721/IERC721.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (proxy/Clones.sol) pragma solidity ^0.8.0; /** * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for * deploying minimal proxy contracts, also known as "clones". * * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies * > a minimal bytecode implementation that delegates all calls to a known, fixed address. * * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the * deterministic method. * * _Available since v3.4._ */ library Clones { /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create opcode, which should never revert. */ function clone(address implementation) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create(0, 0x09, 0x37) } require(instance != address(0), "ERC1167: create failed"); } /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create2 opcode and a `salt` to deterministically deploy * the clone. Using the same `implementation` and `salt` multiple time will revert, since * the clones cannot be deployed twice at the same address. */ function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create2(0, 0x09, 0x37, salt) } require(instance != address(0), "ERC1167: create2 failed"); } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(add(ptr, 0x38), deployer) mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff) mstore(add(ptr, 0x14), implementation) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73) mstore(add(ptr, 0x58), salt) mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37)) predicted := keccak256(add(ptr, 0x43), 0x55) } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress(address implementation, bytes32 salt) internal view returns (address predicted) { return predictDeterministicAddress(implementation, salt, address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; library LibsErrorTypes { /***********************************| | LiquidityCalcs | |__________________________________*/ /// @notice thrown when supply or borrow exchange price is zero at calc token data (token not configured yet) uint256 internal constant LiquidityCalcs__ExchangePriceZero = 70001; /// @notice thrown when rate data is set to a version that is not implemented uint256 internal constant LiquidityCalcs__UnsupportedRateVersion = 70002; /// @notice thrown when the calculated borrow rate turns negative. This should never happen. uint256 internal constant LiquidityCalcs__BorrowRateNegative = 70003; /***********************************| | SafeTransfer | |__________________________________*/ /// @notice thrown when safe transfer from for an ERC20 fails uint256 internal constant SafeTransfer__TransferFromFailed = 71001; /// @notice thrown when safe transfer for an ERC20 fails uint256 internal constant SafeTransfer__TransferFailed = 71002; /***********************************| | SafeApprove | |__________________________________*/ /// @notice thrown when safe approve from for an ERC20 fails uint256 internal constant SafeApprove__ApproveFailed = 81001; }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.21; import { LibsErrorTypes as ErrorTypes } from "./errorTypes.sol"; /// @notice provides minimalistic methods for safe transfers, e.g. ERC20 safeTransferFrom library SafeTransfer { uint256 internal constant MAX_NATIVE_TRANSFER_GAS = 20000; // pass max. 20k gas for native transfers error FluidSafeTransferError(uint256 errorId_); /// @dev Transfer `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. /// Minimally modified from Solmate SafeTransferLib (address as input param for token, Custom Error): /// https://github.com/transmissions11/solmate/blob/50e15bb566f98b7174da9b0066126a4c3e75e0fd/src/utils/SafeTransferLib.sol#L31-L63 function safeTransferFrom(address token_, address from_, address to_, uint256 amount_) internal { bool success_; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(from_, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from_" argument. mstore(add(freeMemoryPointer, 36), and(to_, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to_" argument. mstore(add(freeMemoryPointer, 68), amount_) // Append the "amount_" argument. Masking not required as it's a full 32 byte type. success_ := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token_, 0, freeMemoryPointer, 100, 0, 32) ) } if (!success_) { revert FluidSafeTransferError(ErrorTypes.SafeTransfer__TransferFromFailed); } } /// @dev Transfer `amount_` of `token_` to `to_`. /// If `token_` returns no value, non-reverting calls are assumed to be successful. /// Minimally modified from Solmate SafeTransferLib (address as input param for token, Custom Error): /// https://github.com/transmissions11/solmate/blob/50e15bb566f98b7174da9b0066126a4c3e75e0fd/src/utils/SafeTransferLib.sol#L65-L95 function safeTransfer(address token_, address to_, uint256 amount_) internal { bool success_; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(to_, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to_" argument. mstore(add(freeMemoryPointer, 36), amount_) // Append the "amount_" argument. Masking not required as it's a full 32 byte type. success_ := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token_, 0, freeMemoryPointer, 68, 0, 32) ) } if (!success_) { revert FluidSafeTransferError(ErrorTypes.SafeTransfer__TransferFailed); } } /// @dev Transfer `amount_` of ` native token to `to_`. /// Minimally modified from Solmate SafeTransferLib (Custom Error): /// https://github.com/transmissions11/solmate/blob/50e15bb566f98b7174da9b0066126a4c3e75e0fd/src/utils/SafeTransferLib.sol#L15-L25 function safeTransferNative(address to_, uint256 amount_) internal { bool success_; /// @solidity memory-safe-assembly assembly { // Transfer the ETH and store if it succeeded or not. Pass limited gas success_ := call(MAX_NATIVE_TRANSFER_GAS, to_, amount_, 0, 0, 0, 0) } if (!success_) { revert FluidSafeTransferError(ErrorTypes.SafeTransfer__TransferFailed); } } }
//SPDX-License-Identifier: MIT pragma solidity 0.8.21; /// @notice common Fluid vaults interface, some methods only available for vaults > T1 (type, simulateLiquidate, rebalance is different) interface IFluidVault { /// @notice returns the vault id function VAULT_ID() external view returns (uint256); /// @notice returns the vault id function TYPE() external view returns (uint256); /// @notice reads uint256 data `result_` from storage at a bytes32 storage `slot_` key. function readFromStorage(bytes32 slot_) external view returns (uint256 result_); struct Tokens { address token0; address token1; } struct ConstantViews { address liquidity; address factory; address operateImplementation; address adminImplementation; address secondaryImplementation; address deployer; // address which deploys oracle address supply; // either liquidity layer or DEX protocol address borrow; // either liquidity layer or DEX protocol Tokens supplyToken; // if smart collateral then address of token0 & token1 else just supply token address at token0 and token1 as empty Tokens borrowToken; // if smart debt then address of token0 & token1 else just borrow token address at token0 and token1 as empty uint256 vaultId; uint256 vaultType; bytes32 supplyExchangePriceSlot; // if smart collateral then slot is from DEX protocol else from liquidity layer bytes32 borrowExchangePriceSlot; // if smart debt then slot is from DEX protocol else from liquidity layer bytes32 userSupplySlot; // if smart collateral then slot is from DEX protocol else from liquidity layer bytes32 userBorrowSlot; // if smart debt then slot is from DEX protocol else from liquidity layer } /// @notice returns all Vault constants function constantsView() external view returns (ConstantViews memory constantsView_); /// @notice fetches the latest user position after a liquidation function fetchLatestPosition( int256 positionTick_, uint256 positionTickId_, uint256 positionRawDebt_, uint256 tickData_ ) external view returns ( int256, // tick uint256, // raw debt uint256, // raw collateral uint256, // branchID_ uint256 // branchData_ ); /// @notice calculates the updated vault exchange prices function updateExchangePrices( uint256 vaultVariables2_ ) external view returns ( uint256 liqSupplyExPrice_, uint256 liqBorrowExPrice_, uint256 vaultSupplyExPrice_, uint256 vaultBorrowExPrice_ ); /// @notice calculates the updated vault exchange prices and writes them to storage function updateExchangePricesOnStorage() external returns ( uint256 liqSupplyExPrice_, uint256 liqBorrowExPrice_, uint256 vaultSupplyExPrice_, uint256 vaultBorrowExPrice_ ); /// @notice returns the liquidity contract address function LIQUIDITY() external view returns (address); error FluidLiquidateResult(uint256 colLiquidated, uint256 debtLiquidated); function rebalance( int colToken0MinMax_, int colToken1MinMax_, int debtToken0MinMax_, int debtToken1MinMax_ ) external payable returns (int supplyAmt_, int borrowAmt_); /// @notice reverts with FluidLiquidateResult function simulateLiquidate(uint debtAmt_, bool absorb_) external; }
//SPDX-License-Identifier: MIT pragma solidity 0.8.21; import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; interface IFluidVaultFactory is IERC721Enumerable { /// @notice Minting an NFT Vault for the user function mint(uint256 vaultId_, address user_) external returns (uint256 tokenId_); /// @notice returns owner of Vault which is also an NFT function ownerOf(uint256 tokenId) external view returns (address owner); /// @notice Global auth is auth for all vaults function isGlobalAuth(address auth_) external view returns (bool); /// @notice Vault auth is auth for a specific vault function isVaultAuth(address vault_, address auth_) external view returns (bool); /// @notice Total vaults deployed. function totalVaults() external view returns (uint256); /// @notice Compute vaultAddress function getVaultAddress(uint256 vaultId) external view returns (address); /// @notice read uint256 `result_` for a storage `slot_` key function readFromStorage(bytes32 slot_) external view returns (uint256 result_); }
//SPDX-License-Identifier: MIT pragma solidity 0.8.21; interface IFluidVaultT1 { /// @notice returns the vault id function VAULT_ID() external view returns (uint256); /// @notice reads uint256 data `result_` from storage at a bytes32 storage `slot_` key. function readFromStorage(bytes32 slot_) external view returns (uint256 result_); struct ConstantViews { address liquidity; address factory; address adminImplementation; address secondaryImplementation; address supplyToken; address borrowToken; uint8 supplyDecimals; uint8 borrowDecimals; uint vaultId; bytes32 liquiditySupplyExchangePriceSlot; bytes32 liquidityBorrowExchangePriceSlot; bytes32 liquidityUserSupplySlot; bytes32 liquidityUserBorrowSlot; } /// @notice returns all Vault constants function constantsView() external view returns (ConstantViews memory constantsView_); /// @notice fetches the latest user position after a liquidation function fetchLatestPosition( int256 positionTick_, uint256 positionTickId_, uint256 positionRawDebt_, uint256 tickData_ ) external view returns ( int256, // tick uint256, // raw debt uint256, // raw collateral uint256, // branchID_ uint256 // branchData_ ); /// @notice calculates the updated vault exchange prices function updateExchangePrices( uint256 vaultVariables2_ ) external view returns ( uint256 liqSupplyExPrice_, uint256 liqBorrowExPrice_, uint256 vaultSupplyExPrice_, uint256 vaultBorrowExPrice_ ); /// @notice calculates the updated vault exchange prices and writes them to storage function updateExchangePricesOnStorage() external returns ( uint256 liqSupplyExPrice_, uint256 liqBorrowExPrice_, uint256 vaultSupplyExPrice_, uint256 vaultBorrowExPrice_ ); /// @notice returns the liquidity contract address function LIQUIDITY() external view returns (address); function operate( uint256 nftId_, // if 0 then new position int256 newCol_, // if negative then withdraw int256 newDebt_, // if negative then payback address to_ // address at which the borrow & withdraw amount should go to. If address(0) then it'll go to msg.sender ) external payable returns ( uint256, // nftId_ int256, // final supply amount. if - then withdraw int256 // final borrow amount. if - then payback ); function liquidate( uint256 debtAmt_, uint256 colPerUnitDebt_, // min collateral needed per unit of debt in 1e18 address to_, bool absorb_ ) external payable returns (uint actualDebtAmt_, uint actualColAmt_); function absorb() external; function rebalance() external payable returns (int supplyAmt_, int borrowAmt_); error FluidLiquidateResult(uint256 colLiquidated, uint256 debtLiquidated); }
{ "optimizer": { "enabled": true, "runs": 10000000 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"vaultFactory_","type":"address"},{"internalType":"address","name":"fluidWalletFactory_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"errorId_","type":"uint256"}],"name":"FluidSafeTransferError","type":"error"},{"inputs":[],"name":"FluidWallet__NotAllowed","type":"error"},{"inputs":[],"name":"FluidWallet__ToHexDigit","type":"error"},{"inputs":[],"name":"FluidWallet__Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Executed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"ExecutedCast","type":"event"},{"inputs":[],"name":"ETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FLUID_WALLET_FACTORY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VAULT_FACTORY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint8","name":"operation","type":"uint8"}],"internalType":"struct FluidWalletErrorsAndEvents.Action[]","name":"actions_","type":"tuple[]"}],"name":"cast","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"address","name":"initiator_","type":"address"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"executeOperation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator_","type":"address"},{"internalType":"address","name":"from_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b506040516200267d3803806200267d833981016040819052620000349162000069565b6001600160a01b039182166080521660a052620000a1565b80516001600160a01b03811681146200006457600080fd5b919050565b600080604083850312156200007d57600080fd5b62000088836200004c565b915062000098602084016200004c565b90509250929050565b60805160a05161257f620000fe6000396000818161013c015281816102dd0152818161067f015261074501526000818160920152818161021f015281816103d4015281816104ac01528181610b270152610c1e015261257f6000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638da5cb5b1161005b5780638da5cb5b1461015e578063920f5c841461017e578063a734f06e146101a1578063ffa1ad74146101bc57600080fd5b8063103f29071461008d578063150b7a02146100de57806357b7bf20146101225780636ff66e7914610137575b600080fd5b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100f16100ec36600461185a565b610205565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100d5565b610135610130366004611b97565b610583565b005b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6000546100b49073ffffffffffffffffffffffffffffffffffffffff1681565b61019161018c366004611c19565b6105cc565b60405190151581526020016100d5565b6100b473eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6101f86040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d59190611d62565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610276576040517f52df424e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16146102db576040517f52df424e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610360576040517f52df424e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061036f84860186611d7c565b9150915061037c82610678565b61038581610815565b61038e60018055565b6040517f6352211e00000000000000000000000000000000000000000000000000000000815260048101879052309073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa15801561041b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043f9190611dd7565b73ffffffffffffffffffffffffffffffffffffffff1603610509576040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018890527f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90606401600060405180830381600087803b1580156104f057600080fd5b505af1158015610504573d6000803e3d6000fd5b505050505b6105138287610b23565b604051869073ffffffffffffffffffffffffffffffffffffffff8416907f6f6c6d78a4851d4c222c8404fc92372ee84b7b81054305ae8ea3c83c2dabd42e90600090a3507f150b7a0200000000000000000000000000000000000000000000000000000000979650505050505050565b61058c33610678565b61059581610815565b61059e60018055565b60405133907fd2c4fe7e5a558f9b1b406ce6cd257540e044fe92fa299597ed9656533c6a8c8d90600090a250565b60008282426040516020016105e393929190611df4565b6040516020818303038152906040528051906020012060015414801561061e575073ffffffffffffffffffffffffffffffffffffffff841630145b610654576040517f38b760c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61066861066383850185611b97565b610815565b5060019998505050505050505050565b60006107c07f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ba8df43c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061070c9190611dd7565b6040805173ffffffffffffffffffffffffffffffffffffffff8616602082015201604051602081830303815290604052805190602001207f000000000000000000000000000000000000000000000000000000000000000060405160388101919091526f5af43d82803e903d91602b57fd5bf3ff60248201526014810192909252733d602d80600a3d3981f3363d3d373d3d3d363d73825260588201526037600c8201206078820152605560439091012090565b905073ffffffffffffffffffffffffffffffffffffffff81163014610811576040517f52df424e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b805160005b81811015610b1e57600083828151811061083657610836611e4b565b6020026020010151905060006060826060015160ff166000036108e157826000015173ffffffffffffffffffffffffffffffffffffffff16836040015184602001516040516108859190611e7a565b60006040518083038185875af1925050503d80600081146108c2576040519150601f19603f3d011682016040523d82523d6000602084013e6108c7565b606091505b509092509050816108dc576108dc8482610cd7565b610b10565b826060015160ff1660010361097b57826000015173ffffffffffffffffffffffffffffffffffffffff16836020015160405161091d9190611e7a565b600060405180830381855af49150503d8060008114610958576040519150601f19603f3d011682016040523d82523d6000602084013e61095d565b606091505b50909250905061096c60018055565b816108dc576108dc8482610cd7565b826060015160ff16600203610a9057602083015160048101805190916109a991810160249081019101611f41565b506040519094506109c39350849250429150602001612059565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206001558651918701519087015173ffffffffffffffffffffffffffffffffffffffff909216929091610a2a91611e7a565b60006040518083038185875af1925050503d8060008114610a67576040519150601f19603f3d011682016040523d82523d6000602084013e610a6c565b606091505b50909350915082610a8157610a818583610cd7565b610a8a60018055565b50610b10565b610a9984610cfa565b604051602001610aa9919061207b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610b0791600401611d62565b60405180910390fd5b83600101935050505061081a565b505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b5c736e4610b6c600385610db8565b6040518263ffffffff1660e01b8152600401610b8a91815260200190565b602060405180830381865afa158015610ba7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bcb91906120bc565b6040517fe6bd26a200000000000000000000000000000000000000000000000000000000815260c082901c63ffffffff16600482015290915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e6bd26a290602401602060405180830381865afa158015610c65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c899190611dd7565b90506000610c9682610de7565b9050610ca681600001518661102e565b610cb481602001518661102e565b610cc281604001518661102e565b610cd081606001518661102e565b5050505050565b610ce082610cfa565b610ce98261113f565b604051602001610aa99291906120d5565b60606000610d07836115b4565b600101905060008167ffffffffffffffff811115610d2757610d276118cd565b6040519080825280601f01601f191660200182016040528015610d51576020820181803683370190505b5090508181016020015b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8504945084610d5b57509392505050565b604080516020808201849052818301859052825180830384018152606090920190925280519101205b92915050565b6040805160808101825260008082526020820181905291810182905260608101919091528173ffffffffffffffffffffffffffffffffffffffff163b600003610e2f57919050565b8173ffffffffffffffffffffffffffffffffffffffff1663bb24fe8a6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610eb4575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610eb1918101906120bc565b60015b610f695760008273ffffffffffffffffffffffffffffffffffffffff1663b7791bf26040518163ffffffff1660e01b81526004016101a060405180830381865afa158015610f06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2a919061213e565b608081015173ffffffffffffffffffffffffffffffffffffffff908116845260006020850181905260a090920151166040840152606083015250919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663b7791bf26040518163ffffffff1660e01b815260040161024060405180830381865afa158015610fb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdb9190612280565b610100810180515173ffffffffffffffffffffffffffffffffffffffff9081168652905160209081015182168187015261012090920180515182166040870152519091015116606084015250505b919050565b73ffffffffffffffffffffffffffffffffffffffff821661104d575050565b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff83160161109b57478015610b1e57610b1e8282611696565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112c91906120bc565b90508015610b1e57610b1e8383836116e2565b606060048251101561118457505060408051808201909152601381527f5f524541534f4e5f4e4f545f444546494e454400000000000000000000000000602082015290565b60208201517fb1b7848f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016113105760408051600280825281830190925260009160208201818036833701905050905061122e6010856001875161120791906123c7565b8151811061121757611217611e4b565b0160200151611229919060f81c6123da565b61178c565b8160008151811061124157611241611e4b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506112a66010856001875161128491906123c7565b8151811061129457611294611e4b565b0160200151611229919060f81c6123fc565b816001815181106112b9576112b9611e4b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806040516020016112f9919061241e565b6040516020818303038152906040529250506114d4565b7ff73c8660000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000082160161139957600483019250828060200190518101906113739190612463565b60405160200161138391906124ac565b60405160208183030381529060405291506114d4565b60408051600880825281830190925260009160208201818036833701905050905060005b60048110156114af576113f160108483600481106113dd576113dd611e4b565b1a816113eb576113eb612104565b0461178c565b82826002028151811061140657611406611e4b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611460601084836004811061144c5761144c611e4b565b1a8161145a5761145a612104565b0661178c565b82826002026001018151811061147857611478611e4b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001016113bd565b50806040516020016114c191906124f1565b6040516020818303038152906040529250505b60fa825111156115ae578160006114ed60fa6001612536565b905060008167ffffffffffffffff81111561150a5761150a6118cd565b6040519080825280601f01601f191660200182016040528015611534576020820181803683370190505b50905060005b828110156115a85783818151811061155457611554611e4b565b602001015160f81c60f81b82828151811061157157611571611e4b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161153a565b50935050505b50919050565b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106115fd577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310611629576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061164757662386f26fc10000830492506010015b6305f5e100831061165f576305f5e100830492506008015b612710831061167357612710830492506004015b60648310611685576064830492506002015b600a8310610de15760010192915050565b60008060008060008587614e20f1905080610b1e576040517fdee51a8a0000000000000000000000000000000000000000000000000000000081526201155a6004820152602401610b07565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080611786576040517fdee51a8a0000000000000000000000000000000000000000000000000000000081526201155a6004820152602401610b07565b50505050565b6000600a8260ff1610156117a4575060300160f81b90565b60108260ff1610156117ba575060570160f81b90565b6040517fb0b8d61a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461180e57600080fd5b50565b60008083601f84011261182357600080fd5b50813567ffffffffffffffff81111561183b57600080fd5b60208301915083602082850101111561185357600080fd5b9250929050565b60008060008060006080868803121561187257600080fd5b853561187d816117ec565b9450602086013561188d816117ec565b935060408601359250606086013567ffffffffffffffff8111156118b057600080fd5b6118bc88828901611811565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561191f5761191f6118cd565b60405290565b6040516101a0810167ffffffffffffffff8111828210171561191f5761191f6118cd565b604051610200810167ffffffffffffffff8111828210171561191f5761191f6118cd565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156119b4576119b46118cd565b604052919050565b600067ffffffffffffffff8211156119d6576119d66118cd565b5060051b60200190565b600067ffffffffffffffff8211156119fa576119fa6118cd565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60ff8116811461180e57600080fd5b803561102981611a26565b600082601f830112611a5157600080fd5b81356020611a66611a61836119bc565b61196d565b82815260059290921b84018101918181019086841115611a8557600080fd5b8286015b84811015611b8c57803567ffffffffffffffff80821115611aaa5760008081fd5b81890191506080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215611ae35760008081fd5b611aeb6118fc565b87840135611af8816117ec565b815260408481013584811115611b0e5760008081fd5b85019350603f84018d13611b225760008081fd5b88840135611b32611a61826119e0565b8181528e83838801011115611b475760008081fd5b818387018c83013760008b8383010152808b850152505060609350838501358183015250611b76828501611a35565b9281019290925250845250918301918301611a89565b509695505050505050565b600060208284031215611ba957600080fd5b813567ffffffffffffffff811115611bc057600080fd5b611bcc84828501611a40565b949350505050565b60008083601f840112611be657600080fd5b50813567ffffffffffffffff811115611bfe57600080fd5b6020830191508360208260051b850101111561185357600080fd5b600080600080600080600080600060a08a8c031215611c3757600080fd5b893567ffffffffffffffff80821115611c4f57600080fd5b611c5b8d838e01611bd4565b909b50995060208c0135915080821115611c7457600080fd5b611c808d838e01611bd4565b909950975060408c0135915080821115611c9957600080fd5b611ca58d838e01611bd4565b909750955060608c01359150611cba826117ec565b90935060808b01359080821115611cd057600080fd5b50611cdd8c828d01611811565b915080935050809150509295985092959850929598565b60005b83811015611d0f578181015183820152602001611cf7565b50506000910152565b60008151808452611d30816020860160208601611cf4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d756020830184611d18565b9392505050565b60008060408385031215611d8f57600080fd5b8235611d9a816117ec565b9150602083013567ffffffffffffffff811115611db657600080fd5b611dc285828601611a40565b9150509250929050565b8051611029816117ec565b600060208284031215611de957600080fd5b8151611d75816117ec565b6040815282604082015282846060830137600060608483010152600060607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8601168301019050826020830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008251611e8c818460208701611cf4565b9190910192915050565b600082601f830112611ea757600080fd5b81516020611eb7611a61836119bc565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611b8c5780518352918301918301611eda565b6000611eff611a61846119e0565b9050828152838383011115611f1357600080fd5b611d75836020830184611cf4565b600082601f830112611f3257600080fd5b611d7583835160208501611ef1565b600080600080600060a08688031215611f5957600080fd5b855167ffffffffffffffff80821115611f7157600080fd5b818801915088601f830112611f8557600080fd5b81516020611f95611a61836119bc565b82815260059290921b8401810191818101908c841115611fb457600080fd5b948201945b83861015611fdb578551611fcc816117ec565b82529482019490820190611fb9565b918b0151919950909350505080821115611ff457600080fd5b61200089838a01611e96565b955060408801519450606088015191508082111561201d57600080fd5b61202989838a01611f21565b9350608088015191508082111561203f57600080fd5b5061204c88828901611f21565b9150509295509295909350565b60408152600061206c6040830185611d18565b90508260208301529392505050565b6000825161208d818460208701611cf4565b7f5f464c5549445f5f494e56414c49445f49445f4f525f4f5045524154494f4e00920191825250601f01919050565b6000602082840312156120ce57600080fd5b5051919050565b600083516120e7818460208801611cf4565b8351908301906120fb818360208801611cf4565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b805161102981611a26565b60006101a0828403121561215157600080fd5b612159611925565b61216283611dcc565b815261217060208401611dcc565b602082015261218160408401611dcc565b604082015261219260608401611dcc565b60608201526121a360808401611dcc565b60808201526121b460a08401611dcc565b60a08201526121c560c08401612133565b60c08201526121d660e08401612133565b60e08201526101008381015190820152610120808401519082015261014080840151908201526101608084015190820152610180928301519281019290925250919050565b60006040828403121561222d57600080fd5b6040516040810181811067ffffffffffffffff82111715612250576122506118cd565b80604052508091508251612263816117ec565b81526020830151612273816117ec565b6020919091015292915050565b6000610240828403121561229357600080fd5b61229b611949565b6122a483611dcc565b81526122b260208401611dcc565b60208201526122c360408401611dcc565b60408201526122d460608401611dcc565b60608201526122e560808401611dcc565b60808201526122f660a08401611dcc565b60a082015261230760c08401611dcc565b60c082015261231860e08401611dcc565b60e082015261010061232c8582860161221b565b9082015261014061233f8585830161221b565b61012083015261018080850151828401526101a09150818501516101608401526101c080860151828501526101e09150818601518385015261020086015181850152506102208501518184015250508091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610de157610de1612398565b600060ff8316806123ed576123ed612104565b8060ff84160491505092915050565b600060ff83168061240f5761240f612104565b8060ff84160691505092915050565b7f5f5441524745545f50414e49434b45443a203078000000000000000000000000815260008251612456816014850160208701611cf4565b9190910160140192915050565b60006020828403121561247557600080fd5b815167ffffffffffffffff81111561248c57600080fd5b8201601f8101841361249d57600080fd5b611bcc84825160208401611ef1565b7f5f000000000000000000000000000000000000000000000000000000000000008152600082516124e4816001850160208701611cf4565b9190910160010192915050565b7f5f435553544f4d5f4552524f523a203078000000000000000000000000000000815260008251612529816011850160208701611cf4565b9190910160110192915050565b80820180821115610de157610de161239856fea26469706673582212208c368e3e3faf01565309336d05cd6b031c36481a570b212da86a2a1e0e35218764736f6c63430008150033000000000000000000000000324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d000000000000000000000000d8ae986159e350b6535539b8a1e488658452f25e
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100885760003560e01c80638da5cb5b1161005b5780638da5cb5b1461015e578063920f5c841461017e578063a734f06e146101a1578063ffa1ad74146101bc57600080fd5b8063103f29071461008d578063150b7a02146100de57806357b7bf20146101225780636ff66e7914610137575b600080fd5b6100b47f000000000000000000000000324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100f16100ec36600461185a565b610205565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100d5565b610135610130366004611b97565b610583565b005b6100b47f000000000000000000000000d8ae986159e350b6535539b8a1e488658452f25e81565b6000546100b49073ffffffffffffffffffffffffffffffffffffffff1681565b61019161018c366004611c19565b6105cc565b60405190151581526020016100d5565b6100b473eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6101f86040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d59190611d62565b60003373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d1614610276576040517f52df424e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16146102db576040517f52df424e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000d8ae986159e350b6535539b8a1e488658452f25e73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610360576040517f52df424e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061036f84860186611d7c565b9150915061037c82610678565b61038581610815565b61038e60018055565b6040517f6352211e00000000000000000000000000000000000000000000000000000000815260048101879052309073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d1690636352211e90602401602060405180830381865afa15801561041b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043f9190611dd7565b73ffffffffffffffffffffffffffffffffffffffff1603610509576040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018890527f000000000000000000000000324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d16906323b872dd90606401600060405180830381600087803b1580156104f057600080fd5b505af1158015610504573d6000803e3d6000fd5b505050505b6105138287610b23565b604051869073ffffffffffffffffffffffffffffffffffffffff8416907f6f6c6d78a4851d4c222c8404fc92372ee84b7b81054305ae8ea3c83c2dabd42e90600090a3507f150b7a0200000000000000000000000000000000000000000000000000000000979650505050505050565b61058c33610678565b61059581610815565b61059e60018055565b60405133907fd2c4fe7e5a558f9b1b406ce6cd257540e044fe92fa299597ed9656533c6a8c8d90600090a250565b60008282426040516020016105e393929190611df4565b6040516020818303038152906040528051906020012060015414801561061e575073ffffffffffffffffffffffffffffffffffffffff841630145b610654576040517f38b760c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61066861066383850185611b97565b610815565b5060019998505050505050505050565b60006107c07f000000000000000000000000d8ae986159e350b6535539b8a1e488658452f25e73ffffffffffffffffffffffffffffffffffffffff1663ba8df43c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061070c9190611dd7565b6040805173ffffffffffffffffffffffffffffffffffffffff8616602082015201604051602081830303815290604052805190602001207f000000000000000000000000d8ae986159e350b6535539b8a1e488658452f25e60405160388101919091526f5af43d82803e903d91602b57fd5bf3ff60248201526014810192909252733d602d80600a3d3981f3363d3d373d3d3d363d73825260588201526037600c8201206078820152605560439091012090565b905073ffffffffffffffffffffffffffffffffffffffff81163014610811576040517f52df424e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b805160005b81811015610b1e57600083828151811061083657610836611e4b565b6020026020010151905060006060826060015160ff166000036108e157826000015173ffffffffffffffffffffffffffffffffffffffff16836040015184602001516040516108859190611e7a565b60006040518083038185875af1925050503d80600081146108c2576040519150601f19603f3d011682016040523d82523d6000602084013e6108c7565b606091505b509092509050816108dc576108dc8482610cd7565b610b10565b826060015160ff1660010361097b57826000015173ffffffffffffffffffffffffffffffffffffffff16836020015160405161091d9190611e7a565b600060405180830381855af49150503d8060008114610958576040519150601f19603f3d011682016040523d82523d6000602084013e61095d565b606091505b50909250905061096c60018055565b816108dc576108dc8482610cd7565b826060015160ff16600203610a9057602083015160048101805190916109a991810160249081019101611f41565b506040519094506109c39350849250429150602001612059565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206001558651918701519087015173ffffffffffffffffffffffffffffffffffffffff909216929091610a2a91611e7a565b60006040518083038185875af1925050503d8060008114610a67576040519150601f19603f3d011682016040523d82523d6000602084013e610a6c565b606091505b50909350915082610a8157610a818583610cd7565b610a8a60018055565b50610b10565b610a9984610cfa565b604051602001610aa9919061207b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610b0791600401611d62565b60405180910390fd5b83600101935050505061081a565b505050565b60007f000000000000000000000000324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d73ffffffffffffffffffffffffffffffffffffffff1663b5c736e4610b6c600385610db8565b6040518263ffffffff1660e01b8152600401610b8a91815260200190565b602060405180830381865afa158015610ba7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bcb91906120bc565b6040517fe6bd26a200000000000000000000000000000000000000000000000000000000815260c082901c63ffffffff16600482015290915060009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d169063e6bd26a290602401602060405180830381865afa158015610c65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c899190611dd7565b90506000610c9682610de7565b9050610ca681600001518661102e565b610cb481602001518661102e565b610cc281604001518661102e565b610cd081606001518661102e565b5050505050565b610ce082610cfa565b610ce98261113f565b604051602001610aa99291906120d5565b60606000610d07836115b4565b600101905060008167ffffffffffffffff811115610d2757610d276118cd565b6040519080825280601f01601f191660200182016040528015610d51576020820181803683370190505b5090508181016020015b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8504945084610d5b57509392505050565b604080516020808201849052818301859052825180830384018152606090920190925280519101205b92915050565b6040805160808101825260008082526020820181905291810182905260608101919091528173ffffffffffffffffffffffffffffffffffffffff163b600003610e2f57919050565b8173ffffffffffffffffffffffffffffffffffffffff1663bb24fe8a6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610eb4575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610eb1918101906120bc565b60015b610f695760008273ffffffffffffffffffffffffffffffffffffffff1663b7791bf26040518163ffffffff1660e01b81526004016101a060405180830381865afa158015610f06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2a919061213e565b608081015173ffffffffffffffffffffffffffffffffffffffff908116845260006020850181905260a090920151166040840152606083015250919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663b7791bf26040518163ffffffff1660e01b815260040161024060405180830381865afa158015610fb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdb9190612280565b610100810180515173ffffffffffffffffffffffffffffffffffffffff9081168652905160209081015182168187015261012090920180515182166040870152519091015116606084015250505b919050565b73ffffffffffffffffffffffffffffffffffffffff821661104d575050565b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff83160161109b57478015610b1e57610b1e8282611696565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112c91906120bc565b90508015610b1e57610b1e8383836116e2565b606060048251101561118457505060408051808201909152601381527f5f524541534f4e5f4e4f545f444546494e454400000000000000000000000000602082015290565b60208201517fb1b7848f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016113105760408051600280825281830190925260009160208201818036833701905050905061122e6010856001875161120791906123c7565b8151811061121757611217611e4b565b0160200151611229919060f81c6123da565b61178c565b8160008151811061124157611241611e4b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506112a66010856001875161128491906123c7565b8151811061129457611294611e4b565b0160200151611229919060f81c6123fc565b816001815181106112b9576112b9611e4b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806040516020016112f9919061241e565b6040516020818303038152906040529250506114d4565b7ff73c8660000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000082160161139957600483019250828060200190518101906113739190612463565b60405160200161138391906124ac565b60405160208183030381529060405291506114d4565b60408051600880825281830190925260009160208201818036833701905050905060005b60048110156114af576113f160108483600481106113dd576113dd611e4b565b1a816113eb576113eb612104565b0461178c565b82826002028151811061140657611406611e4b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611460601084836004811061144c5761144c611e4b565b1a8161145a5761145a612104565b0661178c565b82826002026001018151811061147857611478611e4b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001016113bd565b50806040516020016114c191906124f1565b6040516020818303038152906040529250505b60fa825111156115ae578160006114ed60fa6001612536565b905060008167ffffffffffffffff81111561150a5761150a6118cd565b6040519080825280601f01601f191660200182016040528015611534576020820181803683370190505b50905060005b828110156115a85783818151811061155457611554611e4b565b602001015160f81c60f81b82828151811061157157611571611e4b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161153a565b50935050505b50919050565b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106115fd577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310611629576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061164757662386f26fc10000830492506010015b6305f5e100831061165f576305f5e100830492506008015b612710831061167357612710830492506004015b60648310611685576064830492506002015b600a8310610de15760010192915050565b60008060008060008587614e20f1905080610b1e576040517fdee51a8a0000000000000000000000000000000000000000000000000000000081526201155a6004820152602401610b07565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080611786576040517fdee51a8a0000000000000000000000000000000000000000000000000000000081526201155a6004820152602401610b07565b50505050565b6000600a8260ff1610156117a4575060300160f81b90565b60108260ff1610156117ba575060570160f81b90565b6040517fb0b8d61a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461180e57600080fd5b50565b60008083601f84011261182357600080fd5b50813567ffffffffffffffff81111561183b57600080fd5b60208301915083602082850101111561185357600080fd5b9250929050565b60008060008060006080868803121561187257600080fd5b853561187d816117ec565b9450602086013561188d816117ec565b935060408601359250606086013567ffffffffffffffff8111156118b057600080fd5b6118bc88828901611811565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561191f5761191f6118cd565b60405290565b6040516101a0810167ffffffffffffffff8111828210171561191f5761191f6118cd565b604051610200810167ffffffffffffffff8111828210171561191f5761191f6118cd565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156119b4576119b46118cd565b604052919050565b600067ffffffffffffffff8211156119d6576119d66118cd565b5060051b60200190565b600067ffffffffffffffff8211156119fa576119fa6118cd565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60ff8116811461180e57600080fd5b803561102981611a26565b600082601f830112611a5157600080fd5b81356020611a66611a61836119bc565b61196d565b82815260059290921b84018101918181019086841115611a8557600080fd5b8286015b84811015611b8c57803567ffffffffffffffff80821115611aaa5760008081fd5b81890191506080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215611ae35760008081fd5b611aeb6118fc565b87840135611af8816117ec565b815260408481013584811115611b0e5760008081fd5b85019350603f84018d13611b225760008081fd5b88840135611b32611a61826119e0565b8181528e83838801011115611b475760008081fd5b818387018c83013760008b8383010152808b850152505060609350838501358183015250611b76828501611a35565b9281019290925250845250918301918301611a89565b509695505050505050565b600060208284031215611ba957600080fd5b813567ffffffffffffffff811115611bc057600080fd5b611bcc84828501611a40565b949350505050565b60008083601f840112611be657600080fd5b50813567ffffffffffffffff811115611bfe57600080fd5b6020830191508360208260051b850101111561185357600080fd5b600080600080600080600080600060a08a8c031215611c3757600080fd5b893567ffffffffffffffff80821115611c4f57600080fd5b611c5b8d838e01611bd4565b909b50995060208c0135915080821115611c7457600080fd5b611c808d838e01611bd4565b909950975060408c0135915080821115611c9957600080fd5b611ca58d838e01611bd4565b909750955060608c01359150611cba826117ec565b90935060808b01359080821115611cd057600080fd5b50611cdd8c828d01611811565b915080935050809150509295985092959850929598565b60005b83811015611d0f578181015183820152602001611cf7565b50506000910152565b60008151808452611d30816020860160208601611cf4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d756020830184611d18565b9392505050565b60008060408385031215611d8f57600080fd5b8235611d9a816117ec565b9150602083013567ffffffffffffffff811115611db657600080fd5b611dc285828601611a40565b9150509250929050565b8051611029816117ec565b600060208284031215611de957600080fd5b8151611d75816117ec565b6040815282604082015282846060830137600060608483010152600060607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8601168301019050826020830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008251611e8c818460208701611cf4565b9190910192915050565b600082601f830112611ea757600080fd5b81516020611eb7611a61836119bc565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611b8c5780518352918301918301611eda565b6000611eff611a61846119e0565b9050828152838383011115611f1357600080fd5b611d75836020830184611cf4565b600082601f830112611f3257600080fd5b611d7583835160208501611ef1565b600080600080600060a08688031215611f5957600080fd5b855167ffffffffffffffff80821115611f7157600080fd5b818801915088601f830112611f8557600080fd5b81516020611f95611a61836119bc565b82815260059290921b8401810191818101908c841115611fb457600080fd5b948201945b83861015611fdb578551611fcc816117ec565b82529482019490820190611fb9565b918b0151919950909350505080821115611ff457600080fd5b61200089838a01611e96565b955060408801519450606088015191508082111561201d57600080fd5b61202989838a01611f21565b9350608088015191508082111561203f57600080fd5b5061204c88828901611f21565b9150509295509295909350565b60408152600061206c6040830185611d18565b90508260208301529392505050565b6000825161208d818460208701611cf4565b7f5f464c5549445f5f494e56414c49445f49445f4f525f4f5045524154494f4e00920191825250601f01919050565b6000602082840312156120ce57600080fd5b5051919050565b600083516120e7818460208801611cf4565b8351908301906120fb818360208801611cf4565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b805161102981611a26565b60006101a0828403121561215157600080fd5b612159611925565b61216283611dcc565b815261217060208401611dcc565b602082015261218160408401611dcc565b604082015261219260608401611dcc565b60608201526121a360808401611dcc565b60808201526121b460a08401611dcc565b60a08201526121c560c08401612133565b60c08201526121d660e08401612133565b60e08201526101008381015190820152610120808401519082015261014080840151908201526101608084015190820152610180928301519281019290925250919050565b60006040828403121561222d57600080fd5b6040516040810181811067ffffffffffffffff82111715612250576122506118cd565b80604052508091508251612263816117ec565b81526020830151612273816117ec565b6020919091015292915050565b6000610240828403121561229357600080fd5b61229b611949565b6122a483611dcc565b81526122b260208401611dcc565b60208201526122c360408401611dcc565b60408201526122d460608401611dcc565b60608201526122e560808401611dcc565b60808201526122f660a08401611dcc565b60a082015261230760c08401611dcc565b60c082015261231860e08401611dcc565b60e082015261010061232c8582860161221b565b9082015261014061233f8585830161221b565b61012083015261018080850151828401526101a09150818501516101608401526101c080860151828501526101e09150818601518385015261020086015181850152506102208501518184015250508091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610de157610de1612398565b600060ff8316806123ed576123ed612104565b8060ff84160491505092915050565b600060ff83168061240f5761240f612104565b8060ff84160691505092915050565b7f5f5441524745545f50414e49434b45443a203078000000000000000000000000815260008251612456816014850160208701611cf4565b9190910160140192915050565b60006020828403121561247557600080fd5b815167ffffffffffffffff81111561248c57600080fd5b8201601f8101841361249d57600080fd5b611bcc84825160208401611ef1565b7f5f000000000000000000000000000000000000000000000000000000000000008152600082516124e4816001850160208701611cf4565b9190910160010192915050565b7f5f435553544f4d5f4552524f523a203078000000000000000000000000000000815260008251612529816011850160208701611cf4565b9190910160110192915050565b80820180821115610de157610de161239856fea26469706673582212208c368e3e3faf01565309336d05cd6b031c36481a570b212da86a2a1e0e35218764736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d000000000000000000000000d8ae986159e350b6535539b8a1e488658452f25e
-----Decoded View---------------
Arg [0] : vaultFactory_ (address): 0x324c5Dc1fC42c7a4D43d92df1eBA58a54d13Bf2d
Arg [1] : fluidWalletFactory_ (address): 0xd8Ae986159e350B6535539B8A1e488658452f25E
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d
Arg [1] : 000000000000000000000000d8ae986159e350b6535539b8a1e488658452f25e
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.