Skip to content

Commit

Permalink
support swap comment on safe transfer helper (#710)
Browse files Browse the repository at this point in the history
SecondarySwap currently doesnt support comments in the `onERC1155Received` hook - this updates that hook to handle including a mint comment.  It treats the `operator` argument, which is the msg.sender that initiated the transfer, as the one that emitted the comment.
  • Loading branch information
oveddan authored Sep 5, 2024
1 parent fe9d2df commit 27f1d5e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .changeset/stale-planets-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@zoralabs/erc20z": patch
---

SecondarySwap supports comment in safeTransfer method of selling
45 changes: 29 additions & 16 deletions packages/erc20z/src/helper/SecondarySwap.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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;
}
Expand Down
11 changes: 10 additions & 1 deletion packages/erc20z/test/helper/SecondarySwap.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down

0 comments on commit 27f1d5e

Please sign in to comment.