diff --git a/contracts/CollateralVault/impl/NFTCollateralVault.sol b/contracts/CollateralVault/impl/NFTCollateralVault.sol index 04fe1ee..58015c3 100644 --- a/contracts/CollateralVault/impl/NFTCollateralVault.sol +++ b/contracts/CollateralVault/impl/NFTCollateralVault.sol @@ -11,13 +11,50 @@ import {SafeMath} from "../../lib/SafeMath.sol"; import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; import {IERC721} from "../../intf/IERC721.sol"; import {IERC721Receiver} from "../../intf/IERC721Receiver.sol"; +import {IERC1155} from "../../intf/IERC1155.sol"; +import {IERC1155Receiver} from "../../intf/IERC1155Receiver.sol"; contract NFTCollateralVault is InitializableOwnable, IERC721Receiver, ReentrancyGuard { - mapping(address => uint256[]) public _COLLECTIONS_; - address[] public _COLLECTION_ADDRESSES_; function transferOwnership(address newOwner) external override onlyOwner { emit OwnershipTransferred(_OWNER_, newOwner); _OWNER_ = newOwner; } + + function withdrawERC721(address nftContract, uint256 tokenId) onlyOwner { + IERC721(nftContract).safeTransferFrom(msg.sender, _OWNER_, tokenId, ""); + } + + function withdrawERC1155(address nftContract, uint256[] tokenIds, uint256[] amounts) onlyOwner { + IERC1155(nftContract).safeBatchTransferFrom(msg.sender, _OWNER_, tokenIds, amounts, ""); + } + + function onERC721Received( + address operator, + address from, + uint256 tokenId, + bytes calldata data + ) external returns (bytes4) { + return IERC721Receiver.onERC721Received.selector; + } + + function onERC1155Received( + address operator, + address from, + uint256 id, + uint256 value, + bytes calldata data + ) external returns (bytes4){ + return IERC1155Receiver.onERC1155Received.selector; + }; + + function onERC1155BatchReceived( + address operator, + address from, + uint256[] calldata ids, + uint256[] calldata values, + bytes calldata data + ) external returns (bytes4){ + return IERC1155BatchReceiver.onERC1155BatchReceived.selector; + }; } diff --git a/contracts/intf/IERC1155.sol b/contracts/intf/IERC1155.sol new file mode 100644 index 0000000..c63e9b8 --- /dev/null +++ b/contracts/intf/IERC1155.sol @@ -0,0 +1,131 @@ +// This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.6/contracts/token/ERC1155/IERC1155.sol +// SPDX-License-Identifier: MIT + +pragma solidity >=0.6.2 <0.8.0; + +import "./IERC165.sol"; + +/** + * @dev Required interface of an ERC1155 compliant contract, as defined in the + * https://eips.ethereum.org/EIPS/eip-1155[EIP]. + * + * _Available since v3.1._ + */ +interface IERC1155 is IERC165 { + /** + * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. + */ + event TransferSingle( + address indexed operator, + address indexed from, + address indexed to, + uint256 id, + uint256 value + ); + + /** + * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all + * transfers. + */ + event TransferBatch( + address indexed operator, + address indexed from, + address indexed to, + uint256[] ids, + uint256[] values + ); + + /** + * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to + * `approved`. + */ + event ApprovalForAll(address indexed account, address indexed operator, bool approved); + + /** + * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. + * + * If an {URI} event was emitted for `id`, the standard + * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value + * returned by {IERC1155MetadataURI-uri}. + */ + event URI(string value, uint256 indexed id); + + /** + * @dev Returns the amount of tokens of token type `id` owned by `account`. + * + * Requirements: + * + * - `account` cannot be the zero address. + */ + function balanceOf(address account, uint256 id) external view returns (uint256); + + /** + * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. + * + * Requirements: + * + * - `accounts` and `ids` must have the same length. + */ + function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) + external + view + returns (uint256[] memory); + + /** + * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, + * + * Emits an {ApprovalForAll} event. + * + * Requirements: + * + * - `operator` cannot be the caller. + */ + function setApprovalForAll(address operator, bool approved) external; + + /** + * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. + * + * See {setApprovalForAll}. + */ + function isApprovedForAll(address account, address operator) external view returns (bool); + + /** + * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. + * + * Emits a {TransferSingle} event. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. + * - `from` must have a balance of tokens of type `id` of at least `amount`. + * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the + * acceptance magic value. + */ + function safeTransferFrom( + address from, + address to, + uint256 id, + uint256 amount, + bytes calldata data + ) external; + + /** + * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. + * + * Emits a {TransferBatch} event. + * + * Requirements: + * + * - `ids` and `amounts` must have the same length. + * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the + * acceptance magic value. + */ + function safeBatchTransferFrom( + address from, + address to, + uint256[] calldata ids, + uint256[] calldata amounts, + bytes calldata data + ) external; +} diff --git a/contracts/intf/IERC1155Receiver.sol b/contracts/intf/IERC1155Receiver.sol new file mode 100644 index 0000000..1acba02 --- /dev/null +++ b/contracts/intf/IERC1155Receiver.sol @@ -0,0 +1,53 @@ +// This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/IERC1155Receiver.sol +// SPDX-License-Identifier: MIT + +pragma solidity >=0.6.0 <0.8.0; + +import "./ERC165.sol"; + +/** + * _Available since v3.1._ + */ +interface IERC1155Receiver is IERC165 { + /** + @dev Handles the receipt of a single ERC1155 token type. This function is + called at the end of a `safeTransferFrom` after the balance has been updated. + To accept the transfer, this must return + `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` + (i.e. 0xf23a6e61, or its own function selector). + @param operator The address which initiated the transfer (i.e. msg.sender) + @param from The address which previously owned the token + @param id The ID of the token being transferred + @param value The amount of tokens being transferred + @param data Additional data with no specified format + @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed + */ + function onERC1155Received( + address operator, + address from, + uint256 id, + uint256 value, + bytes calldata data + ) external returns (bytes4); + + /** + @dev Handles the receipt of a multiple ERC1155 token types. This function + is called at the end of a `safeBatchTransferFrom` after the balances have + been updated. To accept the transfer(s), this must return + `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` + (i.e. 0xbc197c81, or its own function selector). + @param operator The address which initiated the batch transfer (i.e. msg.sender) + @param from The address which previously owned the token + @param ids An array containing ids of each token being transferred (order and length must match values array) + @param values An array containing amounts of each token being transferred (order and length must match ids array) + @param data Additional data with no specified format + @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed + */ + function onERC1155BatchReceived( + address operator, + address from, + uint256[] calldata ids, + uint256[] calldata values, + bytes calldata data + ) external returns (bytes4); +}