Overview
S Balance
0 S
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
SolvBTCMultiAssetPool
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 1 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.20; import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "./access/AdminControlUpgradeable.sol"; import "./utils/ERC3525TransferHelper.sol"; import "./external/IERC3525.sol"; import "./ISolvBTCMultiAssetPool.sol"; import "./ISolvBTC.sol"; contract SolvBTCMultiAssetPool is ISolvBTCMultiAssetPool, ReentrancyGuardUpgradeable, AdminControlUpgradeable { struct SftSlotInfo { uint256 holdingValueSftId; address erc20; bool depositAllowed; bool withdrawAllowed; } mapping(address => mapping(uint256 => SftSlotInfo)) internal _sftSlotInfos; event AddSftSlot(address indexed sft, uint256 indexed slot, address indexed erc20, uint256 holdingValueSftId); event SftSlotAllowedChanged(address indexed sft, uint256 indexed slot, bool depositAllowed, bool withdrawAllowed); event Deposit( address indexed owner, address indexed sft, uint256 indexed slot, address erc20, uint256 sftId, uint256 value ); event Withdraw( address indexed owner, address indexed sft, uint256 indexed slot, address erc20, uint256 sftId, uint256 value ); /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize() external virtual initializer { AdminControlUpgradeable.__AdminControl_init(msg.sender); ReentrancyGuardUpgradeable.__ReentrancyGuard_init(); } function deposit(address sft_, uint256 sftId_, uint256 value_) external virtual override nonReentrant { require(value_ > 0, "SolvBTCMultiAssetPool: deposit amount cannot be 0"); require(msg.sender == IERC3525(sft_).ownerOf(sftId_), "SolvBTCMultiAssetPool: caller is not sft owner"); uint256 slot = IERC3525(sft_).slotOf(sftId_); SftSlotInfo storage sftSlotInfo = _sftSlotInfos[sft_][slot]; require(sftSlotInfo.depositAllowed, "SolvBTCMultiAssetPool: sft slot deposit not allowed"); uint256 sftBalance = IERC3525(sft_).balanceOf(sftId_); if (value_ == sftBalance) { ERC3525TransferHelper.doTransferIn(sft_, msg.sender, sftId_); if (sftSlotInfo.holdingValueSftId == 0) { sftSlotInfo.holdingValueSftId = sftId_; } else { ERC3525TransferHelper.doTransfer(sft_, sftId_, sftSlotInfo.holdingValueSftId, value_); ERC3525TransferHelper.doTransferOut(sft_, 0x000000000000000000000000000000000000dEaD, sftId_); } } else if (value_ < sftBalance) { if (sftSlotInfo.holdingValueSftId == 0) { sftSlotInfo.holdingValueSftId = ERC3525TransferHelper.doTransferIn(sft_, sftId_, value_); } else { ERC3525TransferHelper.doTransfer(sft_, sftId_, sftSlotInfo.holdingValueSftId, value_); } } else { revert("SolvBTCMultiAssetPool: deposit amount exceeds sft balance"); } ISolvBTC(sftSlotInfo.erc20).mint(msg.sender, value_); emit Deposit(msg.sender, sft_, slot, sftSlotInfo.erc20, sftId_, value_); } function withdraw(address sft_, uint256 slot_, uint256 sftId_, uint256 value_) external virtual override nonReentrant returns (uint256 toSftId_) { require(value_ > 0, "SolvBTCMultiAssetPool: withdraw amount cannot be 0"); SftSlotInfo storage sftSlotInfo = _sftSlotInfos[sft_][slot_]; require(sftSlotInfo.withdrawAllowed, "SolvBTCMultiAssetPool: sft slot not allowed"); uint256 sftSlotBalance = getSftSlotBalance(sft_, slot_); require(value_ <= sftSlotBalance, "SolvBTCMultiAssetPool: insufficient balance"); ISolvBTC(sftSlotInfo.erc20).burn(msg.sender, value_); if (sftId_ == 0) { toSftId_ = ERC3525TransferHelper.doTransferOut(sft_, sftSlotInfo.holdingValueSftId, msg.sender, value_); } else { require(slot_ == IERC3525(sft_).slotOf(sftId_), "SolvBTCMultiAssetPool: slot not matched"); require(msg.sender == IERC3525(sft_).ownerOf(sftId_), "SolvBTCMultiAssetPool: caller is not sft owner"); ERC3525TransferHelper.doTransfer(sft_, sftSlotInfo.holdingValueSftId, sftId_, value_); toSftId_ = sftId_; } emit Withdraw(msg.sender, sft_, slot_, sftSlotInfo.erc20, toSftId_, value_); } function addSftSlotOnlyAdmin(address sft_, uint256 slot_, address erc20_, uint256 holdingValueSftId_) external virtual onlyAdmin { SftSlotInfo storage sftSlotInfo = _sftSlotInfos[sft_][slot_]; require(sftSlotInfo.erc20 == address(0), "SolvBTCMultiAssetPool: sft slot already existed"); require( IERC3525(sft_).valueDecimals() == IERC20Metadata(erc20_).decimals(), "SolvBTCMultiAssetPool: decimals not matched" ); if (holdingValueSftId_ > 0) { require(IERC3525(sft_).slotOf(holdingValueSftId_) == slot_, "SolvBTCMultiAssetPool: slot not matched"); require( IERC3525(sft_).ownerOf(holdingValueSftId_) == address(this), "SolvBTCMultiAssetPool: sftId not owned" ); } sftSlotInfo.holdingValueSftId = holdingValueSftId_; sftSlotInfo.erc20 = erc20_; sftSlotInfo.depositAllowed = true; sftSlotInfo.withdrawAllowed = true; emit AddSftSlot(sft_, slot_, erc20_, holdingValueSftId_); } function changeSftSlotAllowedOnlyAdmin(address sft_, uint256 slot_, bool depositAllowed_, bool withdrawAllowed_) external virtual onlyAdmin { SftSlotInfo storage sftSlotInfo = _sftSlotInfos[sft_][slot_]; require(sftSlotInfo.erc20 != address(0), "SolvBTCMultiAssetPool: sft slot not existed"); sftSlotInfo.depositAllowed = depositAllowed_; sftSlotInfo.withdrawAllowed = withdrawAllowed_; emit SftSlotAllowedChanged(sft_, slot_, depositAllowed_, withdrawAllowed_); } function isSftSlotDepositAllowed(address sft_, uint256 slot_) public view virtual override returns (bool) { return _sftSlotInfos[sft_][slot_].depositAllowed; } function isSftSlotWithdrawAllowed(address sft_, uint256 slot_) public view virtual override returns (bool) { return _sftSlotInfos[sft_][slot_].withdrawAllowed; } function getERC20(address sft_, uint256 slot_) public view virtual override returns (address) { return _sftSlotInfos[sft_][slot_].erc20; } function getHoldingValueSftId(address sft_, uint256 slot_) public view virtual override returns (uint256) { return _sftSlotInfos[sft_][slot_].holdingValueSftId; } function getSftSlotBalance(address sft_, uint256 slot_) public view virtual override returns (uint256) { SftSlotInfo storage sftSlotInfo = _sftSlotInfos[sft_][slot_]; return sftSlotInfo.holdingValueSftId == 0 ? 0 : IERC3525(sft_).balanceOf(sftSlotInfo.holdingValueSftId); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._initialized = 1; if (isTopLevelCall) { $._initializing = true; } _; if (isTopLevelCall) { $._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._initialized = version; $._initializing = true; _; $._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; /// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard struct ReentrancyGuardStorage { uint256 _status; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00; function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) { assembly { $.slot := ReentrancyGuardStorageLocation } } /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage(); $._status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage(); // On the first call to nonReentrant, _status will be NOT_ENTERED if ($._status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail $._status = ENTERED; } function _nonReentrantAfter() private { ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage(); // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) $._status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage(); return $._status == ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @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 pragma solidity 0.8.20; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; abstract contract AdminControlUpgradeable is Initializable { event NewAdmin(address oldAdmin, address newAdmin); event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin); address public admin; address public pendingAdmin; modifier onlyAdmin() { require(msg.sender == admin, "only admin"); _; } modifier onlyPendingAdmin() { require(msg.sender == pendingAdmin, "only pending admin"); _; } function __AdminControl_init(address admin_) internal onlyInitializing { __AdminControl_init_unchained(admin_); } function __AdminControl_init_unchained(address admin_) internal onlyInitializing { admin = admin_; emit NewAdmin(address(0), admin_); } function transferAdmin(address newPendingAdmin_) external virtual onlyAdmin { emit NewPendingAdmin(pendingAdmin, newPendingAdmin_); pendingAdmin = newPendingAdmin_; } function acceptAdmin() external virtual onlyPendingAdmin { emit NewAdmin(admin, pendingAdmin); admin = pendingAdmin; delete pendingAdmin; } uint256[48] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.20; import "./IERC721.sol"; interface IERC3525 is IERC721 { function valueDecimals() external view returns (uint8); function balanceOf(uint256 tokenId) external view returns (uint256); function slotOf(uint256 tokenId) external view returns (uint256); function allowance(uint256 tokenId, address operator) external view returns (uint256); function approve(address operator, uint256 tokenId) external payable; function approve(uint256 tokenId, address operator, uint256 value) external payable; function transferFrom(uint256 fromTokenId, uint256 toTokenId, uint256 value) external payable; function transferFrom(uint256 fromTokenId, address to, uint256 value) external payable returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.20; interface IERC3525Receiver { function onERC3525Received(address operator, uint256 fromTokenId, uint256 toTokenId, uint256 value, bytes calldata data) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.20; interface IERC721 { function balanceOf(address owner) external view returns (uint256); function ownerOf(uint256 tokenId) external view returns (address); function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); function getApproved(uint256 tokenId) external view returns (address); function isApprovedForAll(address owner, address operator) external view returns (bool); function approve(address approved, uint256 tokenId) external payable; function setApprovalForAll(address operator, bool approved) external; function transferFrom(address from, address to, uint256 tokenId) external payable; function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external payable; function safeTransferFrom(address from, address to, uint256 tokenId) external payable; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.20; interface IERC721Receiver { function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.20; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import "./external/IERC721Receiver.sol"; import "./external/IERC3525Receiver.sol"; interface ISolvBTC is IERC20, IERC721Receiver, IERC3525Receiver, IERC165 { error ERC721NotReceivable(address token); error ERC3525NotReceivable(address token); function mint(address account, uint256 value) external; function burn(address account, uint256 value) external; function burn(uint256 value) external; function solvBTCMultiAssetPool() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.20; interface ISolvBTCMultiAssetPool { function deposit(address sft_, uint256 sftId_, uint256 value_) external; function withdraw(address sft, uint256 slot, uint256 sftId, uint256 value) external returns (uint256 toSftId_); function isSftSlotDepositAllowed(address sft_, uint256 slot_) external view returns (bool); function isSftSlotWithdrawAllowed(address sft_, uint256 slot_) external view returns (bool); function getERC20(address sft_, uint256 slot_) external view returns (address); function getHoldingValueSftId(address sft_, uint256 slot_) external view returns (uint256); function getSftSlotBalance(address sft_, uint256 slot_) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.20; interface ERC721Interface { function approve(address to, uint256 tokenId) external; function transferFrom(address from, address to, uint256 tokenId) external; function safeTransferFrom(address from, address to, uint256 tokenId) external; } interface ERC3525Interface { function approve(uint256 tokenId, address to, uint256 allowance) external payable; function transferFrom(uint256 fromTokenId, uint256 toTokenId, uint256 value) external payable; function transferFrom(uint256 fromTokenId, address to, uint256 value) external payable returns (uint256); } library ERC3525TransferHelper { function doApproveId(address underlying, address to, uint256 tokenId) internal { ERC721Interface token = ERC721Interface(underlying); token.approve(to, tokenId); } function doApproveValue(address underlying, uint256 tokenId, address to, uint256 allowance) internal { ERC3525Interface token = ERC3525Interface(underlying); token.approve(tokenId, to, allowance); } function doTransferIn(address underlying, address from, uint256 tokenId) internal { ERC721Interface token = ERC721Interface(underlying); token.transferFrom(from, address(this), tokenId); } function doSafeTransferIn(address underlying, address from, uint256 tokenId) internal { ERC721Interface token = ERC721Interface(underlying); token.safeTransferFrom(from, address(this), tokenId); } function doSafeTransferOut(address underlying, address to, uint256 tokenId) internal { ERC721Interface token = ERC721Interface(underlying); token.safeTransferFrom(address(this), to, tokenId); } function doTransferOut(address underlying, address to, uint256 tokenId) internal { ERC721Interface token = ERC721Interface(underlying); token.transferFrom(address(this), to, tokenId); } function doTransferIn(address underlying, uint256 fromTokenId, uint256 value) internal returns (uint256 newTokenId) { ERC3525Interface token = ERC3525Interface(underlying); return token.transferFrom(fromTokenId, address(this), value); } function doTransferOut(address underlying, uint256 fromTokenId, address to, uint256 value) internal returns (uint256 newTokenId) { ERC3525Interface token = ERC3525Interface(underlying); newTokenId = token.transferFrom(fromTokenId, to, value); } function doTransfer(address underlying, address from, address to, uint256 tokenId) internal { ERC721Interface token = ERC721Interface(underlying); token.transferFrom(from, to, tokenId); } function doTransfer(address underlying, uint256 fromTokenId, uint256 toTokenId, uint256 value) internal { ERC3525Interface token = ERC3525Interface(underlying); token.transferFrom(fromTokenId, toTokenId, value); } }
{ "optimizer": { "enabled": true, "runs": 1 }, "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":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sft","type":"address"},{"indexed":true,"internalType":"uint256","name":"slot","type":"uint256"},{"indexed":true,"internalType":"address","name":"erc20","type":"address"},{"indexed":false,"internalType":"uint256","name":"holdingValueSftId","type":"uint256"}],"name":"AddSftSlot","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"sft","type":"address"},{"indexed":true,"internalType":"uint256","name":"slot","type":"uint256"},{"indexed":false,"internalType":"address","name":"erc20","type":"address"},{"indexed":false,"internalType":"uint256","name":"sftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"NewAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPendingAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newPendingAdmin","type":"address"}],"name":"NewPendingAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sft","type":"address"},{"indexed":true,"internalType":"uint256","name":"slot","type":"uint256"},{"indexed":false,"internalType":"bool","name":"depositAllowed","type":"bool"},{"indexed":false,"internalType":"bool","name":"withdrawAllowed","type":"bool"}],"name":"SftSlotAllowedChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"sft","type":"address"},{"indexed":true,"internalType":"uint256","name":"slot","type":"uint256"},{"indexed":false,"internalType":"address","name":"erc20","type":"address"},{"indexed":false,"internalType":"uint256","name":"sftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"acceptAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sft_","type":"address"},{"internalType":"uint256","name":"slot_","type":"uint256"},{"internalType":"address","name":"erc20_","type":"address"},{"internalType":"uint256","name":"holdingValueSftId_","type":"uint256"}],"name":"addSftSlotOnlyAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sft_","type":"address"},{"internalType":"uint256","name":"slot_","type":"uint256"},{"internalType":"bool","name":"depositAllowed_","type":"bool"},{"internalType":"bool","name":"withdrawAllowed_","type":"bool"}],"name":"changeSftSlotAllowedOnlyAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sft_","type":"address"},{"internalType":"uint256","name":"sftId_","type":"uint256"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sft_","type":"address"},{"internalType":"uint256","name":"slot_","type":"uint256"}],"name":"getERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sft_","type":"address"},{"internalType":"uint256","name":"slot_","type":"uint256"}],"name":"getHoldingValueSftId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sft_","type":"address"},{"internalType":"uint256","name":"slot_","type":"uint256"}],"name":"getSftSlotBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sft_","type":"address"},{"internalType":"uint256","name":"slot_","type":"uint256"}],"name":"isSftSlotDepositAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sft_","type":"address"},{"internalType":"uint256","name":"slot_","type":"uint256"}],"name":"isSftSlotWithdrawAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPendingAdmin_","type":"address"}],"name":"transferAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sft_","type":"address"},{"internalType":"uint256","name":"slot_","type":"uint256"},{"internalType":"uint256","name":"sftId_","type":"uint256"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"toSftId_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061001961001e565b6100d0565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161561006e5760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146100cd5780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6118eb806100df6000396000f3fe608060405234801561001057600080fd5b50600436106100ba5760003560e01c80630e18b681146100bf5780630efe6a8b146100c957806312a2b905146100dc578063159c3a201461010257806326782247146101155780634532d7761461014057806375829def146101535780638129fc1c1461016657806386585a5e1461016e5780639f0b8d03146101c1578063a6c3325f146101fa578063c4d9799514610230578063d2d9210014610243578063f851a44014610286575b600080fd5b6100c7610299565b005b6100c76100d7366004611540565b61034d565b6100ef6100ea366004611575565b610742565b6040519081526020015b60405180910390f35b6100c76101103660046115a1565b6107e8565b600154610128906001600160a01b031681565b6040516001600160a01b0390911681526020016100f9565b6100ef61014e3660046115e9565b610b9c565b6100c7610161366004611624565b610f18565b6100c7610fab565b6101b161017c366004611575565b6001600160a01b039190911660009081526032602090815260408083209383529290522060010154600160a01b900460ff1690565b60405190151581526020016100f9565b6101286101cf366004611575565b6001600160a01b03918216600090815260326020908152604080832093835292905220600101541690565b6100ef610208366004611575565b6001600160a01b03919091166000908152603260209081526040808320938352929052205490565b6100c761023e36600461165d565b6110ab565b6101b1610251366004611575565b6001600160a01b039190911660009081526032602090815260408083209383529290522060010154600160a81b900460ff1690565b600054610128906001600160a01b031681565b6001546001600160a01b031633146102ed5760405162461bcd60e51b815260206004820152601260248201527137b7363c903832b73234b7339030b236b4b760711b60448201526064015b60405180910390fd5b6000546001546040516000805160206118968339815191529261031e926001600160a01b03918216929116906116ac565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6103556111d3565b600081116103ad5760405162461bcd60e51b8152602060048201526031602482015260008051602061185683398151915260448201527006d6f756e742063616e6e6f74206265203607c1b60648201526084016102e4565b6040516331a9108f60e11b8152600481018390526001600160a01b03841690636352211e90602401602060405180830381865afa1580156103f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061041691906116c6565b6001600160a01b0316336001600160a01b0316146104465760405162461bcd60e51b81526004016102e4906116e3565b60405163131f9f3f60e11b8152600481018390526000906001600160a01b0385169063263f3e7e90602401602060405180830381865afa15801561048e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b29190611731565b6001600160a01b03851660009081526032602090815260408083208484529091529020600181015491925090600160a01b900460ff1661053e5760405162461bcd60e51b8152602060048201526033602482015260008051602061187683398151915260448201527219195c1bdcda5d081b9bdd08185b1b1bddd959606a1b60648201526084016102e4565b604051631398fee160e31b8152600481018590526000906001600160a01b03871690639cc7f70890602401602060405180830381865afa158015610586573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105aa9190611731565b90508084036105f1576105be863387611209565b81546000036105cf5784825561067c565b6105df8686846000015487611273565b6105ec8661dead876112e4565b61067c565b808410156106245781546000036106145761060d868686611316565b825561067c565b6105ec8686846000015487611273565b60405162461bcd60e51b815260206004820152603960248201526000805160206118568339815191526044820152786d6f756e742065786365656473207366742062616c616e636560381b60648201526084016102e4565b60018201546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906106b0903390889060040161174a565b600060405180830381600087803b1580156106ca57600080fd5b505af11580156106de573d6000803e3d6000fd5b50505060018301546040518592506001600160a01b03808a169233927e989e8d31410c29caf0085f1b67a406c7146d720ea8e126047c5aac4c1b3b2b9261072a9216908b908b90611763565b60405180910390a450505061073d611397565b505050565b6001600160a01b038216600090815260326020908152604080832084845290915281208054156107dd578054604051631398fee160e31b815260048101919091526001600160a01b03851690639cc7f70890602401602060405180830381865afa1580156107b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d89190611731565b6107e0565b60005b949350505050565b6000546001600160a01b031633146108125760405162461bcd60e51b81526004016102e490611784565b6001600160a01b03808516600090815260326020908152604080832087845290915290206001810154909116156108915760405162461bcd60e51b815260206004820152602f602482015260008051602061187683398151915260448201526e185b1c9958591e48195e1a5cdd1959608a1b60648201526084016102e4565b826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f391906117a8565b60ff16856001600160a01b0316633e7e86696040518163ffffffff1660e01b8152600401602060405180830381865afa158015610934573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095891906117a8565b60ff16146109bc5760405162461bcd60e51b815260206004820152602b60248201527f536f6c764254434d756c74694173736574506f6f6c3a20646563696d616c732060448201526a1b9bdd081b585d18da195960aa1b60648201526084016102e4565b8115610b1a5760405163131f9f3f60e11b81526004810183905284906001600160a01b0387169063263f3e7e90602401602060405180830381865afa158015610a09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2d9190611731565b14610a4a5760405162461bcd60e51b81526004016102e4906117cb565b6040516331a9108f60e11b81526004810183905230906001600160a01b03871690636352211e90602401602060405180830381865afa158015610a91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab591906116c6565b6001600160a01b031614610b1a5760405162461bcd60e51b815260206004820152602660248201527f536f6c764254434d756c74694173736574506f6f6c3a207366744964206e6f74604482015265081bdddb995960d21b60648201526084016102e4565b81815560018101805460ff60a81b196001600160a81b03199091166001600160a01b03808716918217600160a01b1792909216600160a81b1790925560405186918816907fc2532812ecf7eb4907c9cac96370c00bfb6064322750c6dd0bc97114ceeaa18790610b8d9087815260200190565b60405180910390a45050505050565b6000610ba66111d3565b60008211610c115760405162461bcd60e51b815260206004820152603260248201527f536f6c764254434d756c74694173736574506f6f6c3a207769746864726177206044820152710616d6f756e742063616e6e6f7420626520360741b60648201526084016102e4565b6001600160a01b038516600090815260326020908152604080832087845290915290206001810154600160a81b900460ff16610c915760405162461bcd60e51b815260206004820152602b602482015260008051602061187683398151915260448201526a1b9bdd08185b1b1bddd95960aa1b60648201526084016102e4565b6000610c9d8787610742565b905080841115610d035760405162461bcd60e51b815260206004820152602b60248201527f536f6c764254434d756c74694173736574506f6f6c3a20696e7375666669636960448201526a656e742062616c616e636560a81b60648201526084016102e4565b6001820154604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90610d37903390889060040161174a565b600060405180830381600087803b158015610d5157600080fd5b505af1158015610d65573d6000803e3d6000fd5b5050505084600003610d8857610d8187836000015433876113a8565b9250610ebc565b60405163131f9f3f60e11b8152600481018690526001600160a01b0388169063263f3e7e90602401602060405180830381865afa158015610dcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df19190611731565b8614610e0f5760405162461bcd60e51b81526004016102e4906117cb565b6040516331a9108f60e11b8152600481018690526001600160a01b03881690636352211e90602401602060405180830381865afa158015610e54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7891906116c6565b6001600160a01b0316336001600160a01b031614610ea85760405162461bcd60e51b81526004016102e4906116e3565b610eb88783600001548787611273565b8492505b600182015460405187916001600160a01b03808b169233927f57a06fdd930dbeed1599239829f62ff839283da1c96a5eb2b024c791b1d76e6992610f069291169089908b90611763565b60405180910390a450506107e0611397565b6000546001600160a01b03163314610f425760405162461bcd60e51b81526004016102e490611784565b6001546040517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a991610f81916001600160a01b039091169084906116ac565b60405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000610fb561142a565b805490915060ff600160401b82041615906001600160401b0316600081158015610fdc5750825b90506000826001600160401b03166001148015610ff85750303b155b905081158015611006575080155b156110245760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b0319166001178555831561104d57845460ff60401b1916600160401b1785555b6110563361144e565b61105e611462565b83156110a457845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050565b6000546001600160a01b031633146110d55760405162461bcd60e51b81526004016102e490611784565b6001600160a01b0380851660009081526032602090815260408083208784529091529020600181015490911661114f5760405162461bcd60e51b815260206004820152602b602482015260008051602061187683398151915260448201526a1b9bdd08195e1a5cdd195960aa1b60648201526084016102e4565b60018101805461ffff60a01b1916600160a01b85151590810260ff60a81b191691909117600160a81b8515159081029190911790925560408051918252602082019290925285916001600160a01b038816917fa36339e77124f707069252e7a04f56b467507541182e9e4b2536c9f8377464ff910160405180910390a35050505050565b60006111dd611474565b80549091506001190161120357604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b6040516323b872dd60e01b815283906001600160a01b038216906323b872dd9061123b90869030908790600401611812565b600060405180830381600087803b15801561125557600080fd5b505af1158015611269573d6000803e3d6000fd5b5050505050505050565b604051630310ed7f60e41b815260048101849052602481018390526044810182905284906001600160a01b0382169063310ed7f090606401600060405180830381600087803b1580156112c557600080fd5b505af11580156112d9573d6000803e3d6000fd5b505050505050505050565b6040516323b872dd60e01b815283906001600160a01b038216906323b872dd9061123b90309087908790600401611812565b6040516307a42e0160e11b815260009084906001600160a01b03821690630f485c029061134b90879030908890600401611836565b6020604051808303816000875af115801561136a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138e9190611731565b95945050505050565b60006113a1611474565b6001905550565b6040516307a42e0160e11b815260009085906001600160a01b03821690630f485c02906113dd90889088908890600401611836565b6020604051808303816000875af11580156113fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114209190611731565b9695505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0090565b611456611498565b61145f816114bd565b50565b61146a611498565b611472611509565b565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0090565b6114a0611511565b61147257604051631afcd79f60e31b815260040160405180910390fd5b6114c5611498565b600080546001600160a01b0319166001600160a01b038316178155604051600080516020611896833981519152916114fe9184906116ac565b60405180910390a150565b611397611498565b600061151b61142a565b54600160401b900460ff16919050565b6001600160a01b038116811461145f57600080fd5b60008060006060848603121561155557600080fd5b83356115608161152b565b95602085013595506040909401359392505050565b6000806040838503121561158857600080fd5b82356115938161152b565b946020939093013593505050565b600080600080608085870312156115b757600080fd5b84356115c28161152b565b93506020850135925060408501356115d98161152b565b9396929550929360600135925050565b600080600080608085870312156115ff57600080fd5b843561160a8161152b565b966020860135965060408601359560600135945092505050565b60006020828403121561163657600080fd5b81356116418161152b565b9392505050565b8035801515811461165857600080fd5b919050565b6000806000806080858703121561167357600080fd5b843561167e8161152b565b93506020850135925061169360408601611648565b91506116a160608601611648565b905092959194509250565b6001600160a01b0392831681529116602082015260400190565b6000602082840312156116d857600080fd5b81516116418161152b565b6020808252602e908201527f536f6c764254434d756c74694173736574506f6f6c3a2063616c6c657220697360408201526d103737ba1039b33a1037bbb732b960911b606082015260800190565b60006020828403121561174357600080fd5b5051919050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039390931683526020830191909152604082015260600190565b6020808252600a908201526937b7363c9030b236b4b760b11b604082015260600190565b6000602082840312156117ba57600080fd5b815160ff8116811461164157600080fd5b60208082526027908201527f536f6c764254434d756c74694173736574506f6f6c3a20736c6f74206e6f74206040820152661b585d18da195960ca1b606082015260800190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b9283526001600160a01b0391909116602083015260408201526060019056fe536f6c764254434d756c74694173736574506f6f6c3a206465706f7369742061536f6c764254434d756c74694173736574506f6f6c3a2073667420736c6f7420f9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dca2646970667358221220796dea34e37d6ef38d596a87ec1ee8048aa84e7a7dfb299d535dc4423c540f5964736f6c63430008140033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ba5760003560e01c80630e18b681146100bf5780630efe6a8b146100c957806312a2b905146100dc578063159c3a201461010257806326782247146101155780634532d7761461014057806375829def146101535780638129fc1c1461016657806386585a5e1461016e5780639f0b8d03146101c1578063a6c3325f146101fa578063c4d9799514610230578063d2d9210014610243578063f851a44014610286575b600080fd5b6100c7610299565b005b6100c76100d7366004611540565b61034d565b6100ef6100ea366004611575565b610742565b6040519081526020015b60405180910390f35b6100c76101103660046115a1565b6107e8565b600154610128906001600160a01b031681565b6040516001600160a01b0390911681526020016100f9565b6100ef61014e3660046115e9565b610b9c565b6100c7610161366004611624565b610f18565b6100c7610fab565b6101b161017c366004611575565b6001600160a01b039190911660009081526032602090815260408083209383529290522060010154600160a01b900460ff1690565b60405190151581526020016100f9565b6101286101cf366004611575565b6001600160a01b03918216600090815260326020908152604080832093835292905220600101541690565b6100ef610208366004611575565b6001600160a01b03919091166000908152603260209081526040808320938352929052205490565b6100c761023e36600461165d565b6110ab565b6101b1610251366004611575565b6001600160a01b039190911660009081526032602090815260408083209383529290522060010154600160a81b900460ff1690565b600054610128906001600160a01b031681565b6001546001600160a01b031633146102ed5760405162461bcd60e51b815260206004820152601260248201527137b7363c903832b73234b7339030b236b4b760711b60448201526064015b60405180910390fd5b6000546001546040516000805160206118968339815191529261031e926001600160a01b03918216929116906116ac565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6103556111d3565b600081116103ad5760405162461bcd60e51b8152602060048201526031602482015260008051602061185683398151915260448201527006d6f756e742063616e6e6f74206265203607c1b60648201526084016102e4565b6040516331a9108f60e11b8152600481018390526001600160a01b03841690636352211e90602401602060405180830381865afa1580156103f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061041691906116c6565b6001600160a01b0316336001600160a01b0316146104465760405162461bcd60e51b81526004016102e4906116e3565b60405163131f9f3f60e11b8152600481018390526000906001600160a01b0385169063263f3e7e90602401602060405180830381865afa15801561048e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b29190611731565b6001600160a01b03851660009081526032602090815260408083208484529091529020600181015491925090600160a01b900460ff1661053e5760405162461bcd60e51b8152602060048201526033602482015260008051602061187683398151915260448201527219195c1bdcda5d081b9bdd08185b1b1bddd959606a1b60648201526084016102e4565b604051631398fee160e31b8152600481018590526000906001600160a01b03871690639cc7f70890602401602060405180830381865afa158015610586573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105aa9190611731565b90508084036105f1576105be863387611209565b81546000036105cf5784825561067c565b6105df8686846000015487611273565b6105ec8661dead876112e4565b61067c565b808410156106245781546000036106145761060d868686611316565b825561067c565b6105ec8686846000015487611273565b60405162461bcd60e51b815260206004820152603960248201526000805160206118568339815191526044820152786d6f756e742065786365656473207366742062616c616e636560381b60648201526084016102e4565b60018201546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906106b0903390889060040161174a565b600060405180830381600087803b1580156106ca57600080fd5b505af11580156106de573d6000803e3d6000fd5b50505060018301546040518592506001600160a01b03808a169233927e989e8d31410c29caf0085f1b67a406c7146d720ea8e126047c5aac4c1b3b2b9261072a9216908b908b90611763565b60405180910390a450505061073d611397565b505050565b6001600160a01b038216600090815260326020908152604080832084845290915281208054156107dd578054604051631398fee160e31b815260048101919091526001600160a01b03851690639cc7f70890602401602060405180830381865afa1580156107b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d89190611731565b6107e0565b60005b949350505050565b6000546001600160a01b031633146108125760405162461bcd60e51b81526004016102e490611784565b6001600160a01b03808516600090815260326020908152604080832087845290915290206001810154909116156108915760405162461bcd60e51b815260206004820152602f602482015260008051602061187683398151915260448201526e185b1c9958591e48195e1a5cdd1959608a1b60648201526084016102e4565b826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f391906117a8565b60ff16856001600160a01b0316633e7e86696040518163ffffffff1660e01b8152600401602060405180830381865afa158015610934573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095891906117a8565b60ff16146109bc5760405162461bcd60e51b815260206004820152602b60248201527f536f6c764254434d756c74694173736574506f6f6c3a20646563696d616c732060448201526a1b9bdd081b585d18da195960aa1b60648201526084016102e4565b8115610b1a5760405163131f9f3f60e11b81526004810183905284906001600160a01b0387169063263f3e7e90602401602060405180830381865afa158015610a09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2d9190611731565b14610a4a5760405162461bcd60e51b81526004016102e4906117cb565b6040516331a9108f60e11b81526004810183905230906001600160a01b03871690636352211e90602401602060405180830381865afa158015610a91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab591906116c6565b6001600160a01b031614610b1a5760405162461bcd60e51b815260206004820152602660248201527f536f6c764254434d756c74694173736574506f6f6c3a207366744964206e6f74604482015265081bdddb995960d21b60648201526084016102e4565b81815560018101805460ff60a81b196001600160a81b03199091166001600160a01b03808716918217600160a01b1792909216600160a81b1790925560405186918816907fc2532812ecf7eb4907c9cac96370c00bfb6064322750c6dd0bc97114ceeaa18790610b8d9087815260200190565b60405180910390a45050505050565b6000610ba66111d3565b60008211610c115760405162461bcd60e51b815260206004820152603260248201527f536f6c764254434d756c74694173736574506f6f6c3a207769746864726177206044820152710616d6f756e742063616e6e6f7420626520360741b60648201526084016102e4565b6001600160a01b038516600090815260326020908152604080832087845290915290206001810154600160a81b900460ff16610c915760405162461bcd60e51b815260206004820152602b602482015260008051602061187683398151915260448201526a1b9bdd08185b1b1bddd95960aa1b60648201526084016102e4565b6000610c9d8787610742565b905080841115610d035760405162461bcd60e51b815260206004820152602b60248201527f536f6c764254434d756c74694173736574506f6f6c3a20696e7375666669636960448201526a656e742062616c616e636560a81b60648201526084016102e4565b6001820154604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90610d37903390889060040161174a565b600060405180830381600087803b158015610d5157600080fd5b505af1158015610d65573d6000803e3d6000fd5b5050505084600003610d8857610d8187836000015433876113a8565b9250610ebc565b60405163131f9f3f60e11b8152600481018690526001600160a01b0388169063263f3e7e90602401602060405180830381865afa158015610dcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df19190611731565b8614610e0f5760405162461bcd60e51b81526004016102e4906117cb565b6040516331a9108f60e11b8152600481018690526001600160a01b03881690636352211e90602401602060405180830381865afa158015610e54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7891906116c6565b6001600160a01b0316336001600160a01b031614610ea85760405162461bcd60e51b81526004016102e4906116e3565b610eb88783600001548787611273565b8492505b600182015460405187916001600160a01b03808b169233927f57a06fdd930dbeed1599239829f62ff839283da1c96a5eb2b024c791b1d76e6992610f069291169089908b90611763565b60405180910390a450506107e0611397565b6000546001600160a01b03163314610f425760405162461bcd60e51b81526004016102e490611784565b6001546040517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a991610f81916001600160a01b039091169084906116ac565b60405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000610fb561142a565b805490915060ff600160401b82041615906001600160401b0316600081158015610fdc5750825b90506000826001600160401b03166001148015610ff85750303b155b905081158015611006575080155b156110245760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b0319166001178555831561104d57845460ff60401b1916600160401b1785555b6110563361144e565b61105e611462565b83156110a457845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050565b6000546001600160a01b031633146110d55760405162461bcd60e51b81526004016102e490611784565b6001600160a01b0380851660009081526032602090815260408083208784529091529020600181015490911661114f5760405162461bcd60e51b815260206004820152602b602482015260008051602061187683398151915260448201526a1b9bdd08195e1a5cdd195960aa1b60648201526084016102e4565b60018101805461ffff60a01b1916600160a01b85151590810260ff60a81b191691909117600160a81b8515159081029190911790925560408051918252602082019290925285916001600160a01b038816917fa36339e77124f707069252e7a04f56b467507541182e9e4b2536c9f8377464ff910160405180910390a35050505050565b60006111dd611474565b80549091506001190161120357604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b6040516323b872dd60e01b815283906001600160a01b038216906323b872dd9061123b90869030908790600401611812565b600060405180830381600087803b15801561125557600080fd5b505af1158015611269573d6000803e3d6000fd5b5050505050505050565b604051630310ed7f60e41b815260048101849052602481018390526044810182905284906001600160a01b0382169063310ed7f090606401600060405180830381600087803b1580156112c557600080fd5b505af11580156112d9573d6000803e3d6000fd5b505050505050505050565b6040516323b872dd60e01b815283906001600160a01b038216906323b872dd9061123b90309087908790600401611812565b6040516307a42e0160e11b815260009084906001600160a01b03821690630f485c029061134b90879030908890600401611836565b6020604051808303816000875af115801561136a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138e9190611731565b95945050505050565b60006113a1611474565b6001905550565b6040516307a42e0160e11b815260009085906001600160a01b03821690630f485c02906113dd90889088908890600401611836565b6020604051808303816000875af11580156113fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114209190611731565b9695505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0090565b611456611498565b61145f816114bd565b50565b61146a611498565b611472611509565b565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0090565b6114a0611511565b61147257604051631afcd79f60e31b815260040160405180910390fd5b6114c5611498565b600080546001600160a01b0319166001600160a01b038316178155604051600080516020611896833981519152916114fe9184906116ac565b60405180910390a150565b611397611498565b600061151b61142a565b54600160401b900460ff16919050565b6001600160a01b038116811461145f57600080fd5b60008060006060848603121561155557600080fd5b83356115608161152b565b95602085013595506040909401359392505050565b6000806040838503121561158857600080fd5b82356115938161152b565b946020939093013593505050565b600080600080608085870312156115b757600080fd5b84356115c28161152b565b93506020850135925060408501356115d98161152b565b9396929550929360600135925050565b600080600080608085870312156115ff57600080fd5b843561160a8161152b565b966020860135965060408601359560600135945092505050565b60006020828403121561163657600080fd5b81356116418161152b565b9392505050565b8035801515811461165857600080fd5b919050565b6000806000806080858703121561167357600080fd5b843561167e8161152b565b93506020850135925061169360408601611648565b91506116a160608601611648565b905092959194509250565b6001600160a01b0392831681529116602082015260400190565b6000602082840312156116d857600080fd5b81516116418161152b565b6020808252602e908201527f536f6c764254434d756c74694173736574506f6f6c3a2063616c6c657220697360408201526d103737ba1039b33a1037bbb732b960911b606082015260800190565b60006020828403121561174357600080fd5b5051919050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039390931683526020830191909152604082015260600190565b6020808252600a908201526937b7363c9030b236b4b760b11b604082015260600190565b6000602082840312156117ba57600080fd5b815160ff8116811461164157600080fd5b60208082526027908201527f536f6c764254434d756c74694173736574506f6f6c3a20736c6f74206e6f74206040820152661b585d18da195960ca1b606082015260800190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b9283526001600160a01b0391909116602083015260408201526060019056fe536f6c764254434d756c74694173736574506f6f6c3a206465706f7369742061536f6c764254434d756c74694173736574506f6f6c3a2073667420736c6f7420f9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dca2646970667358221220796dea34e37d6ef38d596a87ec1ee8048aa84e7a7dfb299d535dc4423c540f5964736f6c63430008140033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.