creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/escrows/DAIEscrow.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\nimport \"src/interfaces/IERC20.sol\";\n\n// @dev Caution: We assume all failed transfers cause reverts and ignore the returned bool.\ninterface IDSR {\n    function daiBalance(address usr) external returns (uint wad);\n    function pieOf(address usr) external view returns (uint wad);\n    function join(address dst, uint wad) external;\n    function exit(address dst, uint wad) external;\n    function exitAll(address dst) external;\n    function pot() external view returns (address);\n}\n\ninterface IPot {\n    function chi() external view returns (uint);\n    function drip() external;\n    function pie(address) external view returns (uint slice);\n}\n\n/**\n * @title DAI Escrow\n * @notice Collateral is stored in unique escrow contracts for every user and every market.\n * This escrow allows user to deposit DAI collateral directly into the DSR contract, earning DAI yyield\n * @dev Caution: This is a proxy implementation. Follow proxy pattern best practices\n */\ncontract DAIEscrow {\n\n    address public market;\n    IERC20 public constant token = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);\n    IDSR public constant DSR_MANAGER = IDSR(0x373238337Bfe1146fb49989fc222523f83081dDb);\n    IPot public constant POT = IPot(0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7);\n\n    /**\n     * @notice Initialize escrow with a token\n     * @dev Must be called right after proxy is created. Unecessary to set both token and beneficiary, as escrow only works with DAI\n     */\n    function initialize(IERC20, address) public {\n        require(market == address(0), \"ALREADY INITIALIZED\");\n        market = msg.sender;\n        token.approve(address(DSR_MANAGER), type(uint).max);\n    }\n    \n    /**\n     * @notice Transfers the associated ERC20 token to a recipient.\n     * @param recipient The address to receive payment from the escrow\n     * @param amount The amount of ERC20 token to be transferred.\n     */\n    function pay(address recipient, uint amount) public {\n        require(msg.sender == market, \"ONLY MARKET\");\n        if(balance() == amount){\n            //If trying to pay full balance, use exitAll to avoid dust being left over\n            DSR_MANAGER.exitAll(recipient);\n        } else {\n            DSR_MANAGER.exit(recipient, amount);\n        }\n    }\n\n    /**\n    * @notice Get the token balance of the escrow\n    * @return The balance accrued in the DSR up until the last `drip` function call\n    */\n    function balance() public view returns (uint) {\n        return rmul(POT.chi(), DSR_MANAGER.pieOf(address(this)));\n    }\n    \n    /**\n     * @notice Function called by market on deposit. Will deposit DAI into the DSR\n     * @dev This function should remain callable by anyone to handle direct inbound transfers.\n     */\n    function onDeposit() public {\n        uint daiBalance = token.balanceOf(address(this));\n        if(daiBalance > 0) {\n            DSR_MANAGER.join(address(this), daiBalance);\n        }\n    }\n\n    function rmul(uint x, uint y) internal pure returns(uint){\n        uint256 RAY = 10 ** 27;\n        // always rounds down\n        return x * y / RAY;\n    }\n}\n"
      },
      "src/interfaces/IERC20.sol": {
        "content": "pragma solidity ^0.8.13;\n\ninterface IERC20 {\n    function approve(address,uint) external;\n    function transfer(address,uint) external returns (bool);\n    function transferFrom(address,address,uint) external returns (bool);\n    function balanceOf(address) external view returns (uint);\n    function allowance(address from, address to) external view returns (uint);\n}\n\ninterface IDelegateableERC20 is IERC20 {\n    function delegate(address delegatee) external;\n    function delegates(address delegator) external view returns (address delegatee);\n}\n\n"
      }
    },
    "settings": {
      "remappings": [
        "ds-test/=lib/solmate/lib/ds-test/src/",
        "forge-std/=lib/forge-std/src/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "solmate/=lib/solmate/src/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs"
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "london",
      "libraries": {}
    }
  }}