Skip to content

Commit

Permalink
Merge pull request #71 from gnosis/batch-mint
Browse files Browse the repository at this point in the history
Batch mint/burn conditional tokens when splitting/merging
  • Loading branch information
cag committed Aug 28, 2019
2 parents 9a174be + f282ab2 commit 75adb59
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 12 deletions.
32 changes: 20 additions & 12 deletions contracts/ConditionalTokens.sol
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,15 @@ contract ConditionalTokens is ERC1155 {
// freeIndexSet starts as the full collection
uint freeIndexSet = fullIndexSet;
// This loop checks that all condition sets are disjoint (the same outcome is not part of more than 1 set)
uint[] memory positionIds = new uint[](partition.length);
uint[] memory amounts = new uint[](partition.length);
for (uint i = 0; i < partition.length; i++) {
uint indexSet = partition[i];
require(indexSet > 0 && indexSet < fullIndexSet, "got invalid index set");
require((indexSet & freeIndexSet) == indexSet, "partition not disjoint");
freeIndexSet ^= indexSet;
_mint(
msg.sender,
// position ID is the ERC 1155 token ID
getPositionId(collateralToken, getCollectionId(parentCollectionId, conditionId, indexSet)),
amount,
""
);
positionIds[i] = getPositionId(collateralToken, getCollectionId(parentCollectionId, conditionId, indexSet));
amounts[i] = amount;
}

if (freeIndexSet == 0) {
Expand All @@ -155,6 +152,13 @@ contract ConditionalTokens is ERC1155 {
);
}

_batchMint(
msg.sender,
// position ID is the ERC 1155 token ID
positionIds,
amounts,
""
);
emit PositionSplit(msg.sender, collateralToken, parentCollectionId, conditionId, partition, amount);
}

Expand All @@ -171,17 +175,21 @@ contract ConditionalTokens is ERC1155 {

uint fullIndexSet = (1 << outcomeSlotCount) - 1;
uint freeIndexSet = fullIndexSet;
uint[] memory positionIds = new uint[](partition.length);
uint[] memory amounts = new uint[](partition.length);
for (uint i = 0; i < partition.length; i++) {
uint indexSet = partition[i];
require(indexSet > 0 && indexSet < fullIndexSet, "got invalid index set");
require((indexSet & freeIndexSet) == indexSet, "partition not disjoint");
freeIndexSet ^= indexSet;
_burn(
msg.sender,
getPositionId(collateralToken, getCollectionId(parentCollectionId, conditionId, indexSet)),
amount
);
positionIds[i] = getPositionId(collateralToken, getCollectionId(parentCollectionId, conditionId, indexSet));
amounts[i] = amount;
}
_batchBurn(
msg.sender,
positionIds,
amounts
);

if (freeIndexSet == 0) {
if (parentCollectionId == bytes32(0)) {
Expand Down
36 changes: 36 additions & 0 deletions contracts/ERC1155/ERC1155.sol
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,26 @@ contract ERC1155 is ERC165, IERC1155
_doSafeTransferAcceptanceCheck(msg.sender, address(0), to, id, value, data);
}

/**
* @dev Internal function to batch mint amounts of tokens with the given IDs
* @param to The address that will own the minted token
* @param ids IDs of the tokens to be minted
* @param values Amounts of the tokens to be minted
* @param data Data forwarded to `onERC1155Received` if `to` is a contract receiver
*/
function _batchMint(address to, uint256[] memory ids, uint256[] memory values, bytes memory data) internal {
require(to != address(0), "ERC1155: batch mint to the zero address");
require(ids.length == values.length, "ERC1155: IDs and values must have same lengths");

for(uint i = 0; i < ids.length; i++) {
_balances[ids[i]][to] = values[i].add(_balances[ids[i]][to]);
}

emit TransferBatch(msg.sender, address(0), to, ids, values);

_doSafeBatchTransferAcceptanceCheck(msg.sender, address(0), to, ids, values, data);
}

/**
* @dev Internal function to burn an amount of a token with the given ID
* @param owner Account which owns the token to be burnt
Expand All @@ -195,6 +215,22 @@ contract ERC1155 is ERC165, IERC1155
emit TransferSingle(msg.sender, owner, address(0), id, value);
}

/**
* @dev Internal function to batch burn an amounts of tokens with the given IDs
* @param owner Account which owns the token to be burnt
* @param ids IDs of the tokens to be burnt
* @param values Amounts of the tokens to be burnt
*/
function _batchBurn(address owner, uint256[] memory ids, uint256[] memory values) internal {
require(ids.length == values.length, "ERC1155: IDs and values must have same lengths");

for(uint i = 0; i < ids.length; i++) {
_balances[ids[i]][owner] = _balances[ids[i]][owner].sub(values[i]);
}

emit TransferBatch(msg.sender, owner, address(0), ids, values);
}

function _doSafeTransferAcceptanceCheck(
address operator,
address from,
Expand Down

0 comments on commit 75adb59

Please sign in to comment.