diff --git a/proxy/contracts/schain/TokenManagers/TokenManagerERC721.sol b/proxy/contracts/schain/TokenManagers/TokenManagerERC721.sol index 34c6fe4ee..9021bbb74 100644 --- a/proxy/contracts/schain/TokenManagers/TokenManagerERC721.sol +++ b/proxy/contracts/schain/TokenManagers/TokenManagerERC721.sol @@ -328,7 +328,11 @@ contract TokenManagerERC721 is TokenManager, ITokenManagerERC721 { isMainChainToken = true; } require(address(contractOnSchain).isContract(), "No token clone on schain"); - require(contractOnSchain.getApproved(tokenId) == address(this), "Not allowed ERC721 Token"); + require( + contractOnSchain.getApproved(tokenId) == address(this) || + contractOnSchain.isApprovedForAll(msg.sender, address(this)), + "Not allowed ERC721 Token" + ); bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId); if (isMainChainToken) { require(chainHash != MAINNET_HASH, "Main chain token could not be transfered to Mainnet"); diff --git a/proxy/contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol b/proxy/contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol index 51807eeef..b8cb15c50 100644 --- a/proxy/contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol +++ b/proxy/contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol @@ -144,7 +144,11 @@ contract TokenManagerERC721WithMetadata is TokenManagerERC721 { isMainChainToken = true; } require(address(contractOnSchain).isContract(), "No token clone on schain"); - require(contractOnSchain.getApproved(tokenId) == address(this), "Not allowed ERC721 Token"); + require( + contractOnSchain.getApproved(tokenId) == address(this) || + contractOnSchain.isApprovedForAll(msg.sender, address(this)), + "Not allowed ERC721 Token" + ); bytes memory data = Messages.encodeTransferErc721MessageWithMetadata( contractOnMainChain, to, diff --git a/proxy/test/TokenManagerERC721.ts b/proxy/test/TokenManagerERC721.ts index 9072679a9..916107422 100644 --- a/proxy/test/TokenManagerERC721.ts +++ b/proxy/test/TokenManagerERC721.ts @@ -166,6 +166,24 @@ describe("TokenManagerERC721", () => { outgoingMessagesCounterMainnet.should.be.deep.equal(BigNumber.from(1)); }); + it("should send token if TokenManager was approved for all transfers by user", async () => { + await tokenManagerERC721.connect(schainOwner).addERC721TokenByOwner(mainnetName, token.address, tokenClone.address); + await tokenClone.connect(deployer).mint(user.address, tokenId); + await messageProxyForSchain.registerExtraContract("Mainnet", tokenManagerERC721.address); + + await tokenManagerERC721.connect(user).exitToMainERC721(token.address, tokenId) + .should.be.eventually.rejectedWith("Not allowed ERC721 Token"); + + await tokenClone.connect(user).setApprovalForAll(tokenManagerERC721.address, true); + + await tokenManagerERC721.connect(user).exitToMainERC721(token.address, tokenId); + + const outgoingMessagesCounterMainnet = BigNumber.from( + await messageProxyForSchain.getOutgoingMessagesCounter("Mainnet") + ); + outgoingMessagesCounterMainnet.should.be.deep.equal(BigNumber.from(1)); + }); + it("should be rejected when call exitToMainERC721 if remove contract for all chains", async () => { await tokenManagerERC721.connect(schainOwner).addERC721TokenByOwner(mainnetName, token.address, tokenClone.address); await tokenClone.connect(deployer).mint(user.address, tokenId); diff --git a/proxy/test/TokenManagerERC721WithMetadata.ts b/proxy/test/TokenManagerERC721WithMetadata.ts index b85757697..2186bac4b 100644 --- a/proxy/test/TokenManagerERC721WithMetadata.ts +++ b/proxy/test/TokenManagerERC721WithMetadata.ts @@ -169,6 +169,24 @@ describe("TokenManagerERC721WithMetadata", () => { outgoingMessagesCounterMainnet.should.be.deep.equal(BigNumber.from(1)); }); + it("should send token if TokenManager was approved for all transfers by user", async () => { + await tokenManagerERC721WithMetadata.connect(schainOwner).addERC721TokenByOwner(mainnetName, token.address, tokenClone.address); + await tokenClone.connect(deployer).mint(user.address, tokenId); + await messageProxyForSchain.registerExtraContract("Mainnet", tokenManagerERC721WithMetadata.address); + + await tokenManagerERC721WithMetadata.connect(user).exitToMainERC721(token.address, tokenId) + .should.be.eventually.rejectedWith("Not allowed ERC721 Token"); + + await tokenClone.connect(user).setApprovalForAll(tokenManagerERC721WithMetadata.address, true); + + await tokenManagerERC721WithMetadata.connect(user).exitToMainERC721(token.address, tokenId); + + const outgoingMessagesCounterMainnet = BigNumber.from( + await messageProxyForSchain.getOutgoingMessagesCounter("Mainnet") + ); + outgoingMessagesCounterMainnet.should.be.deep.equal(BigNumber.from(1)); + }); + it("should be rejected when call exitToMainERC721 if remove contract for all chains", async () => { await tokenManagerERC721WithMetadata.connect(schainOwner).addERC721TokenByOwner(mainnetName, token.address, tokenClone.address); await tokenClone.connect(deployer).mint(user.address, tokenId);