Created
March 29, 2023 19:11
-
-
Save thekillertoaster/c55d439dd1c05c22705830077eaa3ca7 to your computer and use it in GitHub Desktop.
Enabling the safe swapping of different NFTs between users. Requires setApprovalForAll to be ran on involved Token Contracts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // SPDX-License-Identifier: MIT | |
| pragma solidity ^0.8.0; | |
| import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; | |
| import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; | |
| contract ERC721TokenSwap is ReentrancyGuard { | |
| event SwapCreated(uint256 indexed swapId, address indexed trader1, address indexed trader2); | |
| event SwapExecuted(uint256 indexed swapId); | |
| struct Swap { | |
| address trader1; | |
| address trader2; | |
| address[] trader1TokenAddresses; | |
| uint256[] trader1TokenIds; | |
| address[] trader2TokenAddresses; | |
| uint256[] trader2TokenIds; | |
| bool trader1Approval; | |
| bool trader2Approval; | |
| } | |
| Swap[] public swaps; | |
| function createSwap( | |
| address _trader2, | |
| address[] memory _trader1TokenAddresses, | |
| uint256[] memory _trader1TokenIds, | |
| address[] memory _trader2TokenAddresses, | |
| uint256[] memory _trader2TokenIds | |
| ) external returns (uint256) { | |
| require(_trader1TokenIds.length > 0 && _trader2TokenIds.length > 0, "Both traders must have tokens to trade"); | |
| require(_trader1TokenAddresses.length == _trader1TokenIds.length, "Token addresses and IDs must match for trader1"); | |
| require(_trader2TokenAddresses.length == _trader2TokenIds.length, "Token addresses and IDs must match for trader2"); | |
| for (uint256 i = 0; i < _trader1TokenIds.length; i++) { | |
| require(IERC721(_trader1TokenAddresses[i]).ownerOf(_trader1TokenIds[i]) == msg.sender, "Trader1 does not own token"); | |
| } | |
| for (uint256 i = 0; i < _trader2TokenIds.length; i++) { | |
| require(IERC721(_trader2TokenAddresses[i]).ownerOf(_trader2TokenIds[i]) == _trader2, "Trader2 does not own token"); | |
| } | |
| uint256 swapId = swaps.length; | |
| swaps.push(Swap(msg.sender, _trader2, _trader1TokenAddresses, _trader1TokenIds, _trader2TokenAddresses, _trader2TokenIds, false, false)); | |
| emit SwapCreated(swapId, msg.sender, _trader2); | |
| return swapId; | |
| } | |
| function approveSwap(uint256 _swapId) external nonReentrant { | |
| Swap storage swap = swaps[_swapId]; | |
| require(msg.sender == swap.trader1 || msg.sender == swap.trader2, "Not a participant"); | |
| require(swap.trader1 != address(0) && swap.trader2 != address(0), "Invalid traders"); | |
| if (msg.sender == swap.trader1) { | |
| swap.trader1Approval = true; | |
| } else if (msg.sender == swap.trader2) { | |
| swap.trader2Approval = true; | |
| } | |
| if (swap.trader1Approval && swap.trader2Approval) { | |
| executeSwap(_swapId); | |
| } | |
| } | |
| function executeSwap(uint256 _swapId) private { | |
| Swap storage swap = swaps[_swapId]; | |
| for (uint256 i = 0; i < swap.trader1TokenIds.length; i++) { | |
| IERC721(swap.trader1TokenAddresses[i]).safeTransferFrom( | |
| swap.trader1, | |
| swap.trader2, | |
| swap.trader1TokenIds[i] | |
| ); | |
| } | |
| for (uint256 i = 0; i < swap.trader2TokenIds.length; i++) { | |
| IERC721(swap.trader2TokenAddresses[i]).safeTransferFrom( | |
| swap.trader2, | |
| swap.trader1, | |
| swap.trader2TokenIds[i] | |
| ); | |
| } | |
| emit SwapExecuted(_swapId); | |
| delete swaps[_swapId]; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment