From baec596fe102fc9aa1db96e995a952c0a9dd8a2d Mon Sep 17 00:00:00 2001 From: Bogdan Gusiev Date: Tue, 7 Dec 2021 17:41:39 +0200 Subject: [PATCH] Allow deposit from non-token owner --- contracts/root/TokenPredicates/ERC721Predicate.sol | 5 +++-- .../root/TokenPredicates/MintableERC721Predicate.sol | 5 +++-- test/predicates/ERC721Predicate.test.js | 12 ++++++++++++ test/predicates/MintableERC721Predicate.test.js | 12 ++++++++++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/contracts/root/TokenPredicates/ERC721Predicate.sol b/contracts/root/TokenPredicates/ERC721Predicate.sol index 97082e68..4badf3a5 100644 --- a/contracts/root/TokenPredicates/ERC721Predicate.sol +++ b/contracts/root/TokenPredicates/ERC721Predicate.sol @@ -77,11 +77,12 @@ contract ERC721Predicate is ITokenPredicate, AccessControlMixin, Initializable, override only(MANAGER_ROLE) { + IRootERC721 token = IRootERC721(rootToken); // deposit single if (depositData.length == 32) { uint256 tokenId = abi.decode(depositData, (uint256)); emit LockedERC721(depositor, depositReceiver, rootToken, tokenId); - IRootERC721(rootToken).safeTransferFrom(depositor, address(this), tokenId); + token.safeTransferFrom(token.ownerOf(tokenId), address(this), tokenId); // deposit batch } else { @@ -90,7 +91,7 @@ contract ERC721Predicate is ITokenPredicate, AccessControlMixin, Initializable, uint256 length = tokenIds.length; require(length <= BATCH_LIMIT, "ERC721Predicate: EXCEEDS_BATCH_LIMIT"); for (uint256 i; i < length; i++) { - IRootERC721(rootToken).safeTransferFrom(depositor, address(this), tokenIds[i]); + token.safeTransferFrom(token.ownerOf(tokenIds[i]), address(this), tokenIds[i]); } } } diff --git a/contracts/root/TokenPredicates/MintableERC721Predicate.sol b/contracts/root/TokenPredicates/MintableERC721Predicate.sol index 99a798e2..2973f3e1 100644 --- a/contracts/root/TokenPredicates/MintableERC721Predicate.sol +++ b/contracts/root/TokenPredicates/MintableERC721Predicate.sol @@ -80,6 +80,7 @@ contract MintableERC721Predicate is ITokenPredicate, AccessControlMixin, Initial override only(MANAGER_ROLE) { + IMintableERC721 token = IMintableERC721(rootToken); // Locking single ERC721 token if (depositData.length == 32) { @@ -91,7 +92,7 @@ contract MintableERC721Predicate is ITokenPredicate, AccessControlMixin, Initial // Transferring token to this address, which will be // released when attempted to be unlocked - IMintableERC721(rootToken).safeTransferFrom(depositor, address(this), tokenId); + token.safeTransferFrom(token.ownerOf(tokenId), address(this), tokenId); } else { // Locking a set a ERC721 token(s) @@ -111,7 +112,7 @@ contract MintableERC721Predicate is ITokenPredicate, AccessControlMixin, Initial // to this predicate address for (uint256 i; i < length; i++) { - IMintableERC721(rootToken).safeTransferFrom(depositor, address(this), tokenIds[i]); + token.safeTransferFrom(token.ownerOf(tokenIds[i]), address(this), tokenIds[i]); } diff --git a/test/predicates/ERC721Predicate.test.js b/test/predicates/ERC721Predicate.test.js index c5f3e761..a959ee52 100644 --- a/test/predicates/ERC721Predicate.test.js +++ b/test/predicates/ERC721Predicate.test.js @@ -24,6 +24,7 @@ contract('ERC721Predicate', (accounts) => { const tokenId = mockValues.numbers[2] const depositReceiver = mockValues.addresses[7] const depositor = accounts[1] + const depositor2 = accounts[2]; let dummyERC721 let erc721Predicate let lockTokensTx @@ -88,6 +89,17 @@ contract('ERC721Predicate', (accounts) => { const owner = await dummyERC721.ownerOf(tokenId) owner.should.equal(erc721Predicate.address) }) + + it('Should be able to receive lockTokens tx from address that does not own a token', async () => { + const depositData = abi.encode(['uint256'], [tokenId]) + lockTokensTx = await erc721Predicate.lockTokens( + depositor2, + depositReceiver, + dummyERC721.address, + depositData, + ) + should.exist(lockTokensTx) + }) }) describe('batch lockTokens', () => { diff --git a/test/predicates/MintableERC721Predicate.test.js b/test/predicates/MintableERC721Predicate.test.js index 80380fe8..dc2f307d 100644 --- a/test/predicates/MintableERC721Predicate.test.js +++ b/test/predicates/MintableERC721Predicate.test.js @@ -24,6 +24,7 @@ contract('MintableERC721Predicate', (accounts) => { const tokenId = mockValues.numbers[2] const depositReceiver = mockValues.addresses[7] const depositor = accounts[1] + const depositor2 = accounts[2]; let dummyMintableERC721 let mintableERC721Predicate let lockTokensTx @@ -98,6 +99,17 @@ contract('MintableERC721Predicate', (accounts) => { const owner = await dummyMintableERC721.ownerOf(tokenId) owner.should.equal(mintableERC721Predicate.address) }) + + it('Should be able to receive lockTokens tx from address that does not own a token', async () => { + const depositData = abi.encode(['uint256'], [tokenId]) + lockTokensTx = await mintableERC721Predicate.lockTokens( + depositor2, + depositReceiver, + dummyMintableERC721.address, + depositData, + ) + should.exist(lockTokensTx) + }) }) describe('lockTokens called by non manager', () => {