contract UnbuttonTokenFactory is InstanceRegistry, IFactory {
    using SafeERC20 for IERC20;

    address public immutable template;

    constructor(address _template) {
        template = _template;
    }

    /// @dev Create and initialize an instance of the unbutton token
    function create(bytes calldata args) external override returns (address) {
        // Parse params
        address underlying;
        string memory name;
        string memory symbol;
        uint256 initialRate;
        (underlying, name, symbol, initialRate) = abi.decode(
            args,
            (address, string, string, uint256)
        );

        // Create instance
        address unbuttonToken = Clones.clone(template);

        // Approve transfer of initial deposit to instance
        uint256 inititalDeposit = IUnbuttonToken(unbuttonToken).INITIAL_DEPOSIT();
        IERC20(underlying).safeTransferFrom(msg.sender, address(this), inititalDeposit);
        IERC20(underlying).approve(unbuttonToken, inititalDeposit);

        // Initialize instance
        IUnbuttonToken(unbuttonToken).initialize(underlying, name, symbol, initialRate);

        // Register instance
        InstanceRegistry._register(address(unbuttonToken));

        // Return instance
        return unbuttonToken;
    }
}
/**
 * @title The UnbuttonToken Factory
 *
 * @dev Creates clones of the target UnbuttonToken template
 *
 */
function create(bytes calldata args) external override returns (address) {
        // Parse params
        address underlying;
        string memory name;
        string memory symbol;
        uint256 initialRate;
        (underlying, name, symbol, initialRate) = abi.decode(
            args,
            (address, string, string, uint256)
        );

        // Create instance
        address unbuttonToken = Clones.clone(template);

        // Approve transfer of initial deposit to instance
        uint256 inititalDeposit = IUnbuttonToken(unbuttonToken).INITIAL_DEPOSIT();
        IERC20(underlying).safeTransferFrom(msg.sender, address(this), inititalDeposit);
        IERC20(underlying).approve(unbuttonToken, inititalDeposit);

        // Initialize instance
        IUnbuttonToken(unbuttonToken).initialize(underlying, name, symbol, initialRate);

        // Register instance
        InstanceRegistry._register(address(unbuttonToken));

        // Return instance
        return unbuttonToken;
    }
/// @dev Create and initialize an instance of the unbutton token