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 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 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 Modifiers
**************************/ **************************/
modifier onlyIfTokenOwner( modifier onlyIfPaid(
address contractAddress, address[] calldata recipients,
uint256 tokenIndex, uint256[] calldata tokenIndexes
bool isERC1155
) { ) {
if (isERC1155) { require(tokenIndexes.length == recipients.length, "Array lengths must match.");
require(ERC1155(contractAddress).balanceOf(msg.sender, tokenIndex) > 0, "You must own the token."); require(msg.value >= tokenIndexes.length * usageFee, "Invalid usage fee sent.");
} else {
require(msg.sender == ERC721(contractAddress).ownerOf(tokenIndex), "You must own the token.");
}
_; _;
} }
@ -50,34 +44,31 @@ contract ShipIt is Ownable {
addressVault[msg.sender] = vaultAddress; addressVault[msg.sender] = vaultAddress;
} }
function contractTransfer( // Expects flat list of recipients and token IDs
function erc721BulkTransfer(
address contractAddress, address contractAddress,
uint256 tokenIndex, address[] calldata recipients,
address recipient, uint256[] calldata tokenIndexes
bool isERC1155 ) external payable onlyIfPaid(recipients, tokenIndexes) {
) private { require(ERC721(contractAddress).isApprovedForAll(msg.sender, address(this)), "Contract not approved to send tokens on Sender behalf.");
if (isERC1155) { for(uint256 i; i < tokenIndexes.length; i++) {
require(ERC1155(contractAddress).balanceOf(msg.sender, tokenIndex) > 0, "Sender is not the token owner, cannot proceed with transfer."); require(msg.sender == ERC721(contractAddress).ownerOf(tokenIndexes[i]), "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."); ERC721(contractAddress).safeTransferFrom(msg.sender, recipients[i], tokenIndexes[i]);
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);
} }
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, address contractAddress,
uint256[] calldata tokenIndexes,
address[] calldata recipients, address[] calldata recipients,
bool isERC1155 uint256[] calldata tokenIndexes,
) external payable { uint256[] calldata amounts
require(tokenIndexes.length == recipients.length, "Array lengths must match."); ) external payable onlyIfPaid(recipients, tokenIndexes) {
require(msg.value >= tokenIndexes.length * usageFee, "Invalid usage fee sent."); 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++) { 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)); vm.startPrank(address(5));
nft721.mint(amt); nft721.mint(amt);
nft721.setApprovalForAll(address(shipit), true); nft721.setApprovalForAll(address(shipit), true);
shipit.contractBulkTransfer{value: val}( shipit.erc721BulkTransfer{value: val}(
address(nft721), address(nft721),
tokenIndexes,
recipients, recipients,
false tokenIndexes
); );
// assert balances // assert balances
} }
@ -58,11 +57,10 @@ contract ShipItTest is Test {
nft721.setApprovalForAll(address(shipit), true); nft721.setApprovalForAll(address(shipit), true);
vm.stopPrank(); vm.stopPrank();
vm.prank(address(3)); vm.prank(address(3));
shipit.contractBulkTransfer{value: val}( shipit.erc721BulkTransfer{value: val}(
address(nft721), address(nft721),
tokenIndexes,
recipients, recipients,
false tokenIndexes
); );
} }
@ -70,33 +68,40 @@ contract ShipItTest is Test {
uint256 amt = 10; uint256 amt = 10;
uint256 fee = shipit.usageFee(); uint256 fee = shipit.usageFee();
uint256 val = fee * amt; uint256 val = fee * amt;
uint256[] memory tokenIndexes = new uint256[](amt); address[] memory recipients = new address[](2);
address[] memory recipients = new address[](amt); uint256[] memory tokenIndexes = new uint256[](2);
for (uint256 i; i < amt; i++) { uint256[] memory amounts = new uint256[](2);
tokenIndexes[i] = 1; recipients[0] = address(11);
recipients[i] = address(1); recipients[1] = address(11);
} tokenIndexes[0] = 1;
vm.deal(address(5), 1 ether); tokenIndexes[1] = 5;
vm.startPrank(address(5)); amounts[0] = amt;
amounts[1] = amt;
vm.deal(address(50), 1 ether);
vm.startPrank(address(50));
nft1155.mint(1, amt); nft1155.mint(1, amt);
nft1155.mint(5, amt);
nft1155.setApprovalForAll(address(shipit), true); nft1155.setApprovalForAll(address(shipit), true);
shipit.contractBulkTransfer{value: val}( shipit.erc1155BulkTransfer{value: val}(
address(nft1155), address(nft1155),
tokenIndexes,
recipients, 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 { function testFail1155NonTokenOwnerCanSend() public {
uint256 amt = 1; uint256 amt = 1;
uint256 fee = shipit.usageFee(); uint256 fee = shipit.usageFee();
uint256 val = fee * amt; uint256 val = fee * amt;
uint256[] memory tokenIndexes = new uint256[](amt);
address[] memory recipients = new address[](amt); address[] memory recipients = new address[](amt);
uint256[] memory tokenIndexes = new uint256[](amt);
uint256[] memory amounts = new uint256[](amt);
tokenIndexes[0] = 1; tokenIndexes[0] = 1;
recipients[0] = address(1); recipients[0] = address(1);
amounts[0] = amt;
vm.deal(address(5), 1 ether); vm.deal(address(5), 1 ether);
vm.deal(address(3), 1 ether); vm.deal(address(3), 1 ether);
vm.startPrank(address(5)); vm.startPrank(address(5));
@ -104,11 +109,11 @@ contract ShipItTest is Test {
nft1155.setApprovalForAll(address(shipit), true); nft1155.setApprovalForAll(address(shipit), true);
vm.stopPrank(); vm.stopPrank();
vm.prank(address(3)); vm.prank(address(3));
shipit.contractBulkTransfer{value: val}( shipit.erc1155BulkTransfer{value: val}(
address(nft1155), address(nft1155),
tokenIndexes,
recipients, recipients,
true tokenIndexes,
amounts
); );
} }

Loading…
Cancel
Save