creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/core/interfaces/ISCRYERC20.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.5.0;\n\ninterface ISCRYERC20 {\n    // event Approval(address indexed owner, address indexed spender, uint value);\n    // event Transfer(address indexed from, address indexed to, uint value);\n\n    function name() external view returns (string memory);\n    function symbol() external view returns (string memory);\n    function decimals() external view returns (uint8);\n    function totalSupply() external view returns (uint);\n    function balanceOf(address owner) external view returns (uint);\n    function allowance(address owner, address spender) external view returns (uint);\n\n    function approve(address spender, uint value) external returns (bool);\n    function transfer(address to, uint value) external returns (bool);\n    function transferFrom(address from, address to, uint value) external returns (bool);\n}\n"
      },
      "contracts/core/interfaces/ISCRYERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.5.0;\n\nimport './ISCRYERC20.sol';\n\ninterface ISCRYERC20Permit is ISCRYERC20 {\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n    function PERMIT_TYPEHASH() external pure returns (bytes32);\n    function nonces(address owner) external view returns (uint);\n\n    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;\n}"
      },
      "contracts/core/interfaces/ISCRYFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.5.0;\n\ninterface ISCRYFactory {\n    event PairCreated(address indexed token0, address indexed token1, address pair, uint);\n\n    function getPair(address tokenA, address tokenB) external view returns (address pair);\n    function allPairs(uint) external view returns (address pair);\n    function allPairsLength() external view returns (uint);\n    function lpTokens(address) external view returns (bool);\n\n    function createPair(address tokenA, address tokenB) external returns (address pair, address stashTokenA, address stashTokenB);\n    function oldMajor() external view returns (address);\n    function tokenFactory() external view returns (address);\n    function stashETH() external view returns (address);\n}\n"
      },
      "contracts/core/interfaces/ISCRYPairTransferable.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.5.0;\n\ninterface ISCRYPairTransferable {\n    function transferFromPool(address to, uint value) external returns (bool);\n    // function balanceOf(address owner) external returns (uint);\n}\n"
      },
      "contracts/core/interfaces/IStashToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.5.0;\n\nimport './ISCRYERC20.sol';\nimport './ISCRYPairTransferable.sol';\n\ninterface IStashToken is ISCRYPairTransferable {\n    // needs permit\n    function underlying() external returns (ISCRYERC20);\n    function depositFor(address to, uint256 amount) external returns (bool);\n    function depositForWithPermit(address to, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external returns (bool);\n    function deposit() external returns (uint256);\n    function depositTo(address to) external returns (uint256);\n    function withdrawTo(address account, uint amount) external returns (bool);\n    function withdrawFrom(address from, address to, uint amount) external returns (bool);\n}"
      },
      "contracts/core/libraries/SafeMath.sol": {
        "content": "pragma solidity >=0.5.0;\n\n// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)\n\nlibrary SafeMath {\n    function add(uint x, uint y) internal pure returns (uint z) {\n        require((z = x + y) >= x, 'ds-math-add-overflow');\n    }\n\n    function sub(uint x, uint y) internal pure returns (uint z) {\n        require((z = x - y) <= x, 'ds-math-sub-underflow');\n    }\n\n    function mul(uint x, uint y) internal pure returns (uint z) {\n        require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');\n    }\n}\n"
      },
      "contracts/core/SLOWERC20.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity =0.6.12;\n\nimport './interfaces/ISCRYERC20Permit.sol';\nimport './interfaces/ISCRYFactory.sol';\nimport './libraries/SafeMath.sol';\n\nabstract contract SLOWERC20 is ISCRYERC20Permit {\n    using SafeMath for uint;\n\n    uint internal _totalSupply;\n    mapping(address => uint) public override balanceOf;\n    mapping(address => mapping(address => uint)) public override allowance;\n\n    bytes32 public override immutable DOMAIN_SEPARATOR;\n    // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n    bytes32 public override constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n    mapping(address => uint) public override nonces;\n\n    mapping (address => uint) internal lastReceivedBlock;\n    uint internal immutable BLOCK_HOLDING_PERIOD;\n\n    constructor(uint blockHoldingPeriod) public {\n        uint chainId;\n        assembly {\n            chainId := chainid()\n        }\n        DOMAIN_SEPARATOR = keccak256(\n            abi.encode(\n                keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),\n                keccak256(bytes(name())),\n                keccak256(bytes('1')),\n                chainId,\n                address(this)\n            )  \n        );\n        BLOCK_HOLDING_PERIOD = blockHoldingPeriod;\n    }\n\n    function name() public view override virtual returns (string memory);\n\n    function symbol() external view override virtual returns (string memory);\n\n    function decimals() external view override virtual returns (uint8) {\n        return 18;\n    }\n\n    function _mint(address to, uint value) internal virtual {\n        _totalSupply = _totalSupply.add(value);\n        balanceOf[to] = balanceOf[to].add(value);\n        // emit Transfer(address(0), to, value);\n    }\n\n    function _burn(address from, uint value) internal {\n        require(block.number.sub(lastReceivedBlock[from]) >= BLOCK_HOLDING_PERIOD, 'SLOWERC20: BLOCKED');\n\n        balanceOf[from] = balanceOf[from].sub(value);\n        _totalSupply = _totalSupply.sub(value);\n        // emit Transfer(from, address(0), value);\n    }\n\n    function _approve(address owner, address spender, uint value) private {\n        allowance[owner][spender] = value;\n        // emit Approval(owner, spender, value);\n    }\n\n    function _transfer(address from, address to, uint value) internal {\n        require(block.number.sub(lastReceivedBlock[from]) >= BLOCK_HOLDING_PERIOD, 'SLOWERC20: BLOCKED');\n        balanceOf[from] = balanceOf[from].sub(value);\n        balanceOf[to] = balanceOf[to].add(value);\n        // emit Transfer(from, to, value);\n    }\n\n    function approve(address spender, uint value) external override returns (bool) {\n        _approve(msg.sender, spender, value);\n        return true;\n    }\n\n    function transfer(address to, uint value) external override returns (bool) {\n        _transfer(msg.sender, to, value);\n        return true;\n    }\n\n    function transferFrom(address from, address to, uint value) public override returns (bool) {\n        if (allowance[from][msg.sender] != 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) {\n            allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);\n        }\n        _transfer(from, to, value);\n        return true;\n    }\n\n    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external override {\n        require(deadline >= block.timestamp, 'SLOWERC20: EXPIRED');\n        bytes32 digest = keccak256(\n            abi.encodePacked(\n                '\\x19\\x01',\n                DOMAIN_SEPARATOR,\n                keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))\n            )\n        );\n        address recoveredAddress = ecrecover(digest, v, r, s);\n        require(recoveredAddress != address(0) && recoveredAddress == owner, 'SLOWERC20: INVALID_SIGNATURE');\n        _approve(owner, spender, value);\n    }\n\n    function totalSupply() external view override virtual returns (uint) {\n        return _totalSupply;\n    }\n}\n"
      },
      "contracts/core/StashToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity =0.6.12;\n\nimport './SLOWERC20.sol';\nimport './interfaces/IStashToken.sol';\nimport './interfaces/ISCRYERC20.sol';\nimport '../solidity-lib/libraries/TransferHelper.sol';\n\ncontract StashToken is IStashToken, SLOWERC20 {\n    ISCRYERC20 public override immutable underlying;\n    address private immutable factory;\n\n    // event Deposit(address indexed dst, uint wad);\n    // event DepositTo(address indexed src, address indexed dst, uint wad);\n    // event DepositFor(address indexed src, address indexed dst, uint wad);\n    // event WithdrawalTo(address indexed src, address indexed to, uint wad);    \n    // event WithdrawalFrom(address indexed src, address indexed to, uint wad);    \n\n    constructor(address _factory, address _underlying) public SLOWERC20(5) {\n        underlying = ISCRYERC20(_underlying);\n        factory = _factory;\n    }\n\n    function name() public view virtual override returns (string memory) {\n        return 'ScurrySwap Stash Token';\n    }\n\n    function symbol() external view virtual override returns (string memory) {\n        return string(abi.encodePacked('stash-', ISCRYERC20(underlying).symbol()));\n    }\n\n    function decimals() external view override returns (uint8) {\n        return underlying.decimals();\n    }\n\n    function depositFor(address to, uint256 amount) external virtual override returns (bool) {\n        // for fee-on-transfer, need to use balanceOf\n        TransferHelper.safeTransferFrom(address(underlying), msg.sender, address(this), amount);\n        _mint(to, underlying.balanceOf(address(this)).sub(_totalSupply));\n        // emit DepositFor(msg.sender, to, amount);\n\n        return true;\n    }\n\n    function depositForWithPermit(address to, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external override returns (bool) {\n        ISCRYERC20Permit(address(underlying))\n          .permit(msg.sender, address(this), amount, deadline, v, r, s);\n        TransferHelper.safeTransferFrom(address(underlying), msg.sender, address(this), amount);\n        _mint(to, underlying.balanceOf(address(this)).sub(_totalSupply));\n        // emit DepositFor(msg.sender, to, amount);\n\n        return true;\n    }\n\n    function deposit() external virtual override returns (uint256) {\n        uint256 value = underlying.balanceOf(address(this)).sub(_totalSupply);\n        _mint(msg.sender, value);\n        // emit Deposit(msg.sender, value);\n\n        return value;\n    }\n\n    function depositTo(address to) external virtual override returns (uint256) {\n        uint256 value = underlying.balanceOf(address(this)).sub(_totalSupply);\n        _mint(to, value);\n        // emit DepositTo(msg.sender, to, value);\n\n        return value;\n    }\n\n    // adds hold time if transferring from pool unless `to` is another pair token\n    function transferFromPool(address to, uint256 value) external override returns (bool) {\n        require(ISCRYFactory(factory).lpTokens(msg.sender), 'StashToken: FORBIDDEN');\n        _transfer(msg.sender, to, value);\n        if (!ISCRYFactory(factory).lpTokens(to) ) {\n            lastReceivedBlock[to] = block.number;\n        }\n        return true;\n    }\n\n    function withdrawTo(address account, uint amount) external virtual override returns (bool) {\n        _burn(msg.sender, amount);\n        TransferHelper.safeTransfer(address(underlying), account, amount);\n        // emit WithdrawalTo(msg.sender, account, amount);\n        return true;\n    }\n\n    function withdrawFrom(address from, address to, uint amount) external virtual override returns (bool) {\n        address sender = msg.sender;\n        if (allowance[from][sender] != 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) {\n            allowance[from][sender] = allowance[from][sender].sub(amount);\n        }\n        _burn(from, amount);\n        TransferHelper.safeTransfer(address(underlying), to, amount);\n        // emit WithdrawalFrom(from, to, amount);\n\n        return true;\n    }\n}\n"
      },
      "contracts/solidity-lib/libraries/TransferHelper.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity >=0.6.0;\n\n// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false\nlibrary TransferHelper {\n    function safeApprove(\n        address token,\n        address to,\n        uint256 value\n    ) internal {\n        // bytes4(keccak256(bytes('approve(address,uint256)')));\n        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));\n        require(\n            success && (data.length == 0 || abi.decode(data, (bool))),\n            'TransferHelper::safeApprove: approve failed'\n        );\n    }\n\n    function safeTransfer(\n        address token,\n        address to,\n        uint256 value\n    ) internal {\n        // bytes4(keccak256(bytes('transfer(address,uint256)')));\n        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));\n        require(\n            success && (data.length == 0 || abi.decode(data, (bool))),\n            'TransferHelper::safeTransfer: transfer failed'\n        );\n    }\n\n    function safeTransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));\n        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));\n        require(\n            success && (data.length == 0 || abi.decode(data, (bool))),\n            'TransferHelper::transferFrom: transferFrom failed'\n        );\n    }\n\n    function safeTransferETH(address to, uint256 value) internal {\n        (bool success, ) = to.call{value: value}(new bytes(0));\n        require(success, 'TransferHelper::safeTransferETH: ETH transfer failed');\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 999999
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}