Skip to content

Commit

Permalink
Basic Crafting Factory pattern.
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Connolly authored and Alex Connolly committed Jan 12, 2024
1 parent fbf321c commit 372df8b
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
51 changes: 51 additions & 0 deletions contracts/crafting/Factory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright Immutable Pty Ltd 2018 - 2023
// SPDX-License-Identifier: Apache 2.0
pragma solidity 0.8.19;

import { IRecipe, ERC1155Input, ERC721Input, ERC20Input, ERC1155Asset } from "./IRecipe.sol";

Check failure on line 5 in contracts/crafting/Factory.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Replace ·IRecipe,·ERC1155Input,·ERC721Input,·ERC20Input,·ERC1155Asset· with IRecipe,·ERC1155Input,·ERC721Input,·ERC20Input,·ERC1155Asset

contract Factory {

Check failure on line 7 in contracts/crafting/Factory.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Delete ⏎

uint256 public craftCounter;

event CraftComplete(uint256 indexed craftID, IRecipe indexed recipe);

function craft(
IRecipe recipe,
ERC20Input[] calldata erc20Inputs,
ERC721Input[] calldata erc721Inputs,
ERC1155Input[] calldata erc1155Inputs,
bytes calldata data
) external {

Check failure on line 19 in contracts/crafting/Factory.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Delete ⏎

uint craftID = craftCounter++;

Check warning on line 21 in contracts/crafting/Factory.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Rule is set with explicit type [var/s: uint]

recipe.beforeTransfers(craftID, erc20Inputs, erc721Inputs, erc1155Inputs, data);

for (uint i = 0; i < erc20Inputs.length; i++) {

Check warning on line 25 in contracts/crafting/Factory.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Rule is set with explicit type [var/s: uint]
ERC20Input memory input = erc20Inputs[i];
input.erc20.transferFrom(msg.sender, input.destination, input.amount);
}


Check failure on line 30 in contracts/crafting/Factory.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Delete ⏎
for (uint i = 0; i < erc721Inputs.length; i++) {

Check warning on line 31 in contracts/crafting/Factory.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Rule is set with explicit type [var/s: uint]
ERC721Input memory input = erc721Inputs[i];
for (uint j = 0; j < input.tokenIDs.length; j++) {

Check warning on line 33 in contracts/crafting/Factory.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Rule is set with explicit type [var/s: uint]
input.erc721.safeTransferFrom(msg.sender, input.destination, input.tokenIDs[j]);
}
}

for (uint i = 0; i < erc1155Inputs.length; i++) {
ERC1155Input memory input = erc1155Inputs[i];
for (uint j = 0; j < input.assets.length; j++) {
ERC1155Asset memory asset = input.assets[j];
input.erc1155.safeTransferFrom(msg.sender, input.destination, asset.tokenID, asset.amount, "0x0");
}
}

recipe.afterTransfers(craftID, data);

Check failure on line 47 in contracts/crafting/Factory.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Delete ········
emit CraftComplete(craftID, recipe);
}

Check failure on line 50 in contracts/crafting/Factory.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Replace ⏎} with }⏎
}
45 changes: 45 additions & 0 deletions contracts/crafting/IRecipe.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright Immutable Pty Ltd 2018 - 2023
// SPDX-License-Identifier: Apache 2.0
pragma solidity 0.8.19;

import { IERC1155 } from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";

Check failure on line 5 in contracts/crafting/IRecipe.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Replace ·IERC1155· with IERC1155
import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";

Check failure on line 6 in contracts/crafting/IRecipe.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Replace ·IERC721· with IERC721
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

Check failure on line 7 in contracts/crafting/IRecipe.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Replace ·IERC20·}·from·"@openzeppelin/contracts/token/ERC20/IERC20.sol";⏎ with IERC20}·from·"@openzeppelin/contracts/token/ERC20/IERC20.sol";


struct ERC1155Asset {
uint256 tokenID;
uint256 amount;
}

struct ERC1155Input {
IERC1155 erc1155;
ERC1155Asset[] assets;
address destination;
}

struct ERC721Input {
IERC721 erc721;
uint256[] tokenIDs;
address destination;
}

struct ERC20Input {
IERC20 erc20;
uint256 amount;
address destination;
}

interface IRecipe {

Check failure on line 34 in contracts/crafting/IRecipe.sol

View workflow job for this annotation

GitHub Actions / Run eslint

Delete ⏎
function beforeTransfers(
uint256 craftID,
ERC20Input[] calldata erc20s,
ERC721Input[] calldata erc721s,
ERC1155Input[] calldata erc1155s,
bytes calldata data
) external;

function afterTransfers(uint256 craftID, bytes calldata data) external;

}
51 changes: 51 additions & 0 deletions contracts/crafting/examples/SimpleRecipe.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright Immutable Pty Ltd 2018 - 2023
// SPDX-License-Identifier: Apache 2.0
pragma solidity 0.8.19;

import { IRecipe, ERC20Input, ERC721Input, ERC1155Input } from "../IRecipe.sol";
import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";

contract SimpleRecipe is IRecipe {

IERC721 public token;
address private factory;

constructor(IERC721 _token, address _factory) {
token = _token;
factory = _factory;
}

modifier onlyFactory {
require(msg.sender == factory, "Caller must be Factory");
_;
}

function beforeTransfers(
uint256,
ERC20Input[] calldata erc20s,
ERC721Input[] calldata erc721s,
ERC1155Input[] calldata erc1155s,
bytes calldata
) external view onlyFactory {

require(erc20s.length == 0, "No ERC20s allowed.");
require(erc1155s.length == 0, "No ERC1155s allowed.");
require(erc721s.length == 1, "Must be only one ERC721 input.");

ERC721Input memory input = erc721s[0];
require(input.erc721 == token, "Must be crafting game assets.");
require(input.destination == address(0), "Only allowed destination is 0x0.");

// No need to check that the 5 assets are unique as transferring them will fail in the Factory.

// Can log any events you want
}

function afterTransfers(uint256 craftID, bytes calldata data) external onlyFactory {
// mint a new NFT to the user
// token.mint() etc.

// Can log any events you want
}

}

0 comments on commit 372df8b

Please sign in to comment.