// Contract: Factory
// Target function: function create(
// SPDX-License-Identifier: None
pragma solidity ^0.8.14;

// @openzepplin/contracts/utils/Strings
// License: MIT
library Utils {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;
    
    function toString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

// @openzepplin/contracts/token/ERC20/IERC20
// License: MIT
interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 amount) external returns (bool);
}

/**
* @title Squid Contract Factory.
* @author Dream Kollab.
* @notice You can use this factory to create and interface with squids.
* @dev All function calls are currently implemented without side effects.
* @custom:developer Etienne Cellier-Clarke.
*/
contract Factory {

    address payable private owner;
    address private manager;

    uint public creation_fee;
    uint public transaction_fee;
    uint public id_counter;

    mapping(uint => Squid) private squids;
    mapping(address => uint) private squid_ids;
    mapping(address => uint[]) private asoc_squids;
    mapping(address => uint[]) private created_squids;

    modifier onlyOwner {
        require(msg.sender == owner, "Error: 1000");
        _;
    }

    modifier onlyManagement {
        require(msg.sender == owner || msg.sender == manager, "Error: 1000");
        _;
    }

    fallback() external payable {}

    constructor() {
        owner = payable(msg.sender);
        manager = msg.sender;
        creation_fee = 10000000000000000; // Wei
        transaction_fee = 1000000; // Fraction of 100000000
        id_counter = 5457;
    }