diff --git a/.changeset/stale-planets-watch.md b/.changeset/stale-planets-watch.md new file mode 100644 index 000000000..a835e710d --- /dev/null +++ b/.changeset/stale-planets-watch.md @@ -0,0 +1,5 @@ +--- +"@zoralabs/erc20z": patch +--- + +SecondarySwap supports comment in safeTransfer method of selling diff --git a/packages/erc20z/src/helper/SecondarySwap.sol b/packages/erc20z/src/helper/SecondarySwap.sol index 1693bbc58..cc1dc3b13 100644 --- a/packages/erc20z/src/helper/SecondarySwap.sol +++ b/packages/erc20z/src/helper/SecondarySwap.sol @@ -115,18 +115,22 @@ contract SecondarySwap is ISecondarySwap, ReentrancyGuard, IERC1155Receiver { ) external nonReentrant { IERC20Z.TokenInfo memory tokenInfo = IERC20Z(erc20zAddress).tokenInfo(); - // Transfer ERC1155 tokens from sender to this contract and wrap them IERC1155(tokenInfo.collection).safeTransferFrom(msg.sender, erc20zAddress, tokenInfo.tokenId, num1155ToSell, abi.encode(address(this))); - _sell1155(erc20zAddress, num1155ToSell, recipient, minEthToAcquire, sqrtPriceLimitX96); - - if (bytes(comment).length > 0) { - emit SecondaryComment(msg.sender, tokenInfo.collection, tokenInfo.tokenId, num1155ToSell, comment, SecondaryType.SELL); - } + _sell1155(tokenInfo, msg.sender, erc20zAddress, num1155ToSell, recipient, minEthToAcquire, sqrtPriceLimitX96, comment); } /// @notice ERC1155 -> ERC20Z -> WETH -> ETH - function _sell1155(address erc20zAddress, uint256 num1155ToSell, address payable recipient, uint256 minEthToAcquire, uint160 sqrtPriceLimitX96) private { + function _sell1155( + IERC20Z.TokenInfo memory tokenInfo, + address msgSender, + address erc20zAddress, + uint256 num1155ToSell, + address payable recipient, + uint256 minEthToAcquire, + uint160 sqrtPriceLimitX96, + string memory comment + ) private { // Ensure the recipient is valid if (recipient == address(0)) { revert InvalidRecipient(); @@ -163,27 +167,36 @@ contract SecondarySwap is ISecondarySwap, ReentrancyGuard, IERC1155Receiver { // Transfer ETH to the recipient Address.sendValue(recipient, amountWethOut); - emit SecondarySell(msg.sender, recipient, erc20zAddress, amountWethOut, num1155ToSell); + if (bytes(comment).length > 0) { + emit SecondaryComment(msgSender, tokenInfo.collection, tokenInfo.tokenId, num1155ToSell, comment, SecondaryType.SELL); + } + + emit SecondarySell(msgSender, recipient, erc20zAddress, amountWethOut, num1155ToSell); } /// @notice Receive transfer hook that allows to sell 1155s for eth based on the secondary market value - function onERC1155Received(address, address, uint256 id, uint256 value, bytes calldata data) external override nonReentrant returns (bytes4) { - address collection = msg.sender; + function onERC1155Received(address operator, address, uint256 id, uint256 value, bytes calldata data) external override nonReentrant returns (bytes4) { + IERC20Z.TokenInfo memory tokenInfo; + + tokenInfo.collection = msg.sender; + tokenInfo.tokenId = id; uint256 num1155ToSell = value; - (address payable recipient, uint256 minEthToAcquire, uint160 sqrtPriceLimitX96) = abi.decode(data, (address, uint256, uint160)); + (address payable recipient, uint256 minEthToAcquire, uint160 sqrtPriceLimitX96, string memory comment) = abi.decode( + data, + (address, uint256, uint160, string) + ); - address erc20zAddress = zoraTimedSaleStrategy.sale(collection, id).erc20zAddress; + address erc20zAddress = zoraTimedSaleStrategy.sale(tokenInfo.collection, tokenInfo.tokenId).erc20zAddress; if (erc20zAddress == address(0)) { revert SaleNotSet(); } - // assume this contract has 1155s, transfer them to the erc20z and wrap them - IERC1155(collection).safeTransferFrom(address(this), erc20zAddress, id, num1155ToSell, abi.encode(address(this))); - - _sell1155(erc20zAddress, num1155ToSell, recipient, minEthToAcquire, sqrtPriceLimitX96); + IERC1155(tokenInfo.collection).safeTransferFrom(address(this), erc20zAddress, id, num1155ToSell, abi.encode(address(this))); + // in the case of a safeTransferFrom, the operator is the msg.sender + _sell1155(tokenInfo, operator, erc20zAddress, num1155ToSell, recipient, minEthToAcquire, sqrtPriceLimitX96, comment); return ON_ERC1155_RECEIVED_HASH; } diff --git a/packages/erc20z/test/helper/SecondarySwap.t.sol b/packages/erc20z/test/helper/SecondarySwap.t.sol index 81ffc2264..3f605dd3f 100644 --- a/packages/erc20z/test/helper/SecondarySwap.t.sol +++ b/packages/erc20z/test/helper/SecondarySwap.t.sol @@ -113,7 +113,16 @@ contract SecondarySwapTest is BaseTest { minEthToAcquire = 0; vm.startPrank(mockBuyer); - collection.safeTransferFrom(mockBuyer, address(secondarySwap), 0, num1155ToTransfer, abi.encode(mockBuyer, minEthToAcquire, sqrtPriceLimitX96)); + + vm.expectEmit(true, true, true, true); + emit SecondaryComment(mockBuyer, address(collection), tokenId, num1155ToReceive, "sell comment", ISecondarySwap.SecondaryType.SELL); + collection.safeTransferFrom( + mockBuyer, + address(secondarySwap), + 0, + num1155ToTransfer, + abi.encode(mockBuyer, minEthToAcquire, sqrtPriceLimitX96, "sell comment") + ); vm.stopPrank();