Skip to content

Commit

Permalink
Merge pull request #76 from maticnetwork/mintable_erc_1155_predicate_…
Browse files Browse the repository at this point in the history
…single_withdraw

Fix `TransferSingle` of MintableERC1155
  • Loading branch information
itzmeanjan authored Apr 26, 2021
2 parents 24dd3d8 + efbb1ae commit b0ad377
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 23 deletions.
28 changes: 27 additions & 1 deletion contracts/root/TokenPredicates/MintableERC1155Predicate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,24 @@ contract MintableERC1155Predicate is
data
);
}

// Used when attempting to exit with single token, single amount/ id is converted into
// slice of amounts/ ids
// Generally size is going to be `1` i.e. single element array, but it's kept generic
function makeArrayWithValue(uint256 val, uint size) internal pure returns(uint256[] memory) {
require(
size > 0,
"MintableERC1155Predicate: Invalid resulting array length"
);

uint256[] memory vals = new uint256[](size);

for (uint256 i = 0; i < size; i++) {
vals[i] = val;
}

return vals;
}

/**
* @notice Creates an array of `size` by repeating provided address,
Expand Down Expand Up @@ -206,7 +224,15 @@ contract MintableERC1155Predicate is
// it'll mint those tokens for this contract and return
// safely transfer those to withdrawer
if (tokenBalance < amount) {
token.mint(address(this), id, amount - tokenBalance, bytes(""));
// @notice We could have done `mint`, but that would require
// us implementing `onERC1155Received`, which we avoid intentionally
// for sake of only supporting batch deposit.
//
// Which is why this transfer is wrapped as single element batch minting
token.mintBatch(address(this),
makeArrayWithValue(id, 1),
makeArrayWithValue(amount - tokenBalance, 1),
bytes(""));
}

token.safeTransferFrom(
Expand Down
23 changes: 22 additions & 1 deletion flat/MintableERC1155Predicate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1378,6 +1378,24 @@ contract MintableERC1155Predicate is
data
);
}

// Used when attempting to exit with single token, single amount/ id is converted into
// slice of amounts/ ids
// Generally size is going to be `1` i.e. single element array, but it's kept generic
function makeArrayWithValue(uint256 val, uint size) internal pure returns(uint256[] memory) {
require(
size > 0,
"MintableERC1155Predicate: Invalid resulting array length"
);

uint256[] memory vals = new uint256[](size);

for (uint256 i = 0; i < size; i++) {
vals[i] = val;
}

return vals;
}

/**
* @notice Creates an array of `size` by repeating provided address,
Expand Down Expand Up @@ -1479,7 +1497,10 @@ contract MintableERC1155Predicate is
// it'll mint those tokens for this contract and return
// safely transfer those to withdrawer
if (tokenBalance < amount) {
token.mint(address(this), id, amount - tokenBalance, bytes(""));
token.mintBatch(address(this),
makeArrayWithValue(id, 1),
makeArrayWithValue(amount - tokenBalance, 1),
bytes(""));
}

token.safeTransferFrom(
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@maticnetwork/pos-portal",
"version": "1.5.1",
"version": "1.5.2",
"description": "Contracts to facilitate transfer of assets between Ethereum Main Network and Matic Network, using security of Matic POS layer",
"main": "index.js",
"scripts": {
Expand Down
41 changes: 21 additions & 20 deletions test/predicates/MintableERC1155Predicate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,13 @@ contract('MintableERC1155Predicate', (accounts) => {
const PREDICATE_ROLE = await dummyMintableERC1155.PREDICATE_ROLE()
await dummyMintableERC1155.grantRole(PREDICATE_ROLE, mintableERC1155Predicate.address)

const burnLog = getERC1155TransferBatchLog({
// Force predicate to `mint`
const burnLog = getERC1155TransferSingleLog({
operator: depositor,
from: depositor,
to: mockValues.zeroAddress,
tokenIds: [tokenId],
amounts: [amount]
tokenId,
amount
})

await mintableERC1155Predicate.exitTokens(depositor, dummyMintableERC1155.address, burnLog)
Expand Down Expand Up @@ -262,10 +263,10 @@ contract('MintableERC1155Predicate', (accounts) => {
describe('exitTokens batch', () => {
const amountA = mockValues.amounts[9]
const amountB = mockValues.amounts[8]

const tokenIdA = mockValues.numbers[4]
const tokenIdB = mockValues.numbers[5]

const depositData = constructERC1155DepositData([tokenIdA, tokenIdB], [amountA, amountB])
const depositor = accounts[1]
const withdrawer = mockValues.addresses[8]
Expand Down Expand Up @@ -298,7 +299,7 @@ contract('MintableERC1155Predicate', (accounts) => {
await dummyMintableERC1155.setApprovalForAll(mintableERC1155Predicate.address, true, { from: depositor })

await mintableERC1155Predicate.lockTokens(depositor, mockValues.addresses[2], dummyMintableERC1155.address, depositData)

oldAccountBalanceA = await dummyMintableERC1155.balanceOf(withdrawer, tokenIdA)
oldAccountBalanceB = await dummyMintableERC1155.balanceOf(withdrawer, tokenIdB)

Expand Down Expand Up @@ -355,10 +356,10 @@ contract('MintableERC1155Predicate', (accounts) => {
describe('exitTokens called by different user', () => {
const amountA = mockValues.amounts[9]
const amountB = mockValues.amounts[8]

const tokenIdA = mockValues.numbers[4]
const tokenIdB = mockValues.numbers[5]

const depositData = constructERC1155DepositData([tokenIdA, tokenIdB], [amountA, amountB])
const depositor = accounts[1]
const withdrawer = mockValues.addresses[8]
Expand Down Expand Up @@ -392,7 +393,7 @@ contract('MintableERC1155Predicate', (accounts) => {
await dummyMintableERC1155.setApprovalForAll(mintableERC1155Predicate.address, true, { from: depositor })

await mintableERC1155Predicate.lockTokens(depositor, mockValues.addresses[2], dummyMintableERC1155.address, depositData)

oldAccountBalanceA = await dummyMintableERC1155.balanceOf(withdrawer, tokenIdA)
oldAccountBalanceB = await dummyMintableERC1155.balanceOf(withdrawer, tokenIdB)

Expand Down Expand Up @@ -447,7 +448,7 @@ contract('MintableERC1155Predicate', (accounts) => {
const depositData = constructERC1155DepositData([tokenId], [amount])
const depositor = accounts[1]
const withdrawer = mockValues.addresses[8]

let dummyMintableERC1155
let mintableERC1155Predicate

Expand All @@ -459,12 +460,12 @@ contract('MintableERC1155Predicate', (accounts) => {
const PREDICATE_ROLE = await dummyMintableERC1155.PREDICATE_ROLE()
await dummyMintableERC1155.grantRole(PREDICATE_ROLE, mintableERC1155Predicate.address)

const burnLog = getERC1155TransferBatchLog({
const burnLog = getERC1155TransferSingleLog({
operator: depositor,
from: depositor,
to: mockValues.zeroAddress,
tokenIds: [tokenId],
amounts: [amount]
tokenId,
amount
})

await mintableERC1155Predicate.exitTokens(depositor, dummyMintableERC1155.address, burnLog)
Expand All @@ -479,8 +480,8 @@ contract('MintableERC1155Predicate', (accounts) => {
operator: withdrawer,
from: withdrawer,
to: mockValues.zeroAddress,
tokenId: tokenId,
amount: amount
tokenId,
amount
})
await expectRevert(mintableERC1155Predicate.exitTokens(withdrawer, dummyMintableERC1155.address, burnLog), 'MintableERC1155Predicate: INVALID_WITHDRAW_SIG')
})
Expand Down Expand Up @@ -548,12 +549,12 @@ contract('MintableERC1155Predicate', (accounts) => {
const PREDICATE_ROLE = await dummyMintableERC1155.PREDICATE_ROLE()
await dummyMintableERC1155.grantRole(PREDICATE_ROLE, mintableERC1155Predicate.address)

const burnLog = getERC1155TransferBatchLog({
const burnLog = getERC1155TransferSingleLog({
operator: depositor,
from: depositor,
to: mockValues.zeroAddress,
tokenIds: [tokenId],
amounts: [amount]
tokenId,
amount
})

await mintableERC1155Predicate.exitTokens(depositor, dummyMintableERC1155.address, burnLog)
Expand All @@ -567,8 +568,8 @@ contract('MintableERC1155Predicate', (accounts) => {
operator: withdrawer,
from: withdrawer,
to: mockValues.zeroAddress,
tokenId: tokenId,
amount: amount
tokenId,
amount
})
await expectRevert(
mintableERC1155Predicate.exitTokens(withdrawer, dummyMintableERC1155.address, burnLog, { from: accounts[2] }),
Expand Down

0 comments on commit b0ad377

Please sign in to comment.