creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/bridge/BRC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./interfaces/IBRC20Factory.sol\";\n\ncontract BRC20 {\n    string public name;\n    string public symbol;\n    uint8 public immutable decimals;\n    address public immutable factory;\n    uint256 public totalSupply;\n    mapping(address => uint256) public balanceOf;\n    mapping(address => mapping(address => uint256)) public allowance;\n    mapping(address => uint256) public nonces;\n\n    bytes32 public DOMAIN_SEPARATOR;\n    bytes32 public constant PERMIT_TYPEHASH =\n        keccak256(\n            \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n        );\n    bytes32 public constant DOMAIN_TYPEHASH =\n        keccak256(\n            \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n        );\n\n    event Approval(\n        address indexed owner,\n        address indexed spender,\n        uint256 value\n    );\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    constructor() {\n        (name, symbol, decimals) = IBRC20Factory(msg.sender).parameters();\n\n        factory = msg.sender;\n\n        uint256 chainId;\n        assembly {\n            chainId := chainid()\n        }\n        DOMAIN_SEPARATOR = keccak256(\n            abi.encode(\n                DOMAIN_TYPEHASH,\n                keccak256(bytes(name)),\n                keccak256(bytes(\"1\")),\n                chainId,\n                address(this)\n            )\n        );\n    }\n\n    function mint(address to, uint256 amount) external {\n        require(msg.sender == factory, \"unauthorized\");\n        _mint(to, amount);\n    }\n\n    function burn(uint256 amount) external {\n        require(msg.sender == factory, \"unauthorized\");\n        _burn(msg.sender, amount);\n    }\n\n    function approve(address spender, uint256 amount) external returns (bool) {\n        allowance[msg.sender][spender] = amount;\n        emit Approval(msg.sender, spender, amount);\n        return true;\n    }\n\n    function transfer(address to, uint256 amount) external returns (bool) {\n        balanceOf[msg.sender] -= amount;\n\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(msg.sender, to, amount);\n        return true;\n    }\n\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool) {\n        uint256 allowed = allowance[from][msg.sender];\n\n        if (allowed != type(uint256).max)\n            allowance[from][msg.sender] = allowed - amount;\n\n        balanceOf[from] -= amount;\n\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n        return true;\n    }\n\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external {\n        require(deadline >= block.timestamp, \"EXPIRED\");\n        unchecked {\n            bytes32 digest = keccak256(\n                abi.encodePacked(\n                    \"\\x19\\x01\",\n                    DOMAIN_SEPARATOR,\n                    keccak256(\n                        abi.encode(\n                            PERMIT_TYPEHASH,\n                            owner,\n                            spender,\n                            value,\n                            nonces[owner]++,\n                            deadline\n                        )\n                    )\n                )\n            );\n            address recoveredAddress = ecrecover(digest, v, r, s);\n            require(\n                recoveredAddress != address(0) && recoveredAddress == owner,\n                \"INVALID_SIGNATURE\"\n            );\n            allowance[recoveredAddress][spender] = value;\n        }\n        emit Approval(owner, spender, value);\n    }\n\n    function _mint(address to, uint256 amount) internal {\n        totalSupply += amount;\n\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(address(0), to, amount);\n    }\n\n    function _burn(address from, uint256 amount) internal {\n        balanceOf[from] -= amount;\n\n        unchecked {\n            totalSupply -= amount;\n        }\n\n        emit Transfer(from, address(0), amount);\n    }\n}\n"
      },
      "contracts/bridge/interfaces/IBRC20Factory.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IBRC20Factory {\n    function parameters()\n        external\n        view\n        returns (string memory name, string memory symbol, uint8 decimals);\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}