refactored with more efficient erc1155

master
lza_menace 2 years ago
parent 7e5c8ae24a
commit 5c3222664c

@ -10,22 +10,16 @@ contract ShipIt is Ownable {
mapping(address => address) public addressVault; // users can store their personal vaults for ease of use
uint256 public usageFee = .00015 ether; // charge a small fee for the cost savings it provides
event TokenTransfer(address indexed contractAddress, uint256 tokenIndex, address indexed from, address indexed to);
/*************************
Modifiers
**************************/
modifier onlyIfTokenOwner(
address contractAddress,
uint256 tokenIndex,
bool isERC1155
modifier onlyIfPaid(
address[] calldata recipients,
uint256[] calldata tokenIndexes
) {
if (isERC1155) {
require(ERC1155(contractAddress).balanceOf(msg.sender, tokenIndex) > 0, "You must own the token.");
} else {
require(msg.sender == ERC721(contractAddress).ownerOf(tokenIndex), "You must own the token.");
}
require(tokenIndexes.length == recipients.length, "Array lengths must match.");
require(msg.value >= tokenIndexes.length * usageFee, "Invalid usage fee sent.");
_;
}
@ -50,34 +44,31 @@ contract ShipIt is Ownable {
addressVault[msg.sender] = vaultAddress;
}
function contractTransfer(
// Expects flat list of recipients and token IDs
function erc721BulkTransfer(
address contractAddress,
uint256 tokenIndex,
address recipient,
bool isERC1155
) private {
if (isERC1155) {
require(ERC1155(contractAddress).balanceOf(msg.sender, tokenIndex) > 0, "Sender is not the token owner, cannot proceed with transfer.");
require(ERC1155(contractAddress).isApprovedForAll(msg.sender, address(this)), "Contract not approved to send tokens on Sender behalf.");
ERC1155(contractAddress).safeTransferFrom(msg.sender, recipient, tokenIndex, 1, bytes(""));
} else {
require(msg.sender == ERC721(contractAddress).ownerOf(tokenIndex), "Sender is not the token owner, cannot proceed with transfer.");
require(ERC721(contractAddress).isApprovedForAll(msg.sender, address(this)), "Contract not approved to send tokens on Sender behalf.");
ERC721(contractAddress).safeTransferFrom(msg.sender, recipient, tokenIndex);
address[] calldata recipients,
uint256[] calldata tokenIndexes
) external payable onlyIfPaid(recipients, tokenIndexes) {
require(ERC721(contractAddress).isApprovedForAll(msg.sender, address(this)), "Contract not approved to send tokens on Sender behalf.");
for(uint256 i; i < tokenIndexes.length; i++) {
require(msg.sender == ERC721(contractAddress).ownerOf(tokenIndexes[i]), "Sender is not the token owner, cannot proceed with transfer.");
ERC721(contractAddress).safeTransferFrom(msg.sender, recipients[i], tokenIndexes[i]);
}
emit TokenTransfer(contractAddress, tokenIndex, msg.sender, recipient);
}
function contractBulkTransfer(
// Expects a tally of ERC-1155 token amounts batched beforehand for simple sending
function erc1155BulkTransfer(
address contractAddress,
uint256[] calldata tokenIndexes,
address[] calldata recipients,
bool isERC1155
) external payable {
require(tokenIndexes.length == recipients.length, "Array lengths must match.");
require(msg.value >= tokenIndexes.length * usageFee, "Invalid usage fee sent.");
uint256[] calldata tokenIndexes,
uint256[] calldata amounts
) external payable onlyIfPaid(recipients, tokenIndexes) {
require(amounts.length == recipients.length, "Array lengths must match.");
require(ERC1155(contractAddress).isApprovedForAll(msg.sender, address(this)), "Contract not approved to send tokens on Sender behalf.");
for(uint256 i; i < tokenIndexes.length; i++) {
contractTransfer(contractAddress, tokenIndexes[i], recipients[i], isERC1155);
require(ERC1155(contractAddress).balanceOf(msg.sender, tokenIndexes[i]) >= amounts[i], "Not enough balance owned of the given token ID.");
ERC1155(contractAddress).safeTransferFrom(msg.sender, recipients[i], tokenIndexes[i], amounts[i], bytes(""));
}
}

@ -34,11 +34,10 @@ contract ShipItTest is Test {
vm.startPrank(address(5));
nft721.mint(amt);
nft721.setApprovalForAll(address(shipit), true);
shipit.contractBulkTransfer{value: val}(
shipit.erc721BulkTransfer{value: val}(
address(nft721),
tokenIndexes,
recipients,
false
tokenIndexes
);
// assert balances
}
@ -58,11 +57,10 @@ contract ShipItTest is Test {
nft721.setApprovalForAll(address(shipit), true);
vm.stopPrank();
vm.prank(address(3));
shipit.contractBulkTransfer{value: val}(
shipit.erc721BulkTransfer{value: val}(
address(nft721),
tokenIndexes,
recipients,
false
tokenIndexes
);
}
@ -70,33 +68,40 @@ contract ShipItTest is Test {
uint256 amt = 10;
uint256 fee = shipit.usageFee();
uint256 val = fee * amt;
uint256[] memory tokenIndexes = new uint256[](amt);
address[] memory recipients = new address[](amt);
for (uint256 i; i < amt; i++) {
tokenIndexes[i] = 1;
recipients[i] = address(1);
}
vm.deal(address(5), 1 ether);
vm.startPrank(address(5));
address[] memory recipients = new address[](2);
uint256[] memory tokenIndexes = new uint256[](2);
uint256[] memory amounts = new uint256[](2);
recipients[0] = address(11);
recipients[1] = address(11);
tokenIndexes[0] = 1;
tokenIndexes[1] = 5;
amounts[0] = amt;
amounts[1] = amt;
vm.deal(address(50), 1 ether);
vm.startPrank(address(50));
nft1155.mint(1, amt);
nft1155.mint(5, amt);
nft1155.setApprovalForAll(address(shipit), true);
shipit.contractBulkTransfer{value: val}(
shipit.erc1155BulkTransfer{value: val}(
address(nft1155),
tokenIndexes,
recipients,
true
tokenIndexes,
amounts
);
assertEq(nft1155.balanceOf(address(1), 1), 10);
assertEq(nft1155.balanceOf(address(11), 1), 10);
assertEq(nft1155.balanceOf(address(11), 5), 10);
}
function testFail1155NonTokenOwnerCanSend() public {
uint256 amt = 1;
uint256 fee = shipit.usageFee();
uint256 val = fee * amt;
uint256[] memory tokenIndexes = new uint256[](amt);
address[] memory recipients = new address[](amt);
uint256[] memory tokenIndexes = new uint256[](amt);
uint256[] memory amounts = new uint256[](amt);
tokenIndexes[0] = 1;
recipients[0] = address(1);
amounts[0] = amt;
vm.deal(address(5), 1 ether);
vm.deal(address(3), 1 ether);
vm.startPrank(address(5));
@ -104,11 +109,11 @@ contract ShipItTest is Test {
nft1155.setApprovalForAll(address(shipit), true);
vm.stopPrank();
vm.prank(address(3));
shipit.contractBulkTransfer{value: val}(
shipit.erc1155BulkTransfer{value: val}(
address(nft1155),
tokenIndexes,
recipients,
true
tokenIndexes,
amounts
);
}

Loading…
Cancel
Save