diff --git a/contracts/ERC1155Safe.sol b/contracts/ERC1155Safe.sol index b13237b0..f3950219 100644 --- a/contracts/ERC1155Safe.sol +++ b/contracts/ERC1155Safe.sol @@ -23,9 +23,43 @@ contract ERC1155Safe { @param amounts Amounts of tokens to transfer. @param data Additional data. */ - function lockBatchERC1155(address tokenAddress, address owner, address recipient, uint[] memory tokenIDs, uint[] memory amounts, bytes memory data) internal { + function lockBatchERC1155( + address tokenAddress, + address owner, + address recipient, + uint256[] memory tokenIDs, + uint256[] memory amounts, + bytes memory data + ) internal { IERC1155 erc1155 = IERC1155(tokenAddress); - erc1155.safeBatchTransferFrom(owner, recipient, tokenIDs, amounts, data); + erc1155.safeBatchTransferFrom( + owner, + recipient, + tokenIDs, + amounts, + data + ); + } + + /** + @notice Used to gain custoday of deposited token + @param tokenAddress Address of ERC1155 to transfer. + @param owner Address of current token owner. + @param recipient Address to transfer token to. + @param tokenID ID of tokens to transfer. + @param amount Amount of tokens to transfer. + @param data Additional data. + */ + function lockERC1155( + address tokenAddress, + address owner, + address recipient, + uint256 tokenID, + uint256 amount, + bytes memory data + ) internal { + IERC1155 erc1155 = IERC1155(tokenAddress); + erc1155.safeTransferFrom(owner, recipient, tokenID, amount, data); } /** @@ -37,9 +71,41 @@ contract ERC1155Safe { @param amounts Amounts of tokens to transfer. @param data Additional data. */ - function releaseBatchERC1155(address tokenAddress, address owner, address recipient, uint256[] memory tokenIDs, uint[] memory amounts, bytes memory data) internal { + function releaseBatchERC1155( + address tokenAddress, + address owner, + address recipient, + uint256[] memory tokenIDs, + uint256[] memory amounts, + bytes memory data + ) internal { IERC1155 erc1155 = IERC1155(tokenAddress); - erc1155.safeBatchTransferFrom(owner, recipient, tokenIDs, amounts, data); + erc1155.safeBatchTransferFrom( + owner, + recipient, + tokenIDs, + amounts, + data + ); + } + + /** + @notice Transfers custody of token to recipient. + @param tokenAddress Address of ERC1155 to transfer. + @param owner Address of current token owner. + @param recipient Address to transfer token to. + @param tokenID ID of tokens to transfer. + @param amount Amount of tokens to transfer. + */ + function releaseERC1155( + address tokenAddress, + address owner, + address recipient, + uint256 tokenID, + uint256 amount + ) internal { + IERC1155 erc1155 = IERC1155(tokenAddress); + erc1155.safeTransferFrom(owner, recipient, tokenID, amount, "0x"); } /** @@ -50,19 +116,67 @@ contract ERC1155Safe { @param amounts Amounts of token to mint. @param data Additional data. */ - function mintBatchERC1155(address tokenAddress, address recipient, uint[] memory tokenIDs, uint[] memory amounts, bytes memory data) internal { - ERC1155PresetMinterPauser erc1155 = ERC1155PresetMinterPauser(tokenAddress); + function mintBatchERC1155( + address tokenAddress, + address recipient, + uint256[] memory tokenIDs, + uint256[] memory amounts, + bytes memory data + ) internal { + ERC1155PresetMinterPauser erc1155 = ERC1155PresetMinterPauser( + tokenAddress + ); erc1155.mintBatch(recipient, tokenIDs, amounts, data); } + /** + @notice Used to create new ERC1155 + @param tokenAddress Address of ERC1155 to mint. + @param recipient Address to mint token to. + @param tokenID ID of tokens to mint. + @param amount Amount of token to mint. + */ + function mintERC1155( + address tokenAddress, + address recipient, + uint256 tokenID, + uint256 amount + ) internal { + ERC1155PresetMinterPauser erc1155 = ERC1155PresetMinterPauser( + tokenAddress + ); + erc1155.mint(recipient, tokenID, amount, "0x"); + } + /** @notice Used to burn ERC1155s with batching. @param tokenAddress Address of ERC1155 to burn. @param tokenIDs IDs of tokens to burn. @param amounts Amounts of tokens to burn. */ - function burnBatchERC1155(address tokenAddress, address owner, uint[] memory tokenIDs, uint[] memory amounts) internal { + function burnBatchERC1155( + address tokenAddress, + address owner, + uint256[] memory tokenIDs, + uint256[] memory amounts + ) internal { ERC1155Burnable erc1155 = ERC1155Burnable(tokenAddress); erc1155.burnBatch(owner, tokenIDs, amounts); } + + /** + @notice Used to burn ERC1155. + @param tokenAddress Address of ERC1155 to burn. + @param tokenID ID of tokens to burn. + @param amount Amount of tokens to burn. + */ + function burnERC1155( + address tokenAddress, + address owner, + uint256 tokenID, + uint256 amount + ) internal { + ERC1155Burnable erc1155 = ERC1155Burnable(tokenAddress); + erc1155.burn(owner, tokenID, amount); + } } diff --git a/contracts/handlers/ERC1155Handler.sol b/contracts/handlers/ERC1155Handler.sol index 90e86fd9..2d2162ee 100644 --- a/contracts/handlers/ERC1155Handler.sol +++ b/contracts/handlers/ERC1155Handler.sol @@ -9,7 +9,12 @@ import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol"; import "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol"; -contract ERC1155Handler is IDepositExecute, HandlerHelpers, ERC1155Safe, ERC1155Holder { +contract ERC1155Handler is + IDepositExecute, + HandlerHelpers, + ERC1155Safe, + ERC1155Holder +{ using ERC165Checker for address; bytes4 private constant _INTERFACE_ERC1155_METADATA = 0x0e89341c; @@ -18,30 +23,41 @@ contract ERC1155Handler is IDepositExecute, HandlerHelpers, ERC1155Safe, ERC1155 /** @param bridgeAddress Contract address of previously deployed Bridge. */ - constructor( - address bridgeAddress - ) public HandlerHelpers(bridgeAddress) { - } + constructor(address bridgeAddress) HandlerHelpers(bridgeAddress) {} /** @notice A deposit is initiatied by making a deposit in the Bridge contract. @param resourceID ResourceID used to find address of token to be used for deposit. @param depositer Address of account making the deposit in the Bridge contract. - @param data Consists of ABI-encoded arrays of tokenIDs and amounts. + @param data Consists of ABI-encoded arrays of tokenID and amount. */ - function deposit(bytes32 resourceID, address depositer, bytes calldata data) external override onlyBridge returns (bytes memory metaData) { - uint[] memory tokenIDs; - uint[] memory amounts; + function deposit( + bytes32 resourceID, + address depositer, + bytes calldata data + ) external override onlyBridge returns (bytes memory metaData) { + uint256 tokenID; + uint256 amount; - (tokenIDs, amounts) = abi.decode(data, (uint[], uint[])); + (tokenID, amount) = abi.decode(data, (uint256, uint256)); address tokenAddress = _resourceIDToTokenContractAddress[resourceID]; - require(tokenAddress != address(0), "provided resourceID does not exist"); + require( + tokenAddress != address(0), + "provided resourceID does not exist" + ); if (_burnList[tokenAddress]) { - burnBatchERC1155(tokenAddress, depositer, tokenIDs, amounts); + burnERC1155(tokenAddress, depositer, tokenID, amount); } else { - lockBatchERC1155(tokenAddress, depositer, address(this), tokenIDs, amounts, EMPTY_BYTES); + lockERC1155( + tokenAddress, + depositer, + address(this), + tokenID, + amount, + EMPTY_BYTES + ); } } @@ -51,27 +67,51 @@ contract ERC1155Handler is IDepositExecute, HandlerHelpers, ERC1155Safe, ERC1155 @param data Consists of ABI-encoded {tokenIDs}, {amounts}, {recipient}, and {transferData} of types uint[], uint[], bytes, bytes. */ - function executeProposal(bytes32 resourceID, bytes calldata data) external override onlyBridge { - uint[] memory tokenIDs; - uint[] memory amounts; - bytes memory recipient; - bytes memory transferData; - - (tokenIDs, amounts, recipient, transferData) = abi.decode(data, (uint[], uint[], bytes, bytes)); + function executeProposal(bytes32 resourceID, bytes calldata data) + external + override + onlyBridge + { + uint256 tokenID; + uint256 amount; + uint256 lenDestinationRecipientAddress; + bytes memory destinationRecipientAddress; + + (tokenID, amount, lenDestinationRecipientAddress) = abi.decode( + data, + (uint256, uint256, uint256) + ); + destinationRecipientAddress = bytes( + data[96:96 + lenDestinationRecipientAddress] + ); bytes20 recipientAddress; + address tokenAddress = _resourceIDToTokenContractAddress[resourceID]; assembly { - recipientAddress := mload(add(recipient, 0x20)) + recipientAddress := mload(add(destinationRecipientAddress, 0x20)) } - address tokenAddress = _resourceIDToTokenContractAddress[resourceID]; - require(_contractWhitelist[address(tokenAddress)], "provided tokenAddress is not whitelisted"); + require( + _contractWhitelist[address(tokenAddress)], + "provided tokenAddress is not whitelisted" + ); if (_burnList[tokenAddress]) { - mintBatchERC1155(tokenAddress, address(recipientAddress), tokenIDs, amounts, transferData); + mintERC1155( + tokenAddress, + address(recipientAddress), + tokenID, + amount + ); } else { - releaseBatchERC1155(tokenAddress, address(this), address(recipientAddress), tokenIDs, amounts, transferData); + releaseERC1155( + tokenAddress, + address(this), + address(recipientAddress), + tokenID, + amount + ); } } @@ -83,12 +123,22 @@ contract ERC1155Handler is IDepositExecute, HandlerHelpers, ERC1155Safe, ERC1155 function withdraw(bytes memory data) external override onlyBridge { address tokenAddress; address recipient; - uint[] memory tokenIDs; - uint[] memory amounts; + uint256[] memory tokenIDs; + uint256[] memory amounts; bytes memory transferData; - (tokenAddress, recipient, tokenIDs, amounts, transferData) = abi.decode(data, (address, address, uint[], uint[], bytes)); - - releaseBatchERC1155(tokenAddress, address(this), recipient, tokenIDs, amounts, transferData); + (tokenAddress, recipient, tokenIDs, amounts, transferData) = abi.decode( + data, + (address, address, uint256[], uint256[], bytes) + ); + + releaseBatchERC1155( + tokenAddress, + address(this), + recipient, + tokenIDs, + amounts, + transferData + ); } } diff --git a/scripts/geth/genesis.json b/scripts/geth/genesis.json index 2314f3a9..ae5e4f01 100644 --- a/scripts/geth/genesis.json +++ b/scripts/geth/genesis.json @@ -1,6 +1,6 @@ { "config": { - "chainId": 5, + "chainId": 1005, "homesteadBlock": 0, "eip150Block": 0, "eip155Block": 0, @@ -21,6 +21,9 @@ "0x8e0a907331554AF72563Bd8D43051C2E64Be5d35": { "balance": "20000000000000000000"}, "0x24962717f8fA5BA3b931bACaF9ac03924EB475a0": { "balance": "20000000000000000000"}, "0x148FfB2074A9e59eD58142822b3eB3fcBffb0cd7": { "balance": "20000000000000000000"}, + "0x47EA8219Cc2b646AC6a10Ae9E59a82CB2A103Ac9": { "balance": "20000000000000000000"}, + "0xB03C52C465F0Fb2A7229A70C5a1D79d6c30162B0": { "balance": "20000000000000000000"}, + "0x49c965a2194b4630bc05291243e834864762fcea": { "balance": "20000000000000000000"}, "0x4CEEf6139f00F9F4535Ad19640Ff7A0137708485": { "balance": "20000000000000000000"} } -} \ No newline at end of file +} diff --git a/scripts/geth/start_geth.sh b/scripts/geth/start_geth.sh index 2d5233a9..971bfb5b 100755 --- a/scripts/geth/start_geth.sh +++ b/scripts/geth/start_geth.sh @@ -22,13 +22,13 @@ if [[ $QUIET ]]; then --unlock "0xff93B45308FD417dF303D6515aB04D9e89a750Ca","0x8e0a907331554AF72563Bd8D43051C2E64Be5d35","0x24962717f8fA5BA3b931bACaF9ac03924EB475a0","0x148FfB2074A9e59eD58142822b3eB3fcBffb0cd7","0x4CEEf6139f00F9F4535Ad19640Ff7A0137708485" \ --password ./scripts/geth/password.txt \ --ws \ - --wsport 8545 \ - --networkid 5 \ - --wsorigins="*" \ - --rpc \ - --rpcport 8545 \ - --rpccorsdomain="*" \ - --targetgaslimit 8000000 \ + --ws.port 8545 \ + --networkid 1005 \ + --ws.origins="*" \ + --http \ + --http.port 8545 \ + --http.corsdomain="*" \ + --dev.gaslimit 8000000 \ --allow-insecure-unlock \ --mine else @@ -37,13 +37,13 @@ else --unlock "0xff93B45308FD417dF303D6515aB04D9e89a750Ca","0x8e0a907331554AF72563Bd8D43051C2E64Be5d35","0x24962717f8fA5BA3b931bACaF9ac03924EB475a0","0x148FfB2074A9e59eD58142822b3eB3fcBffb0cd7","0x4CEEf6139f00F9F4535Ad19640Ff7A0137708485" \ --password ./scripts/geth/password.txt \ --ws \ - --wsport 8545 \ - --networkid 5 \ - --wsorigins="*" \ - --rpc \ - --rpcport 8545 \ - --rpccorsdomain="*" \ - --targetgaslimit 8000000 \ + --ws.port 8545 \ + --networkid 1005 \ + --ws.origins="*" \ + --http \ + --http.port 8545 \ + --http.corsdomain="*" \ + --dev.gaslimit 8000000 \ --allow-insecure-unlock \ --mine fi diff --git a/scripts/geth/start_geth2.sh b/scripts/geth/start_geth2.sh index 8705101f..92e2673f 100755 --- a/scripts/geth/start_geth2.sh +++ b/scripts/geth/start_geth2.sh @@ -9,7 +9,7 @@ set -e # Delete old chain data rm -rf $DATADIR # Init genesis -geth init ./scripts/geth/genesis.json --datadir $DATADIR +geth init ./scripts/geth/genesis2.json --datadir $DATADIR # Copy keystore rm -rf $DATADIR/keystore cp -r ./scripts/geth/keystore $DATADIR @@ -23,10 +23,13 @@ if [[ $QUIET ]]; then --unlock "0xff93B45308FD417dF303D6515aB04D9e89a750Ca","0x8e0a907331554AF72563Bd8D43051C2E64Be5d35","0x24962717f8fA5BA3b931bACaF9ac03924EB475a0","0x148FfB2074A9e59eD58142822b3eB3fcBffb0cd7","0x4CEEf6139f00F9F4535Ad19640Ff7A0137708485" \ --password ./scripts/geth/password.txt \ --ws \ - --wsport 8546 \ - --networkid 5 \ - --wsorigins="*" \ - --targetgaslimit 8000000 \ + --ws.port 7545 \ + --networkid 1004 \ + --ws.origins="*" \ + --http \ + --http.port 7545 \ + --http.corsdomain="*" \ + --dev.gaslimit 8000000 \ --allow-insecure-unlock \ --mine else @@ -36,10 +39,13 @@ else --unlock "0xff93B45308FD417dF303D6515aB04D9e89a750Ca","0x8e0a907331554AF72563Bd8D43051C2E64Be5d35","0x24962717f8fA5BA3b931bACaF9ac03924EB475a0","0x148FfB2074A9e59eD58142822b3eB3fcBffb0cd7","0x4CEEf6139f00F9F4535Ad19640Ff7A0137708485" \ --password ./scripts/geth/password.txt \ --ws \ - --wsport 8546 \ - --networkid 5 \ - --wsorigins="*" \ - --targetgaslimit 8000000 \ + --ws.port 7545 \ + --http \ + --http.port 7545 \ + --http.corsdomain="*" \ + --networkid 1004 \ + --ws.origins="*" \ + --dev.gaslimit 8000000 \ --allow-insecure-unlock \ --mine -fi \ No newline at end of file +fi diff --git a/test/contractBridge/depositERC1155.js b/test/contractBridge/depositERC1155.js index bbb55875..21ac9c90 100644 --- a/test/contractBridge/depositERC1155.js +++ b/test/contractBridge/depositERC1155.js @@ -20,7 +20,8 @@ contract('Bridge - [deposit - ERC1155]', async (accounts) => { const originChainInitialTokenAmount = 100; const depositAmount = 10; const expectedDepositNonce = 1; - + const recipeintAddress = accounts[2]; + let BridgeInstance; let OriginERC1155MintableInstance; let OriginERC1155HandlerInstance; @@ -31,19 +32,19 @@ contract('Bridge - [deposit - ERC1155]', async (accounts) => { ERC1155MintableContract.new("TOK").then(instance => OriginERC1155MintableInstance = instance), BridgeInstance = await BridgeContract.new(originDomainID, [], relayerThreshold, 0, 100) ]); - - + + resourceID = Helpers.createResourceID(OriginERC1155MintableInstance.address, originDomainID); OriginERC1155HandlerInstance = await ERC1155HandlerContract.new(BridgeInstance.address); await Promise.all([ BridgeInstance.adminSetResource(OriginERC1155HandlerInstance.address, resourceID, OriginERC1155MintableInstance.address), - OriginERC1155MintableInstance.mintBatch(depositerAddress, [originChainTokenID], [originChainInitialTokenAmount], "0x0") + OriginERC1155MintableInstance.mint(depositerAddress, originChainTokenID, originChainInitialTokenAmount, "0x0") ]); await OriginERC1155MintableInstance.setApprovalForAll(OriginERC1155HandlerInstance.address, true, { from: depositerAddress }); - depositData = Helpers.createERC1155DepositData([originChainTokenID], [depositAmount]); + depositData = Helpers.createERC1155DepositData(originChainTokenID, depositAmount, 20, recipeintAddress); }); it("[sanity] test depositerAddress' balance", async () => { diff --git a/test/e2e/erc1155/differentChainsMock.js b/test/e2e/erc1155/differentChainsMock.js index efe4db9f..ca9ea4c3 100644 --- a/test/e2e/erc1155/differentChainsMock.js +++ b/test/e2e/erc1155/differentChainsMock.js @@ -22,7 +22,7 @@ contract('E2E ERC1155 - Two EVM Chains', async accounts => { const recipientAddress = accounts[2]; const tokenID = 1; const initialTokenAmount = 100; - const depositAmount = 10; + const depositAmount = 10; const expectedDepositNonce = 1; let OriginBridgeInstance; @@ -48,12 +48,12 @@ contract('E2E ERC1155 - Two EVM Chains', async accounts => { ERC1155MintableContract.new("TOK").then(instance => OriginERC1155MintableInstance = instance), ERC1155MintableContract.new("TOK").then(instance => DestinationERC1155MintableInstance = instance) ]); - + originResourceID = Helpers.createResourceID(OriginERC1155MintableInstance.address, originDomainID); originInitialResourceIDs = [originResourceID]; originInitialContractAddresses = [OriginERC1155MintableInstance.address]; originBurnableContractAddresses = []; - + destinationResourceID = Helpers.createResourceID(DestinationERC1155MintableInstance.address, originDomainID) destinationInitialResourceIDs = [destinationResourceID]; destinationInitialContractAddresses = [DestinationERC1155MintableInstance.address]; @@ -66,7 +66,7 @@ contract('E2E ERC1155 - Two EVM Chains', async accounts => { .then(instance => DestinationERC1155HandlerInstance = instance) ]); - await OriginERC1155MintableInstance.mintBatch(depositerAddress, [tokenID], [initialTokenAmount], "0x0"); + await OriginERC1155MintableInstance.mint(depositerAddress, tokenID, initialTokenAmount, "0x0"); await Promise.all([ OriginERC1155MintableInstance.setApprovalForAll(OriginERC1155HandlerInstance.address, true, { from: depositerAddress }), @@ -75,12 +75,12 @@ contract('E2E ERC1155 - Two EVM Chains', async accounts => { DestinationBridgeInstance.adminSetResource(DestinationERC1155HandlerInstance.address, destinationResourceID, DestinationERC1155MintableInstance.address), DestinationBridgeInstance.adminSetBurnable(DestinationERC1155HandlerInstance.address, destinationBurnableContractAddresses[0]) ]); - - originDepositData = Helpers.createERC1155DepositData([tokenID], [depositAmount]); - originDepositProposalData = Helpers.createERC1155DepositProposalData([tokenID], [depositAmount], recipientAddress, "0x"); - destinationDepositData = Helpers.createERC1155DepositData([tokenID], [depositAmount]); - destinationDepositProposalData = Helpers.createERC1155DepositProposalData([tokenID], [depositAmount], depositerAddress, "0x"); + originDepositData = Helpers.createERC1155DepositData(tokenID, depositAmount, 20, recipientAddress); + originDepositProposalData = Helpers.createERC1155DepositProposalData(tokenID, depositAmount, 20, recipientAddress, "0x"); + + destinationDepositData = Helpers.createERC1155DepositData(tokenID, depositAmount, 20, recipientAddress); + destinationDepositProposalData = Helpers.createERC1155DepositProposalData(tokenID, depositAmount, 20, depositerAddress, "0x"); }); it("[sanity] depositerAddress' balance of tokenID should be equal to initialTokenAmount", async () => { @@ -174,7 +174,7 @@ contract('E2E ERC1155 - Two EVM Chains', async accounts => { recipientBalance = await DestinationERC1155MintableInstance.balanceOf(recipientAddress, tokenID); assert.strictEqual(recipientBalance.toNumber(), 0); - + depositerBalance = await OriginERC1155MintableInstance.balanceOf(depositerAddress, tokenID); assert.strictEqual(depositerBalance.toNumber(), initialTokenAmount); }); diff --git a/test/e2e/erc1155/sameChain.js b/test/e2e/erc1155/sameChain.js index 379760cd..273485dd 100644 --- a/test/e2e/erc1155/sameChain.js +++ b/test/e2e/erc1155/sameChain.js @@ -18,9 +18,9 @@ contract('E2E ERC1155 - Same Chain', async accounts => { const tokenID = 1; const initialTokenAmount = 100; - const depositAmount = 10; + const depositAmount = 10; const expectedDepositNonce = 1; - + let BridgeInstance; let ERC1155MintableInstance; let ERC1155HandlerInstance; @@ -37,7 +37,7 @@ contract('E2E ERC1155 - Same Chain', async accounts => { BridgeContract.new(domainID, [relayer1Address, relayer2Address], relayerThreshold, 0, 100).then(instance => BridgeInstance = instance), ERC1155MintableContract.new("TOK").then(instance => ERC1155MintableInstance = instance) ]); - + resourceID = Helpers.createResourceID(ERC1155MintableInstance.address, domainID); initialResourceIDs = [resourceID]; initialContractAddresses = [ERC1155MintableInstance.address]; @@ -46,14 +46,14 @@ contract('E2E ERC1155 - Same Chain', async accounts => { ERC1155HandlerInstance = await ERC1155HandlerContract.new(BridgeInstance.address); await Promise.all([ - ERC1155MintableInstance.mintBatch(depositerAddress, [tokenID], [initialTokenAmount], "0x0"), + ERC1155MintableInstance.mint(depositerAddress, tokenID, initialTokenAmount, "0x0"), BridgeInstance.adminSetResource(ERC1155HandlerInstance.address, resourceID, ERC1155MintableInstance.address) ]); await ERC1155MintableInstance.setApprovalForAll(ERC1155HandlerInstance.address, true, { from: depositerAddress }); - depositData = Helpers.createERC1155DepositData([tokenID], [depositAmount]); - proposalData = Helpers.createERC1155DepositProposalData([tokenID], [depositAmount], recipientAddress, "0x"); + depositData = Helpers.createERC1155DepositData(tokenID, depositAmount, 20, recipientAddress); + proposalData = Helpers.createERC1155DepositProposalData(tokenID, depositAmount, 20, recipientAddress, "0x"); }); it("[sanity] depositerAddress' balance should be equal to initialTokenAmount", async () => { @@ -114,12 +114,12 @@ contract('E2E ERC1155 - Same Chain', async accounts => { it("Handler's withdraw function can be called by only bridge", async () => { let withdrawData; - withdrawData = Helpers.createERC1155WithdrawData(ERC1155MintableInstance.address, depositerAddress, [tokenID], [depositAmount], "0x"); + withdrawData = Helpers.createERC1155WithdrawData(ERC1155MintableInstance.address, depositerAddress, tokenID, depositAmount, "0x"); await TruffleAssert.reverts(ERC1155HandlerInstance.withdraw(withdrawData, { from: depositerAddress }), "sender must be bridge contract"); }); - it("Should withdraw funds", async () => { + it("Should withdraw funds", async () => { let depositerBalance; let handlerBalance; let withdrawData; @@ -135,7 +135,7 @@ contract('E2E ERC1155 - Same Chain', async accounts => { handlerBalance = await ERC1155MintableInstance.balanceOf(ERC1155HandlerInstance.address, tokenID); assert.equal(handlerBalance, depositAmount); - withdrawData = Helpers.createERC1155WithdrawData(ERC1155MintableInstance.address, depositerAddress, [tokenID], [depositAmount], "0x"); + withdrawData = Helpers.createERC1155WithdrawData(ERC1155MintableInstance.address, depositerAddress, tokenID, depositAmount, "0x"); await BridgeInstance.adminWithdraw(ERC1155HandlerInstance.address, withdrawData); diff --git a/test/handlers/erc1155/deposit.js b/test/handlers/erc1155/deposit.js index 8a4d85d3..3f549218 100644 --- a/test/handlers/erc1155/deposit.js +++ b/test/handlers/erc1155/deposit.js @@ -27,14 +27,12 @@ contract('ERC1155Handler - [Deposit ERC1155]', async (accounts) => { let initialResourceIDs; let initialContractAddresses; let burnableContractAddresses; - let depositData; - beforeEach(async () => { await Promise.all([ BridgeContract.new(domainID, [], relayerThreshold, 0, 100).then(instance => BridgeInstance = instance), ERC1155MintableContract.new("TOK").then(instance => ERC1155MintableInstance = instance) ]) - + resourceID = Helpers.createResourceID(ERC1155MintableInstance.address, domainID); initialResourceIDs = [resourceID]; initialContractAddresses = [ERC1155MintableInstance.address]; @@ -42,15 +40,13 @@ contract('ERC1155Handler - [Deposit ERC1155]', async (accounts) => { await Promise.all([ ERC1155HandlerContract.new(BridgeInstance.address).then(instance => ERC1155HandlerInstance = instance), - ERC1155MintableInstance.mintBatch(depositerAddress, [tokenID], [tokenAmount], "0x0") + ERC1155MintableInstance.mint(depositerAddress, tokenID, tokenAmount, "0x0") ]); await Promise.all([ ERC1155MintableInstance.setApprovalForAll(ERC1155HandlerInstance.address, true, { from: depositerAddress }), BridgeInstance.adminSetResource(ERC1155HandlerInstance.address, resourceID, ERC1155MintableInstance.address) ]); - - depositData = Helpers.createERC1155DepositData([tokenID], [tokenAmount]); }); it('[sanity] depositer owns tokenAmount of tokenID', async () => { @@ -59,18 +55,25 @@ contract('ERC1155Handler - [Deposit ERC1155]', async (accounts) => { }); it('Deposit event is emitted with expected values', async () => { + const recipientAddress = accounts[0] + accounts[1].substr(2); + const lenRecipientAddress = 40; const depositTx = await BridgeInstance.deposit( domainID, resourceID, - depositData, - {from: depositerAddress} + Helpers.createERC1155DepositData( + tokenID, + tokenAmount, + lenRecipientAddress, + recipientAddress + ), + { from: depositerAddress } ); TruffleAssert.eventEmitted(depositTx, 'Deposit', (event) => { return event.destinationDomainID.toNumber() === domainID && event.resourceID === resourceID.toLowerCase() && event.depositNonce.toNumber() === expectedDepositNonce && - event.data === Helpers.createERC1155DepositData([tokenID], [tokenAmount]).toLowerCase() && + event.data === Helpers.createERC1155DepositData(tokenID, tokenAmount, lenRecipientAddress, recipientAddress).toLowerCase() && event.handlerResponse === null }); }); diff --git a/test/handlers/erc1155/depositBurn.js b/test/handlers/erc1155/depositBurn.js index 37824d2d..6682cdb5 100644 --- a/test/handlers/erc1155/depositBurn.js +++ b/test/handlers/erc1155/depositBurn.js @@ -2,7 +2,7 @@ * Copyright 2021 ChainSafe Systems * SPDX-License-Identifier: LGPL-3.0-only */ - + const TruffleAssert = require('truffle-assertions'); const Helpers = require('../../helpers'); @@ -27,7 +27,6 @@ contract('ERC1155Handler - [Deposit Burn ERC1155]', async (accounts) => { let resourceID1; let resourceID2; - let initialResourceIDs; let initialContractAddresses; let burnableContractAddresses; @@ -40,24 +39,22 @@ contract('ERC1155Handler - [Deposit Burn ERC1155]', async (accounts) => { resourceID1 = Helpers.createResourceID(ERC1155MintableInstance1.address, domainID); resourceID2 = Helpers.createResourceID(ERC1155MintableInstance2.address, domainID); - initialResourceIDs = [resourceID1, resourceID2]; initialContractAddresses = [ERC1155MintableInstance1.address, ERC1155MintableInstance2.address]; burnableContractAddresses = [ERC1155MintableInstance1.address] await Promise.all([ ERC1155HandlerContract.new(BridgeInstance.address).then(instance => ERC1155HandlerInstance = instance), - ERC1155MintableInstance1.mintBatch(depositerAddress, [tokenID], [tokenAmount], "0x0") + ERC1155MintableInstance1.mint(depositerAddress, tokenID, tokenAmount, "0x0") ]); - + await Promise.all([ ERC1155MintableInstance1.setApprovalForAll(ERC1155HandlerInstance.address, true, { from: depositerAddress }), BridgeInstance.adminSetResource(ERC1155HandlerInstance.address, resourceID1, ERC1155MintableInstance1.address), BridgeInstance.adminSetResource(ERC1155HandlerInstance.address, resourceID2, ERC1155MintableInstance2.address), - BridgeInstance.adminSetBurnable(ERC1155HandlerInstance.address, ERC1155MintableInstance1.address), ]); + await BridgeInstance.adminSetBurnable(ERC1155HandlerInstance.address, ERC1155MintableInstance1.address); - depositData = Helpers.createERC1155DepositData([tokenID], [tokenAmount]); - }); + }); it('[sanity] burnableContractAddresses should be marked true in _burnList', async () => { for (const burnableAddress of burnableContractAddresses) { @@ -67,10 +64,13 @@ contract('ERC1155Handler - [Deposit Burn ERC1155]', async (accounts) => { }); it('depositAmount of ERC1155MintableInstance1 tokens should have been burned', async () => { + const recipientAddress = accounts[0] + accounts[1].substr(2); + const lenRecipientAddress = 40; + await BridgeInstance.deposit( domainID, resourceID1, - depositData, + Helpers.createERC1155DepositData(tokenID, tokenAmount, lenRecipientAddress, recipientAddress), { from: depositerAddress } ); diff --git a/test/helpers.js b/test/helpers.js index a7ba9f70..7d4fd7b3 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -3,31 +3,31 @@ * SPDX-License-Identifier: LGPL-3.0-only */ - const Ethers = require('ethers'); +const Ethers = require('ethers'); - const blankFunctionSig = '0x00000000'; - const blankFunctionDepositerOffset = 0; - const AbiCoder = new Ethers.utils.AbiCoder; +const blankFunctionSig = '0x00000000'; +const blankFunctionDepositerOffset = 0; +const AbiCoder = new Ethers.utils.AbiCoder; - const toHex = (covertThis, padding) => { +const toHex = (covertThis, padding) => { return Ethers.utils.hexZeroPad(Ethers.utils.hexlify(covertThis), padding); - }; +}; - const abiEncode = (valueTypes, values) => { +const abiEncode = (valueTypes, values) => { return AbiCoder.encode(valueTypes, values) - }; +}; - const getFunctionSignature = (contractInstance, functionName) => { +const getFunctionSignature = (contractInstance, functionName) => { return contractInstance.abi.filter(abiProperty => abiProperty.name === functionName)[0].signature; - }; +}; - const createCallData = (contractInstance, functionName, valueTypes, values) => { +const createCallData = (contractInstance, functionName, valueTypes, values) => { let signature = getFunctionSignature(contractInstance, functionName); let encodedABI = abiEncode(valueTypes, values); return signature + encodedABI.substr(2); - }; +}; - const createERCDepositData = (tokenAmountOrID, lenRecipientAddress, recipientAddress) => { +const createERCDepositData = (tokenAmountOrID, lenRecipientAddress, recipientAddress) => { return '0x' + toHex(tokenAmountOrID, 32).substr(2) + // Token amount or ID to deposit (32 bytes) toHex(lenRecipientAddress, 32).substr(2) + // len(recipientAddress) (32 bytes) @@ -41,16 +41,31 @@ const createERCWithdrawData = (tokenAddress, recipientAddress, tokenAmountOrID) toHex(tokenAmountOrID, 32).substr(2); } -const createERC1155DepositData = (tokenIDs, amounts) => { - return abiEncode(["uint[]", "uint[]"], [tokenIDs, amounts]); +const createERC1155DepositData = (tokenId, amount, lenRecipientAddress, recipientAddress) => { + return '0x' + + toHex(tokenId, 32).substr(2) + // Token ID to deposit (32 bytes) + toHex(amount, 32).substr(2) + // Token amount to deposit (32 bytes) + toHex(lenRecipientAddress, 32).substr(2) + // len(recipientAddress) (32 bytes) + recipientAddress.substr(2); // recipientAddress (?? bytes) } -const createERC1155DepositProposalData = (tokenIDs, amounts, recipient, transferData) => { - return abiEncode(["uint[]", "uint[]", "bytes", "bytes"], [tokenIDs, amounts, recipient, transferData]) +const createERC1155DepositProposalData = (tokenId, amount, lenRecipientAddress, recipientAddress, lenMetaData, metaData) => { + return '0x' + + toHex(tokenId, 32).substr(2) + // Token ID to deposit (32 bytes) + toHex(amount, 32).substr(2) + // Token amount to deposit (32 bytes) + toHex(lenRecipientAddress, 32).substr(2) + // len(recipientAddress) (32 bytes) + recipientAddress.substr(2) + // recipientAddress (?? bytes) + toHex(lenMetaData, 32).substr(2) + // len(metaData) (32 bytes) + toHex(metaData, lenMetaData).substr(2) // metaData (?? bytes) + } -const createERC1155WithdrawData = (tokenAddress, recipient, tokenIDs, amounts, transferData) => { - return abiEncode(["address", "address", "uint[]", "uint[]", "bytes"], [tokenAddress, recipient, tokenIDs, amounts, transferData]) +const createERC1155WithdrawData = (tokenAddress, recipientAddress, tokenId, amount) => { + return '0x' + + toHex(tokenAddress, 32).substr(2) + + toHex(recipientAddress, 32).substr(2) + + toHex(tokenId, 32).substr(2) + + toHex(amount, 32).substr(2); } const createERC721DepositProposalData = ( @@ -74,7 +89,7 @@ const createGenericDepositData = (hexMetaData) => { if (hexMetaData === null) { return '0x' + toHex(0, 32).substr(2) // len(metaData) (32 bytes) - } + } const hexMetaDataLength = (hexMetaData.substr(2)).length / 2; return '0x' + toHex(hexMetaDataLength, 32).substr(2) + @@ -113,8 +128,8 @@ const assertObjectsMatch = (expectedObj, actualObj) => { actualValue = parseInt(actualValue); } } - - assert.deepEqual(expectedValue, actualValue, `expectedValue: ${expectedValue} does not match actualValue: ${actualValue}`); + + assert.deepEqual(expectedValue, actualValue, `expectedValue: ${expectedValue} does not match actualValue: ${actualValue}`); } }; //uint72 nonceAndID = (uint72(depositNonce) << 8) | uint72(domainID);