{
  "address": "0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312",
  "abi": [
    {
      "inputs": [],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "depositAccount",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "owner",
          "type": "address"
        }
      ],
      "name": "DepositAccountDeployed",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "depositAccount",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "DepositExitCompleted",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "depositAccount",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "token",
          "type": "address"
        }
      ],
      "name": "DepositExitRejected",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "depositAccount",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "lockedUntil",
          "type": "uint256"
        }
      ],
      "name": "DepositExitRequested",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "depositAccount",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "DepositWithdrawn",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "guardian",
          "type": "address"
        }
      ],
      "name": "GuardianAdded",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "guardian",
          "type": "address"
        }
      ],
      "name": "GuardianRemoved",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "initializer",
          "type": "address"
        }
      ],
      "name": "Initialized",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "hash",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "recipient",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "uid",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "PaymentChannelCommitted",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "channelHash",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        }
      ],
      "name": "PaymentDeposited",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "channelHash",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "totalValue",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "depositValue",
          "type": "uint256"
        }
      ],
      "name": "PaymentSplit",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "channelHash",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        }
      ],
      "name": "PaymentWithdrawn",
      "type": "event"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "guardian",
          "type": "address"
        }
      ],
      "name": "addGuardian",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "chainId",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "internalType": "bytes32",
          "name": "uid",
          "type": "bytes32"
        },
        {
          "internalType": "uint256",
          "name": "blockNumber",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        },
        {
          "internalType": "bytes",
          "name": "senderSignature",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "guardianSignature",
          "type": "bytes"
        }
      ],
      "name": "commitPaymentChannelAndDeposit",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "internalType": "bytes32",
          "name": "uid",
          "type": "bytes32"
        },
        {
          "internalType": "uint256",
          "name": "blockNumber",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "depositPaymentValue",
          "type": "uint256"
        },
        {
          "internalType": "bytes",
          "name": "senderSignature",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "guardianSignature",
          "type": "bytes"
        }
      ],
      "name": "commitPaymentChannelAndSplit",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "internalType": "bytes32",
          "name": "uid",
          "type": "bytes32"
        },
        {
          "internalType": "uint256",
          "name": "blockNumber",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        },
        {
          "internalType": "bytes",
          "name": "senderSignature",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "guardianSignature",
          "type": "bytes"
        }
      ],
      "name": "commitPaymentChannelAndWithdraw",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "owner",
          "type": "address"
        }
      ],
      "name": "computeDepositAccountAddress",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "recipient",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "internalType": "bytes32",
          "name": "uid",
          "type": "bytes32"
        }
      ],
      "name": "computePaymentChannelHash",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "pure",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "owner",
          "type": "address"
        }
      ],
      "name": "deployDepositAccount",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "depositExitLockPeriod",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "externalAccountRegistry",
      "outputs": [
        {
          "internalType": "contract ExternalAccountRegistry",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "gateway",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "token",
          "type": "address"
        }
      ],
      "name": "getDepositExitLockedUntil",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "token",
          "type": "address"
        }
      ],
      "name": "getDepositWithdrawnAmount",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "hash",
          "type": "bytes32"
        }
      ],
      "name": "getPaymentChannelCommittedAmount",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "components": [
            {
              "internalType": "address",
              "name": "owner",
              "type": "address"
            },
            {
              "internalType": "address",
              "name": "token",
              "type": "address"
            },
            {
              "internalType": "uint256",
              "name": "amount",
              "type": "uint256"
            }
          ],
          "internalType": "struct PaymentRegistry.DepositWithdrawal",
          "name": "depositWithdrawal",
          "type": "tuple"
        }
      ],
      "name": "hashDepositWithdrawal",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "components": [
            {
              "internalType": "address",
              "name": "sender",
              "type": "address"
            },
            {
              "internalType": "address",
              "name": "recipient",
              "type": "address"
            },
            {
              "internalType": "address",
              "name": "token",
              "type": "address"
            },
            {
              "internalType": "bytes32",
              "name": "uid",
              "type": "bytes32"
            },
            {
              "internalType": "uint256",
              "name": "blockNumber",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "amount",
              "type": "uint256"
            }
          ],
          "internalType": "struct PaymentRegistry.PaymentChannelCommit",
          "name": "paymentChannelCommit",
          "type": "tuple"
        }
      ],
      "name": "hashPaymentChannelCommit",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract ExternalAccountRegistry",
          "name": "externalAccountRegistry_",
          "type": "address"
        },
        {
          "internalType": "contract PersonalAccountRegistry",
          "name": "personalAccountRegistry_",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "depositExitLockPeriod_",
          "type": "uint256"
        },
        {
          "internalType": "address[]",
          "name": "guardians_",
          "type": "address[]"
        },
        {
          "internalType": "address",
          "name": "gateway_",
          "type": "address"
        }
      ],
      "name": "initialize",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "owner",
          "type": "address"
        }
      ],
      "name": "isDepositAccountDeployed",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "guardian",
          "type": "address"
        }
      ],
      "name": "isGuardian",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "isInitialized",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "personalAccountRegistry",
      "outputs": [
        {
          "internalType": "contract PersonalAccountRegistry",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "token",
          "type": "address"
        }
      ],
      "name": "processDepositExit",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "guardian",
          "type": "address"
        }
      ],
      "name": "removeGuardian",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "token",
          "type": "address"
        }
      ],
      "name": "requestDepositExit",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "messageHash",
          "type": "bytes32"
        },
        {
          "internalType": "bytes",
          "name": "signature",
          "type": "bytes"
        }
      ],
      "name": "verifyGuardianSignature",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        },
        {
          "internalType": "bytes",
          "name": "guardianSignature",
          "type": "bytes"
        }
      ],
      "name": "withdrawDeposit",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ],
  "transactionHash": "0x2a2fdbd35a653125226b317ef1be747a3e2ea6c69be0842aa1baf64633b82785",
  "receipt": {
    "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
    "from": "0x53fE9288897e254698175740aa359E19E26c10af",
    "contractAddress": null,
    "transactionIndex": 10,
    "gasUsed": "4295359",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0xa3d5d3513503e93d15e01fa7649f4d2ea90f2403aaf1d0f5bffb1553b1b3759a",
    "transactionHash": "0x2a2fdbd35a653125226b317ef1be747a3e2ea6c69be0842aa1baf64633b82785",
    "logs": [],
    "blockNumber": 23946503,
    "cumulativeGasUsed": "5701195",
    "status": 1,
    "byzantium": true
  },
  "args": [],
  "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae",
  "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositAccount\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"DepositAccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositAccount\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DepositExitCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositAccount\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"DepositExitRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositAccount\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lockedUntil\",\"type\":\"uint256\"}],\"name\":\"DepositExitRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositAccount\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DepositWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"GuardianAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"GuardianRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PaymentChannelCommitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"channelHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"PaymentDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"channelHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalValue\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"depositValue\",\"type\":\"uint256\"}],\"name\":\"PaymentSplit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"channelHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"addGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"senderSignature\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"guardianSignature\",\"type\":\"bytes\"}],\"name\":\"commitPaymentChannelAndDeposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"depositPaymentValue\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"senderSignature\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"guardianSignature\",\"type\":\"bytes\"}],\"name\":\"commitPaymentChannelAndSplit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"senderSignature\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"guardianSignature\",\"type\":\"bytes\"}],\"name\":\"commitPaymentChannelAndWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"computeDepositAccountAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"name\":\"computePaymentChannelHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"deployDepositAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositExitLockPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"externalAccountRegistry\",\"outputs\":[{\"internalType\":\"contract ExternalAccountRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gateway\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getDepositExitLockedUntil\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getDepositWithdrawnAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"getPaymentChannelCommittedAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct PaymentRegistry.DepositWithdrawal\",\"name\":\"depositWithdrawal\",\"type\":\"tuple\"}],\"name\":\"hashDepositWithdrawal\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct PaymentRegistry.PaymentChannelCommit\",\"name\":\"paymentChannelCommit\",\"type\":\"tuple\"}],\"name\":\"hashPaymentChannelCommit\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ExternalAccountRegistry\",\"name\":\"externalAccountRegistry_\",\"type\":\"address\"},{\"internalType\":\"contract PersonalAccountRegistry\",\"name\":\"personalAccountRegistry_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"depositExitLockPeriod_\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"guardians_\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"gateway_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"isDepositAccountDeployed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"isGuardian\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"personalAccountRegistry\",\"outputs\":[{\"internalType\":\"contract PersonalAccountRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"processDepositExit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"removeGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"requestDepositExit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"verifyGuardianSignature\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"guardianSignature\",\"type\":\"bytes\"}],\"name\":\"withdrawDeposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\",\"details\":\"the `DepositExit` process can be used in a case operator (guardian) couldn't sign commit / withdrawal message. Process will be rejected when any of senders channels will be committed.\",\"events\":{\"DepositAccountDeployed(address,address)\":{\"details\":\"Emitted when the deposit account is deployed\",\"params\":{\"depositAccount\":\"deposit account address\",\"owner\":\"owner address\"}},\"DepositExitCompleted(address,address,address,uint256)\":{\"details\":\"Emitted when the deposit exist is completed\",\"params\":{\"amount\":\"deposit exist amount\",\"depositAccount\":\"deposit account address\",\"owner\":\"owner address\",\"token\":\"token address\"}},\"DepositExitRejected(address,address,address)\":{\"details\":\"Emitted when the deposit exist is rejected\",\"params\":{\"depositAccount\":\"deposit account address\",\"owner\":\"owner address\",\"token\":\"token address\"}},\"DepositExitRequested(address,address,address,uint256)\":{\"details\":\"Emitted when the deposit exist is requested\",\"params\":{\"depositAccount\":\"deposit account address\",\"lockedUntil\":\"deposit exist locked util time\",\"owner\":\"owner address\",\"token\":\"token address\"}},\"DepositWithdrawn(address,address,address,uint256)\":{\"details\":\"Emitted when the deposit has been withdrawn\",\"params\":{\"amount\":\"withdrawn amount\",\"depositAccount\":\"deposit account address\",\"owner\":\"owner address\",\"token\":\"token address\"}},\"PaymentChannelCommitted(bytes32,address,address,address,bytes32,uint256)\":{\"details\":\"Emitted when the payment channel has been committed\",\"params\":{\"amount\":\"committed amount\",\"hash\":\"channel hash\",\"recipient\":\"recipient address\",\"sender\":\"sender address\",\"token\":\"token address\",\"uid\":\"unique channel id\"}},\"PaymentDeposited(bytes32,uint256)\":{\"details\":\"Emitted when the payment has been deposited\",\"params\":{\"channelHash\":\"channel hash\",\"value\":\"payment value\"}},\"PaymentSplit(bytes32,uint256,uint256)\":{\"details\":\"Emitted when the payment has been withdrawn and deposited (split)\",\"params\":{\"channelHash\":\"channel hash\",\"depositValue\":\"payment deposited value\",\"totalValue\":\"payment total value\"}},\"PaymentWithdrawn(bytes32,uint256)\":{\"details\":\"Emitted when the payment has been withdrawn\",\"params\":{\"channelHash\":\"channel hash\",\"value\":\"payment value\"}}},\"kind\":\"dev\",\"methods\":{\"addGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"}},\"commitPaymentChannelAndDeposit(address,address,bytes32,uint256,uint256,bytes,bytes)\":{\"params\":{\"amount\":\"amount to commit\",\"blockNumber\":\"block number\",\"guardianSignature\":\"guardian signature\",\"sender\":\"sender address\",\"senderSignature\":\"sender signature\",\"token\":\"token address\",\"uid\":\"unique channel id\"}},\"commitPaymentChannelAndSplit(address,address,bytes32,uint256,uint256,uint256,bytes,bytes)\":{\"params\":{\"amount\":\"amount to commit\",\"blockNumber\":\"block number\",\"depositPaymentValue\":\"amount to deposit\",\"guardianSignature\":\"guardian signature\",\"sender\":\"sender address\",\"senderSignature\":\"sender signature\",\"token\":\"token address\",\"uid\":\"unique channel id\"}},\"commitPaymentChannelAndWithdraw(address,address,bytes32,uint256,uint256,bytes,bytes)\":{\"params\":{\"amount\":\"amount to commit\",\"blockNumber\":\"block number\",\"guardianSignature\":\"guardian signature\",\"sender\":\"sender address\",\"senderSignature\":\"sender signature\",\"token\":\"token address\",\"uid\":\"unique channel id\"}},\"computeDepositAccountAddress(address)\":{\"params\":{\"owner\":\"owner address\"},\"returns\":{\"_0\":\"deposit account address\"}},\"computePaymentChannelHash(address,address,address,bytes32)\":{\"params\":{\"recipient\":\"recipient address\",\"sender\":\"sender address\",\"token\":\"token address\",\"uid\":\"unique channel id\"},\"returns\":{\"_0\":\"hash\"}},\"constructor\":{\"details\":\"Public constructor\"},\"deployDepositAccount(address)\":{\"params\":{\"owner\":\"owner address\"}},\"getDepositExitLockedUntil(address,address)\":{\"params\":{\"owner\":\"owner address\",\"token\":\"token address\"},\"returns\":{\"_0\":\"locked until time\"}},\"getDepositWithdrawnAmount(address,address)\":{\"params\":{\"owner\":\"owner address\",\"token\":\"token address\"},\"returns\":{\"_0\":\"withdrawn amount\"}},\"getPaymentChannelCommittedAmount(bytes32)\":{\"params\":{\"hash\":\"payment channel hash\"},\"returns\":{\"_0\":\"committed amount\"}},\"hashDepositWithdrawal((address,address,uint256))\":{\"params\":{\"depositWithdrawal\":\"struct\"},\"returns\":{\"_0\":\"hash\"}},\"hashPaymentChannelCommit((address,address,address,bytes32,uint256,uint256))\":{\"params\":{\"paymentChannelCommit\":\"struct\"},\"returns\":{\"_0\":\"hash\"}},\"initialize(address,address,uint256,address[],address)\":{\"params\":{\"depositExitLockPeriod_\":\"deposit exit lock period\",\"externalAccountRegistry_\":\"`ExternalAccountRegistry` contract address\",\"gateway_\":\"`Gateway` contract address\",\"guardians_\":\"array of guardians addresses\",\"personalAccountRegistry_\":\"`PersonalAccountRegistry` contract address\"}},\"isDepositAccountDeployed(address)\":{\"params\":{\"owner\":\"owner address\"},\"returns\":{\"_0\":\"true when deposit account is deployed\"}},\"isGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"},\"returns\":{\"_0\":\"true when guardian exists\"}},\"isInitialized()\":{\"returns\":{\"_0\":\"true when contract is initialized\"}},\"processDepositExit(address)\":{\"params\":{\"token\":\"token address\"}},\"removeGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"}},\"requestDepositExit(address)\":{\"params\":{\"token\":\"token address\"}},\"verifyGuardianSignature(bytes32,bytes)\":{\"params\":{\"messageHash\":\"message hash\",\"signature\":\"signature\"},\"returns\":{\"_0\":\"true on correct guardian signature\"}},\"withdrawDeposit(address,uint256,bytes)\":{\"params\":{\"amount\":\"amount to withdraw\",\"guardianSignature\":\"guardian signature\",\"token\":\"token address\"}}},\"title\":\"Payment registry\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addGuardian(address)\":{\"notice\":\"Adds a new guardian\"},\"commitPaymentChannelAndDeposit(address,address,bytes32,uint256,uint256,bytes,bytes)\":{\"notice\":\"Commits payment channel and deposit payment\"},\"commitPaymentChannelAndSplit(address,address,bytes32,uint256,uint256,uint256,bytes,bytes)\":{\"notice\":\"Commits payment channel, withdraws and deposits (split) payment\"},\"commitPaymentChannelAndWithdraw(address,address,bytes32,uint256,uint256,bytes,bytes)\":{\"notice\":\"Commits payment channel and withdraw payment\"},\"computeDepositAccountAddress(address)\":{\"notice\":\"Computes deposit account address\"},\"computePaymentChannelHash(address,address,address,bytes32)\":{\"notice\":\"Computes payment channel hash\"},\"deployDepositAccount(address)\":{\"notice\":\"Deploys deposit account\"},\"getDepositExitLockedUntil(address,address)\":{\"notice\":\"Gets deposit exit locked until time\"},\"getDepositWithdrawnAmount(address,address)\":{\"notice\":\"Gets deposit withdrawn amount\"},\"getPaymentChannelCommittedAmount(bytes32)\":{\"notice\":\"Gets payment channel committed amount\"},\"hashDepositWithdrawal((address,address,uint256))\":{\"notice\":\"Hashes `DepositWithdrawal` message payload\"},\"hashPaymentChannelCommit((address,address,address,bytes32,uint256,uint256))\":{\"notice\":\"Hashes `PaymentChannelCommit` message payload\"},\"initialize(address,address,uint256,address[],address)\":{\"notice\":\"Initialize `PaymentRegistry` contract\"},\"isDepositAccountDeployed(address)\":{\"notice\":\"Checks if deposit account is deployed\"},\"isGuardian(address)\":{\"notice\":\"Check if guardian exists\"},\"isInitialized()\":{\"notice\":\"Check if contract is initialized\"},\"processDepositExit(address)\":{\"notice\":\"Processes deposit exit\"},\"removeGuardian(address)\":{\"notice\":\"Removes the existing guardian\"},\"requestDepositExit(address)\":{\"notice\":\"Requests deposit exit\"},\"verifyGuardianSignature(bytes32,bytes)\":{\"notice\":\"Verifies guardian signature\"},\"withdrawDeposit(address,uint256,bytes)\":{\"notice\":\"Withdraws deposit\"}},\"notice\":\"A registry for payment and payment channels\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/payments/PaymentRegistry.sol\":\"PaymentRegistry\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/common/access/Controlled.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Controlled\\n *\\n * @dev Contract module which provides an access control mechanism.\\n * It ensures there is only one controlling account of the smart contract\\n * and grants that account exclusive access to specific functions.\\n *\\n * The controller account will be the one that deploys the contract.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract Controlled {\\n  /**\\n   * @return controller account address\\n   */\\n  address public controller;\\n\\n  // modifiers\\n\\n  /**\\n   * @dev Throws if msg.sender is not the controller\\n   */\\n  modifier onlyController() {\\n    require(\\n      msg.sender == controller,\\n      \\\"Controlled: msg.sender is not the controller\\\"\\n    );\\n\\n    _;\\n  }\\n\\n  /**\\n   * @dev Internal constructor\\n   */\\n  constructor()\\n    internal\\n  {\\n    controller = msg.sender;\\n  }\\n}\\n\",\"keccak256\":\"0xdf03a0b7ec644da9925c5c1b6c8a86bb1cc1b9c5018bb265a1a4c5044b877af3\",\"license\":\"MIT\"},\"src/common/access/Guarded.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/ECDSALib.sol\\\";\\n\\n\\n/**\\n * @title Guarded\\n *\\n * @dev Contract module which provides a guardian-type control mechanism.\\n * It allows key accounts to have guardians and restricts specific methods to be accessible by guardians only.\\n *\\n * Each guardian account can remove other guardians\\n *\\n * Use `_initializeGuarded` to initialize the contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract Guarded {\\n  using ECDSALib for bytes32;\\n\\n  mapping(address => bool) private guardians;\\n\\n  // events\\n\\n  /**\\n   * @dev Emitted when a new guardian is added\\n   * @param sender sender address\\n   * @param guardian guardian address\\n   */\\n  event GuardianAdded(\\n    address sender,\\n    address guardian\\n  );\\n\\n  /**\\n   * @dev Emitted when the existing guardian is removed\\n   * @param sender sender address\\n   * @param guardian guardian address\\n   */\\n  event GuardianRemoved(\\n    address sender,\\n    address guardian\\n  );\\n\\n  // modifiers\\n\\n  /**\\n   * @dev Throws if tx.origin is not a guardian account\\n   */\\n  modifier onlyGuardian() {\\n    require(\\n      // solhint-disable-next-line avoid-tx-origin\\n      guardians[tx.origin],\\n      \\\"Guarded: tx.origin is not the guardian\\\"\\n    );\\n\\n    _;\\n  }\\n\\n  /**\\n   * @dev Internal constructor\\n   */\\n  constructor() internal {}\\n\\n  // external functions\\n\\n  /**\\n   * @notice Adds a new guardian\\n   * @param guardian guardian address\\n   */\\n  function addGuardian(\\n    address guardian\\n  )\\n    external\\n    onlyGuardian\\n  {\\n    _addGuardian(guardian);\\n  }\\n\\n  /**\\n   * @notice Removes the existing guardian\\n   * @param guardian guardian address\\n   */\\n  function removeGuardian(\\n    address guardian\\n  )\\n    external\\n    onlyGuardian\\n  {\\n    require(\\n      // solhint-disable-next-line avoid-tx-origin\\n      tx.origin != guardian,\\n      \\\"Guarded: cannot remove self\\\"\\n    );\\n\\n    require(\\n      guardians[guardian],\\n      \\\"Guarded: guardian doesn't exist\\\"\\n    );\\n\\n    guardians[guardian] = false;\\n\\n    emit GuardianRemoved(\\n      // solhint-disable-next-line avoid-tx-origin\\n      tx.origin,\\n      guardian\\n    );\\n  }\\n\\n  // external functions (views)\\n\\n  /**\\n   * @notice Check if guardian exists\\n   * @param guardian guardian address\\n   * @return true when guardian exists\\n   */\\n  function isGuardian(\\n    address guardian\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return guardians[guardian];\\n  }\\n\\n  /**\\n   * @notice Verifies guardian signature\\n   * @param messageHash message hash\\n   * @param signature signature\\n   * @return true on correct guardian signature\\n   */\\n  function verifyGuardianSignature(\\n    bytes32 messageHash,\\n    bytes calldata signature\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return _verifyGuardianSignature(\\n      messageHash,\\n      signature\\n    );\\n  }\\n\\n  // internal functions\\n\\n  /**\\n   * @notice Initializes `Guarded` contract\\n   * @dev If `guardians_` array is empty `tx.origin` is added as guardian account\\n   * @param guardians_ array of guardians addresses\\n   */\\n  function _initializeGuarded(\\n    address[] memory guardians_\\n  )\\n    internal\\n  {\\n    if (guardians_.length == 0) {\\n      // solhint-disable-next-line avoid-tx-origin\\n      _addGuardian(tx.origin);\\n    } else {\\n      uint guardiansLen = guardians_.length;\\n      for (uint i = 0; i < guardiansLen; i++) {\\n        _addGuardian(guardians_[i]);\\n      }\\n    }\\n  }\\n\\n\\n  // internal functions (views)\\n\\n  function _verifyGuardianSignature(\\n    bytes32 messageHash,\\n    bytes memory signature\\n  )\\n    internal\\n    view\\n    returns (bool)\\n  {\\n    address guardian = messageHash.recoverAddress(signature);\\n\\n    return guardians[guardian];\\n  }\\n\\n  // private functions\\n\\n  function _addGuardian(\\n    address guardian\\n  )\\n    private\\n  {\\n    require(\\n      guardian != address(0),\\n      \\\"Guarded: cannot add 0x0 guardian\\\"\\n    );\\n\\n    require(\\n      !guardians[guardian],\\n      \\\"Guarded: guardian already exists\\\"\\n    );\\n\\n    guardians[guardian] = true;\\n\\n    emit GuardianAdded(\\n      // solhint-disable-next-line avoid-tx-origin\\n      tx.origin,\\n      guardian\\n    );\\n  }\\n}\\n\",\"keccak256\":\"0x4a5f5670041362e87ea267d81c55fc3edc1a78e81f6f17524b13267f91f31458\",\"license\":\"MIT\"},\"src/common/account/Account.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../access/Controlled.sol\\\";\\nimport \\\"./AccountBase.sol\\\";\\n\\n\\n/**\\n * @title Account\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract Account is Controlled, AccountBase {\\n  address public implementation;\\n\\n  /**\\n   * @dev Public constructor\\n   * @param registry_ account registry address\\n   * @param implementation_ account implementation address\\n   */\\n  constructor(\\n    address registry_,\\n    address implementation_\\n  )\\n    public\\n    Controlled()\\n  {\\n    registry = registry_;\\n    implementation = implementation_;\\n  }\\n\\n  // external functions\\n\\n  /**\\n   * @notice Payable receive\\n   */\\n  receive()\\n    external\\n    payable\\n  {\\n    //\\n  }\\n\\n  /**\\n   * @notice Fallback\\n   */\\n  // solhint-disable-next-line payable-fallback\\n  fallback()\\n    external\\n  {\\n    if (msg.data.length != 0) {\\n      address implementation_ = implementation;\\n\\n      // solhint-disable-next-line no-inline-assembly\\n      assembly {\\n        let calldedatasize := calldatasize()\\n\\n        calldatacopy(0, 0, calldedatasize)\\n\\n        let result := delegatecall(gas(), implementation_, 0, calldedatasize, 0, 0)\\n        let returneddatasize := returndatasize()\\n\\n        returndatacopy(0, 0, returneddatasize)\\n\\n        switch result\\n        case 0 { revert(0, returneddatasize) }\\n        default { return(0, returneddatasize) }\\n      }\\n    }\\n  }\\n\\n  /**\\n   * @notice Sets implementation\\n   * @param implementation_ implementation address\\n   */\\n  function setImplementation(\\n    address implementation_\\n  )\\n    external\\n    onlyController\\n  {\\n    implementation = implementation_;\\n  }\\n\\n  /**\\n   * @notice Executes transaction\\n   * @param to to address\\n   * @param value value\\n   * @param data data\\n   * @return transaction result\\n   */\\n  function executeTransaction(\\n    address to,\\n    uint256 value,\\n    bytes calldata data\\n  )\\n    external\\n    onlyController\\n    returns (bytes memory)\\n  {\\n    bytes memory result;\\n    bool succeeded;\\n\\n    // solhint-disable-next-line avoid-call-value, avoid-low-level-calls\\n    (succeeded, result) = payable(to).call{value: value}(data);\\n\\n    require(\\n      succeeded,\\n      \\\"Account: transaction reverted\\\"\\n    );\\n\\n    return result;\\n  }\\n}\\n\",\"keccak256\":\"0xe516c999a02a65ee99487d398d0c12589500680a9ca08c852540fb9473d70a26\",\"license\":\"MIT\"},\"src/common/account/AccountBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Account base\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract AccountBase {\\n  address public registry;\\n}\\n\",\"keccak256\":\"0xcadf29e389f8db823e14f3f92808fd135f07b0135eb4dcf29b89c85941b39862\",\"license\":\"MIT\"},\"src/common/account/AccountController.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./Account.sol\\\";\\n\\n\\n/**\\n * @title Account controller\\n *\\n * @dev Contract module which provides Account deployment mechanism\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract AccountController {\\n  address public accountRegistry;\\n  address public accountImplementation;\\n\\n  // events\\n\\n  /**\\n   * @dev Emitted when the account registry is updated\\n   * @param accountRegistry account registry address\\n   */\\n  event AccountRegistryUpdated(\\n    address accountRegistry\\n  );\\n\\n  /**\\n   * @dev Emitted when the account implementation is updated\\n   * @param accountImplementation account implementation address\\n   */\\n  event AccountImplementationUpdated(\\n    address accountImplementation\\n  );\\n\\n  /**\\n   * @dev Emitted when the account is deployed\\n   * @param account account address\\n   * @param accountImplementation account implementation address\\n   */\\n  event AccountDeployed(\\n    address account,\\n    address accountImplementation\\n  );\\n\\n  /**\\n   * @dev Emitted when the account is upgraded\\n   * @param account account address\\n   * @param accountImplementation account implementation address\\n   */\\n  event AccountUpgraded(\\n    address account,\\n    address accountImplementation\\n  );\\n\\n  /**\\n   * @dev Emitted when the transaction is executed\\n   * @param account account address\\n   * @param to to address\\n   * @param value value\\n   * @param data data\\n   * @param response response\\n   */\\n  event AccountTransactionExecuted(\\n    address account,\\n    address to,\\n    uint256 value,\\n    bytes data,\\n    bytes response\\n  );\\n\\n  /**\\n   * @dev Internal constructor\\n   */\\n  constructor() internal {}\\n\\n  // internal functions\\n\\n  /**\\n   * @notice Initializes `AccountController` contract\\n   * @param accountRegistry_ account registry address\\n   * @param accountImplementation_ account implementation address\\n   */\\n  function _initializeAccountController(\\n    address accountRegistry_,\\n    address accountImplementation_\\n  )\\n    internal\\n  {\\n    _setAccountRegistry(accountRegistry_, false);\\n    _setAccountImplementation(accountImplementation_, false);\\n  }\\n\\n  /**\\n   * @notice Sets account registry\\n   * @param accountRegistry_ account registry address\\n   * @param emitEvent it will emit event when flag is set to true\\n   */\\n  function _setAccountRegistry(\\n    address accountRegistry_,\\n    bool emitEvent\\n  )\\n    internal\\n  {\\n    require(\\n      accountRegistry_ != address(0),\\n      \\\"AccountController: cannot set account registry to 0x0\\\"\\n    );\\n\\n    accountRegistry = accountRegistry_;\\n\\n    if (emitEvent) {\\n      emit AccountRegistryUpdated(accountRegistry);\\n    }\\n  }\\n\\n  /**\\n   * @notice Sets account implementation\\n   * @param accountImplementation_ account implementation address\\n   * @param emitEvent it will emit event when flag is set to true\\n   */\\n  function _setAccountImplementation(\\n    address accountImplementation_,\\n    bool emitEvent\\n  )\\n    internal\\n  {\\n    require(\\n      accountImplementation_ != address(0),\\n      \\\"AccountController: cannot set account Implementation to 0x0\\\"\\n    );\\n\\n    accountImplementation = accountImplementation_;\\n\\n    if (emitEvent) {\\n      emit AccountImplementationUpdated(accountImplementation);\\n    }\\n  }\\n\\n  /**\\n   * @notice Deploys account\\n   * @param salt CREATE2 salt\\n   * @param emitEvent it will emit event when flag is set to true\\n   * @return account address\\n   */\\n  function _deployAccount(\\n    bytes32 salt,\\n    bool emitEvent\\n  )\\n    internal\\n    returns (address)\\n  {\\n    address account = address(new Account{salt: salt}(\\n      accountRegistry,\\n      accountImplementation\\n    ));\\n\\n    if (emitEvent) {\\n      emit AccountDeployed(\\n        account,\\n        accountImplementation\\n      );\\n    }\\n\\n    return account;\\n  }\\n\\n  /**\\n   * @notice Upgrades account\\n   * @param account account address\\n   * @param emitEvent it will emit event when flag is set to true\\n   */\\n  function _upgradeAccount(\\n    address account,\\n    bool emitEvent\\n  )\\n    internal\\n  {\\n    require(\\n      Account(payable(account)).implementation() != accountImplementation,\\n      \\\"AccountController: account already upgraded\\\"\\n    );\\n\\n    Account(payable(account)).setImplementation(accountImplementation);\\n\\n    if (emitEvent) {\\n      emit AccountUpgraded(\\n        account,\\n        accountImplementation\\n      );\\n    }\\n  }\\n\\n  /**\\n   * @notice Executes transaction from the account\\n   * @param account account address\\n   * @param to to address\\n   * @param value value\\n   * @param data data\\n   * @param emitEvent it will emit event when flag is set to true\\n   * @return transaction result\\n   */\\n  function _executeAccountTransaction(\\n    address account,\\n    address to,\\n    uint256 value,\\n    bytes memory data,\\n    bool emitEvent\\n  )\\n    internal\\n    returns (bytes memory)\\n  {\\n    require(\\n      to != address(0),\\n      \\\"AccountController: cannot send to 0x0\\\"\\n    );\\n\\n    require(\\n      to != address(this),\\n      \\\"AccountController: cannot send to controller\\\"\\n    );\\n\\n    require(\\n      to != account,\\n      \\\"AccountController: cannot send to self\\\"\\n    );\\n\\n    bytes memory response = Account(payable(account)).executeTransaction(\\n      to,\\n      value,\\n      data\\n    );\\n\\n    if (emitEvent) {\\n      emit AccountTransactionExecuted(\\n        account,\\n        to,\\n        value,\\n        data,\\n        response\\n      );\\n    }\\n\\n    return response;\\n  }\\n\\n  // internal functions (views)\\n\\n  /**\\n   * @notice Computes account CREATE2 address\\n   * @param salt CREATE2 salt\\n   * @return account address\\n   */\\n  function _computeAccountAddress(\\n    bytes32 salt\\n  )\\n    internal\\n    view\\n    returns (address)\\n  {\\n    bytes memory creationCode = abi.encodePacked(\\n      type(Account).creationCode,\\n      bytes12(0),\\n      accountRegistry,\\n      bytes12(0),\\n      accountImplementation\\n    );\\n\\n    bytes32 data = keccak256(\\n      abi.encodePacked(\\n        bytes1(0xff),\\n        address(this),\\n        salt,\\n        keccak256(creationCode)\\n      )\\n    );\\n\\n    return address(uint160(uint256(data)));\\n  }\\n}\\n\",\"keccak256\":\"0xe161f1f4f6ea5d3a9810f7c93764d55e473abe1054e6aa68fde791be7d70a26c\",\"license\":\"MIT\"},\"src/common/account/AccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./Account.sol\\\";\\n\\n\\n/**\\n * @title Account registry\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\nabstract contract AccountRegistry {\\n  /**\\n   * @notice Verifies account signature\\n   * @param account account address\\n   * @param messageHash message hash\\n   * @param signature signature\\n   * @return true if valid\\n   */\\n  function isValidAccountSignature(\\n    address account,\\n    bytes32 messageHash,\\n    bytes calldata signature\\n  )\\n    virtual\\n    external\\n    view\\n    returns (bool);\\n\\n  /**\\n   * @notice Verifies account signature\\n   * @param account account address\\n   * @param message message\\n   * @param signature signature\\n   * @return true if valid\\n   */\\n  function isValidAccountSignature(\\n    address account,\\n    bytes calldata message,\\n    bytes calldata signature\\n  )\\n    virtual\\n    external\\n    view\\n    returns (bool);\\n}\\n\",\"keccak256\":\"0x2d40245721f5f74219e5cf88713246dbe8b6d5404e941125d3e850b1f127ec34\",\"license\":\"MIT\"},\"src/common/libs/BlockLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Block library\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\nlibrary BlockLib {\\n  struct BlockRelated {\\n    bool added;\\n    uint256 removedAtBlockNumber;\\n  }\\n\\n  /**\\n   * @notice Verifies self struct at current block\\n   * @param self self struct\\n   * @return true on correct self struct\\n   */\\n  function verifyAtCurrentBlock(\\n    BlockRelated memory self\\n  )\\n    internal\\n    view\\n    returns (bool)\\n  {\\n    return verifyAtBlock(self, block.number);\\n  }\\n\\n  /**\\n   * @notice Verifies self struct at any block\\n   * @param self self struct\\n   * @return true on correct self struct\\n   */\\n  function verifyAtAnyBlock(\\n    BlockRelated memory self\\n  )\\n    internal\\n    pure\\n    returns (bool)\\n  {\\n    return verifyAtBlock(self, 0);\\n  }\\n\\n  /**\\n   * @notice Verifies self struct at specific block\\n   * @param self self struct\\n   * @param blockNumber block number to verify\\n   * @return true on correct self struct\\n   */\\n  function verifyAtBlock(\\n    BlockRelated memory self,\\n    uint256 blockNumber\\n  )\\n    internal\\n    pure\\n    returns (bool)\\n  {\\n    bool result = false;\\n\\n    if (self.added) {\\n      if (self.removedAtBlockNumber == 0) {\\n        result = true;\\n      } else if (blockNumber == 0) {\\n        result = true;\\n      } else {\\n        result = self.removedAtBlockNumber > blockNumber;\\n      }\\n    }\\n\\n    return result;\\n  }\\n}\\n\",\"keccak256\":\"0x9205536bc211f86d1113118a44dddfa7a9b9772a918cf4b1575c982a05472587\",\"license\":\"MIT\"},\"src/common/libs/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Bytes library\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\nlibrary BytesLib {\\n  /**\\n   * @notice Converts bytes to address\\n   * @param data data\\n   * @return address\\n   */\\n  function toAddress(\\n    bytes memory data\\n  )\\n    internal\\n    pure\\n    returns (address)\\n  {\\n    address result;\\n\\n    require(\\n      data.length == 20,\\n      \\\"BytesLib: invalid data length\\\"\\n    );\\n\\n    // solhint-disable-next-line no-inline-assembly\\n    assembly {\\n      result := div(mload(add(data, 0x20)), 0x1000000000000000000000000)\\n    }\\n\\n    return result;\\n  }\\n}\\n\",\"keccak256\":\"0x64c84964ea91bfb1f2d859eea6c57fe5b4a6f269951a4adf5f58d306c54c7f76\",\"license\":\"MIT\"},\"src/common/libs/ECDSAExtendedLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./StringsLib.sol\\\";\\n\\n\\n/**\\n * @title ECDSA extended library\\n */\\nlibrary ECDSAExtendedLib {\\n  using StringsLib for uint;\\n\\n  function toEthereumSignedMessageHash(\\n    bytes memory message\\n  )\\n    internal\\n    pure\\n    returns (bytes32)\\n  {\\n    return keccak256(abi.encodePacked(\\n      \\\"\\\\x19Ethereum Signed Message:\\\\n\\\",\\n      message.length.toString(),\\n      abi.encodePacked(message)\\n    ));\\n  }\\n}\\n\",\"keccak256\":\"0x83e6056caaba892d91de45324f4d2702ac01695fab2d34c86895d7d288547ba3\",\"license\":\"MIT\"},\"src/common/libs/ECDSALib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ECDSA library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/cryptography/ECDSA.sol#L26\\n */\\nlibrary ECDSALib {\\n  function recoverAddress(\\n    bytes32 messageHash,\\n    bytes memory signature\\n  )\\n    internal\\n    pure\\n    returns (address)\\n  {\\n    address result = address(0);\\n\\n    if (signature.length == 65) {\\n      bytes32 r;\\n      bytes32 s;\\n      uint8 v;\\n\\n      // solhint-disable-next-line no-inline-assembly\\n      assembly {\\n        r := mload(add(signature, 0x20))\\n        s := mload(add(signature, 0x40))\\n        v := byte(0, mload(add(signature, 0x60)))\\n      }\\n\\n      if (v < 27) {\\n        v += 27;\\n      }\\n\\n      if (v == 27 || v == 28) {\\n        result = ecrecover(messageHash, v, r, s);\\n      }\\n    }\\n\\n    return result;\\n  }\\n\\n  function toEthereumSignedMessageHash(\\n    bytes32 messageHash\\n  )\\n    internal\\n    pure\\n    returns (bytes32)\\n  {\\n    return keccak256(abi.encodePacked(\\n      \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n      messageHash\\n    ));\\n  }\\n}\\n\",\"keccak256\":\"0x3b1460d688302eb595268c2af147ab532f29dbced66520e013f48d498eed3cec\",\"license\":\"MIT\"},\"src/common/libs/SafeMathLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Safe math library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/math/SafeMath.sol\\n */\\nlibrary SafeMathLib {\\n  function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n    uint256 c = a + b;\\n\\n    require(c >= a, \\\"SafeMathLib: addition overflow\\\");\\n\\n    return c;\\n  }\\n\\n  function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n    return sub(a, b, \\\"SafeMathLib: subtraction overflow\\\");\\n  }\\n\\n  function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n    require(b <= a, errorMessage);\\n\\n    return a - b;\\n  }\\n\\n  function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n    if (a == 0) {\\n      return 0;\\n    }\\n\\n    uint256 c = a * b;\\n\\n    require(c / a == b, \\\"SafeMathLib: multiplication overflow\\\");\\n\\n    return c;\\n  }\\n\\n  function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n    return div(a, b, \\\"SafeMathLib: division by zero\\\");\\n  }\\n\\n  function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n    require(b > 0, errorMessage);\\n\\n    return a / b;\\n  }\\n\\n  function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n    return mod(a, b, \\\"SafeMathLib: modulo by zero\\\");\\n  }\\n\\n  function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n    require(b != 0, errorMessage);\\n\\n    return a % b;\\n  }\\n}\\n\",\"keccak256\":\"0x6089f354ca754d9c5dd9e800ee5ed86717dbf8f9af470604e0be691ac57c0107\",\"license\":\"MIT\"},\"src/common/libs/StringsLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Strings library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/utils/Strings.sol#L12\\n */\\nlibrary StringsLib {\\n  function toString(\\n    uint256 value\\n  )\\n    internal\\n    pure\\n    returns (string memory)\\n  {\\n    if (value == 0) {\\n      return \\\"0\\\";\\n    }\\n\\n    uint256 temp = value;\\n    uint256 digits;\\n\\n    while (temp != 0) {\\n      digits++;\\n      temp /= 10;\\n    }\\n\\n    bytes memory buffer = new bytes(digits);\\n    uint256 index = digits - 1;\\n    temp = value;\\n\\n    while (temp != 0) {\\n      buffer[index--] = byte(uint8(48 + temp % 10));\\n      temp /= 10;\\n    }\\n\\n    return string(buffer);\\n  }\\n}\\n\",\"keccak256\":\"0x4110150d0c921fd31db34ca33672de8e81c3ae467076149a3a546f804d1f58dd\",\"license\":\"MIT\"},\"src/common/lifecycle/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Contract module which provides access control mechanism, where\\n * there is the initializer account that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initializer account will be tx.origin during contract deployment and will be removed on first use.\\n * Use `onlyInitializer` modifier on contract initialize process.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract Initializable {\\n  address private initializer;\\n\\n  // events\\n\\n  /**\\n   * @dev Emitted after `onlyInitializer`\\n   * @param initializer initializer address\\n   */\\n  event Initialized(\\n    address initializer\\n  );\\n\\n  // modifiers\\n\\n  /**\\n   * @dev Throws if tx.origin is not the initializer\\n   */\\n  modifier onlyInitializer() {\\n    require(\\n      // solhint-disable-next-line avoid-tx-origin\\n      tx.origin == initializer,\\n      \\\"Initializable: tx.origin is not the initializer\\\"\\n    );\\n\\n    /// @dev removes initializer\\n    initializer = address(0);\\n\\n    _;\\n\\n    emit Initialized(\\n      // solhint-disable-next-line avoid-tx-origin\\n      tx.origin\\n    );\\n  }\\n\\n  /**\\n   * @dev Internal constructor\\n   */\\n  constructor()\\n    internal\\n  {\\n    // solhint-disable-next-line avoid-tx-origin\\n    initializer = tx.origin;\\n  }\\n\\n   // external functions (views)\\n\\n  /**\\n   * @notice Check if contract is initialized\\n   * @return true when contract is initialized\\n   */\\n  function isInitialized()\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return initializer == address(0);\\n  }\\n}\\n\",\"keccak256\":\"0x3d47b2864dde5bde245917f7ac416a9e9715cdf1d226897e49838eb3186ee067\",\"license\":\"MIT\"},\"src/common/signature/SignatureValidator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/ECDSALib.sol\\\";\\n\\n/**\\n * @title Signature validator\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract SignatureValidator {\\n  using ECDSALib for bytes32;\\n\\n  uint256 public chainId;\\n\\n  /**\\n   * @dev internal constructor\\n   */\\n  constructor() internal {\\n    uint256 chainId_;\\n\\n    // solhint-disable-next-line no-inline-assembly\\n    assembly {\\n      chainId_ := chainid()\\n    }\\n\\n    chainId = chainId_;\\n  }\\n\\n  // internal functions\\n\\n  function _hashMessagePayload(\\n    bytes32 messagePrefix,\\n    bytes memory messagePayload\\n  )\\n    internal\\n    view\\n    returns (bytes32)\\n  {\\n    return keccak256(abi.encodePacked(\\n      chainId,\\n      address(this),\\n      messagePrefix,\\n      messagePayload\\n    )).toEthereumSignedMessageHash();\\n  }\\n}\\n\",\"keccak256\":\"0xc1168f7ccb74aea67089941dc5e4c1d1c4aa766afca47a90c0b017b8445b8acf\",\"license\":\"MIT\"},\"src/common/token/ERC20Token.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/SafeMathLib.sol\\\";\\n\\n\\n/**\\n * @title ERC20 token\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/ERC20.sol\\n */\\ncontract ERC20Token {\\n  using SafeMathLib for uint256;\\n\\n  string public name;\\n  string public symbol;\\n  uint8 public decimals;\\n  uint256 public totalSupply;\\n\\n  mapping(address => uint256) internal balances;\\n  mapping(address => mapping(address => uint256)) internal allowances;\\n\\n  // events\\n\\n  event Transfer(\\n    address indexed from,\\n    address indexed to,\\n    uint256 value\\n  );\\n\\n  event Approval(\\n    address indexed owner,\\n    address indexed spender,\\n    uint256 value\\n  );\\n\\n  /**\\n   * @dev internal constructor\\n   */\\n  constructor() internal {}\\n\\n  // external functions\\n\\n  function transfer(\\n    address to,\\n    uint256 value\\n  )\\n    external\\n    returns (bool)\\n  {\\n    _transfer(_getSender(), to, value);\\n\\n    return true;\\n  }\\n\\n  function transferFrom(\\n    address from,\\n    address to,\\n    uint256 value\\n  )\\n    virtual\\n    external\\n    returns (bool)\\n  {\\n    address sender = _getSender();\\n\\n    _transfer(from, to, value);\\n    _approve(from, sender, allowances[from][sender].sub(value));\\n\\n    return true;\\n  }\\n\\n  function approve(\\n    address spender,\\n    uint256 value\\n  )\\n    virtual\\n    external\\n    returns (bool)\\n  {\\n    _approve(_getSender(), spender, value);\\n\\n    return true;\\n  }\\n\\n  // external functions (views)\\n\\n  function balanceOf(\\n    address owner\\n  )\\n    virtual\\n    external\\n    view\\n    returns (uint256)\\n  {\\n    return balances[owner];\\n  }\\n\\n  function allowance(\\n    address owner,\\n    address spender\\n  )\\n    virtual\\n    external\\n    view\\n    returns (uint256)\\n  {\\n    return allowances[owner][spender];\\n  }\\n\\n  // internal functions\\n\\n  function _transfer(\\n    address from,\\n    address to,\\n    uint256 value\\n  )\\n    virtual\\n    internal\\n  {\\n    require(\\n      from != address(0),\\n      \\\"ERC20Token: cannot transfer from 0x0 address\\\"\\n    );\\n    require(\\n      to != address(0),\\n      \\\"ERC20Token: cannot transfer to 0x0 address\\\"\\n    );\\n\\n    balances[from] = balances[from].sub(value);\\n    balances[to] = balances[to].add(value);\\n\\n    emit Transfer(from, to, value);\\n  }\\n\\n  function _approve(\\n    address owner,\\n    address spender,\\n    uint256 value\\n  )\\n    virtual\\n    internal\\n  {\\n    require(\\n      owner != address(0),\\n      \\\"ERC20Token: cannot approve from 0x0 address\\\"\\n    );\\n    require(\\n      spender != address(0),\\n      \\\"ERC20Token: cannot approve to 0x0 address\\\"\\n    );\\n\\n    allowances[owner][spender] = value;\\n\\n    emit Approval(owner, spender, value);\\n  }\\n\\n  function _mint(\\n    address owner,\\n    uint256 value\\n  )\\n    virtual\\n    internal\\n  {\\n    require(\\n      owner != address(0),\\n      \\\"ERC20Token: cannot mint to 0x0 address\\\"\\n    );\\n    require(\\n      value > 0,\\n      \\\"ERC20Token: cannot mint 0 value\\\"\\n    );\\n\\n    balances[owner] = balances[owner].add(value);\\n    totalSupply = totalSupply.add(value);\\n\\n    emit Transfer(address(0), owner, value);\\n  }\\n\\n  function _burn(\\n    address owner,\\n    uint256 value\\n  )\\n    virtual\\n    internal\\n  {\\n    require(\\n      owner != address(0),\\n      \\\"ERC20Token: cannot burn from 0x0 address\\\"\\n    );\\n\\n    balances[owner] = balances[owner].sub(\\n      value,\\n      \\\"ERC20Token: burn value exceeds balance\\\"\\n    );\\n\\n    totalSupply = totalSupply.sub(value);\\n\\n    emit Transfer(owner, address(0), value);\\n  }\\n\\n  // internal functions (views)\\n\\n  function _getSender()\\n    virtual\\n    internal\\n    view\\n    returns (address)\\n  {\\n    return msg.sender;\\n  }\\n}\\n\",\"keccak256\":\"0x6f2b0bd08da549c6c1f5ceee85766832d587dde62c56bebc3a14bd9ea407e03d\",\"license\":\"MIT\"},\"src/external/ExternalAccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/libs/BlockLib.sol\\\";\\n\\n\\n/**\\n * @title External account registry\\n *\\n * @notice Global registry for keys and external (outside of the platform) contract based wallets\\n *\\n * @dev An account can call the registry to add (`addAccountOwner`) or remove (`removeAccountOwner`) its own owners.\\n * When the owner has been added, information about that fact will live in the registry forever.\\n * Removing an owner only affects the future blocks (until the owner is re-added).\\n *\\n * Given the fact, there is no way to sign the data using a contract based wallet,\\n * we created a registry to store signed by the key wallet proofs.\\n * ERC-1271 allows removing a signer after the signature was created. Thus store the signature for the later use\\n * doesn't guarantee the signer is still has access to that smart account.\\n * Because of that, the ERC1271's `isValidSignature()` cannot be used in e.g. `PaymentRegistry`.*\\n *\\n * An account can call the registry to add (`addAccountProof`) or remove (`removeAccountProof`) proof hash.\\n * When the proof has been added, information about that fact will live in the registry forever.\\n * Removing a proof only affects the future blocks (until the proof is re-added).\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract ExternalAccountRegistry {\\n  using BlockLib for BlockLib.BlockRelated;\\n\\n  struct Account {\\n    mapping(address => BlockLib.BlockRelated) owners;\\n    mapping(bytes32 => BlockLib.BlockRelated) proofs;\\n  }\\n\\n  mapping(address => Account) private accounts;\\n\\n  // events\\n\\n  /**\\n   * @dev Emitted when the new owner is added\\n   * @param account account address\\n   * @param owner owner address\\n   */\\n  event AccountOwnerAdded(\\n    address account,\\n    address owner\\n  );\\n\\n  /**\\n   * @dev Emitted when the existing owner is removed\\n   * @param account account address\\n   * @param owner owner address\\n   */\\n  event AccountOwnerRemoved(\\n    address account,\\n    address owner\\n  );\\n\\n  /**\\n   * @dev Emitted when the new proof is added\\n   * @param account account address\\n   * @param hash proof hash\\n   */\\n  event AccountProofAdded(\\n    address account,\\n    bytes32 hash\\n  );\\n\\n  /**\\n   * @dev Emitted when the existing proof is removed\\n   * @param account account address\\n   * @param hash proof hash\\n   */\\n  event AccountProofRemoved(\\n    address account,\\n    bytes32 hash\\n  );\\n\\n  // external functions\\n\\n  /**\\n   * @notice Adds a new account owner\\n   * @param owner owner address\\n   */\\n  function addAccountOwner(\\n    address owner\\n  )\\n    external\\n  {\\n    require(\\n      owner != address(0),\\n      \\\"ExternalAccountRegistry: cannot add 0x0 owner\\\"\\n    );\\n\\n    require(\\n      !accounts[msg.sender].owners[owner].verifyAtCurrentBlock(),\\n      \\\"ExternalAccountRegistry: owner already exists\\\"\\n    );\\n\\n    accounts[msg.sender].owners[owner].added = true;\\n    accounts[msg.sender].owners[owner].removedAtBlockNumber = 0;\\n\\n    emit AccountOwnerAdded(\\n      msg.sender,\\n      owner\\n    );\\n  }\\n\\n  /**\\n   * @notice Removes existing account owner\\n   * @param owner owner address\\n   */\\n  function removeAccountOwner(\\n    address owner\\n  )\\n    external\\n  {\\n    require(\\n      accounts[msg.sender].owners[owner].verifyAtCurrentBlock(),\\n      \\\"ExternalAccountRegistry: owner doesn't exist\\\"\\n    );\\n\\n    accounts[msg.sender].owners[owner].removedAtBlockNumber = block.number;\\n\\n    emit AccountOwnerRemoved(\\n      msg.sender,\\n      owner\\n    );\\n  }\\n\\n  /**\\n   * @notice Adds a new account proof\\n   * @param hash proof hash\\n   */\\n  function addAccountProof(\\n    bytes32 hash\\n  )\\n    external\\n  {\\n    require(\\n      !accounts[msg.sender].proofs[hash].verifyAtCurrentBlock(),\\n      \\\"ExternalAccountRegistry: proof already exists\\\"\\n    );\\n\\n    accounts[msg.sender].proofs[hash].added = true;\\n    accounts[msg.sender].proofs[hash].removedAtBlockNumber = 0;\\n\\n    emit AccountProofAdded(\\n      msg.sender,\\n      hash\\n    );\\n  }\\n\\n  /**\\n   * @notice Removes existing account proof\\n   * @param hash proof hash\\n   */\\n  function removeAccountProof(\\n    bytes32 hash\\n  )\\n    external\\n  {\\n    require(\\n      accounts[msg.sender].proofs[hash].verifyAtCurrentBlock(),\\n      \\\"ExternalAccountRegistry: proof doesn't exist\\\"\\n    );\\n\\n    accounts[msg.sender].proofs[hash].removedAtBlockNumber = block.number;\\n\\n    emit AccountProofRemoved(\\n      msg.sender,\\n      hash\\n    );\\n  }\\n\\n  // external functions (views)\\n\\n  /**\\n   * @notice Verifies the owner of the account at current block\\n   * @param account account address\\n   * @param owner owner address\\n   * @return true on correct account owner\\n   */\\n  function verifyAccountOwner(\\n    address account,\\n    address owner\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return accounts[account].owners[owner].verifyAtCurrentBlock();\\n  }\\n\\n  /**\\n   * @notice Verifies the owner of the account at specific block\\n   * @param account account address\\n   * @param owner owner address\\n   * @param blockNumber block number to verify\\n   * @return true on correct account owner\\n   */\\n  function verifyAccountOwnerAtBlock(\\n    address account,\\n    address owner,\\n    uint256 blockNumber\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return accounts[account].owners[owner].verifyAtBlock(blockNumber);\\n  }\\n\\n  /**\\n   * @notice Verifies the proof of the account at current block\\n   * @param account account address\\n   * @param hash proof hash\\n   * @return true on correct account proof\\n   */\\n  function verifyAccountProof(\\n    address account,\\n    bytes32 hash\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return accounts[account].proofs[hash].verifyAtCurrentBlock();\\n  }\\n\\n  /**\\n   * @notice Verifies the proof of the account at specific block\\n   * @param account account address\\n   * @param hash proof hash\\n   * @param blockNumber block number to verify\\n   * @return true on correct account proof\\n   */\\n  function verifyAccountProofAtBlock(\\n    address account,\\n    bytes32 hash,\\n    uint256 blockNumber\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return accounts[account].proofs[hash].verifyAtBlock(blockNumber);\\n  }\\n}\\n\",\"keccak256\":\"0x8067b1fae41b73949f8d871a835533cbdd94b9ca3faa93b91f595c37e632ccdb\",\"license\":\"MIT\"},\"src/gateway/GatewayRecipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/libs/BytesLib.sol\\\";\\n\\n\\n/**\\n * @title Gateway recipient\\n *\\n * @notice Gateway target contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract GatewayRecipient {\\n  using BytesLib for bytes;\\n\\n  address public gateway;\\n\\n  /**\\n   * @dev internal constructor\\n   */\\n  constructor() internal {}\\n\\n  // internal functions\\n\\n  /**\\n   * @notice Initializes `GatewayRecipient` contract\\n   * @param gateway_ `Gateway` contract address\\n   */\\n  function _initializeGatewayRecipient(\\n    address gateway_\\n  )\\n    internal\\n  {\\n    gateway = gateway_;\\n  }\\n\\n  // internal functions (views)\\n\\n  /**\\n   * @notice Gets gateway context account\\n   * @return context account address\\n   */\\n  function _getContextAccount()\\n    internal\\n    view\\n    returns (address)\\n  {\\n    return _getContextAddress(40);\\n  }\\n\\n  /**\\n   * @notice Gets gateway context sender\\n   * @return context sender address\\n   */\\n  function _getContextSender()\\n    internal\\n    view\\n    returns (address)\\n  {\\n    return _getContextAddress(20);\\n  }\\n\\n  /**\\n   * @notice Gets gateway context data\\n   * @return context data\\n   */\\n  function _getContextData()\\n    internal\\n    view\\n    returns (bytes calldata)\\n  {\\n    bytes calldata result;\\n\\n    if (_isGatewaySender()) {\\n      result = msg.data[:msg.data.length - 40];\\n    } else {\\n      result = msg.data;\\n    }\\n\\n    return result;\\n  }\\n\\n  // private functions (views)\\n\\n  function _getContextAddress(\\n    uint256 offset\\n  )\\n    private\\n    view\\n    returns (address)\\n  {\\n    address result = address(0);\\n\\n    if (_isGatewaySender()) {\\n      uint from = msg.data.length - offset;\\n      result = bytes(msg.data[from:from + 20]).toAddress();\\n    } else {\\n      result = msg.sender;\\n    }\\n\\n    return result;\\n  }\\n\\n  function _isGatewaySender()\\n    private\\n    view\\n    returns (bool)\\n  {\\n    bool result;\\n\\n    if (msg.sender == gateway) {\\n      require(\\n        msg.data.length >= 44,\\n        \\\"GatewayRecipient: invalid msg.data\\\"\\n      );\\n\\n      result = true;\\n    }\\n\\n    return result;\\n  }\\n}\\n\",\"keccak256\":\"0xe3fd29479d748d67360c61a9cbaafc66eaca25f476e59a45e842472bcf5233fc\",\"license\":\"MIT\"},\"src/payments/PaymentDepositAccount.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/access/Controlled.sol\\\";\\n\\n\\n/**\\n * @title Payment deposit account\\n *\\n * @dev Simple account contract with only one method - `executeTransaction`\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract PaymentDepositAccount is Controlled {\\n  /**\\n   * @dev Public constructor\\n   */\\n  constructor() public payable Controlled() {}\\n\\n  /**\\n   * @notice Allow receives\\n   */\\n  receive()\\n    external\\n    payable\\n  {\\n    //\\n  }\\n\\n  // external functions\\n\\n  /**\\n   * @notice Executes transaction\\n   * @param to to address\\n   * @param value value\\n   * @param data data\\n   * @return transaction result\\n   */\\n  function executeTransaction(\\n    address to,\\n    uint256 value,\\n    bytes calldata data\\n  )\\n    external\\n    onlyController\\n    returns (bytes memory)\\n  {\\n    bytes memory result;\\n    bool succeeded;\\n\\n    // solhint-disable-next-line avoid-call-value, avoid-low-level-calls\\n    (succeeded, result) = payable(to).call{value: value}(data);\\n\\n    require(\\n      succeeded,\\n      \\\"Account: transaction reverted\\\"\\n    );\\n\\n    return result;\\n  }\\n}\\n\",\"keccak256\":\"0xeac8f6b6b1cb749d72d8d5160a622fe4100a1e18a73635e51ce30e6f11029ad1\",\"license\":\"MIT\"},\"src/payments/PaymentRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../common/access/Guarded.sol\\\";\\nimport \\\"../common/libs/ECDSALib.sol\\\";\\nimport \\\"../common/libs/SafeMathLib.sol\\\";\\nimport \\\"../common/lifecycle/Initializable.sol\\\";\\nimport \\\"../common/signature/SignatureValidator.sol\\\";\\nimport \\\"../common/token/ERC20Token.sol\\\";\\nimport \\\"../external/ExternalAccountRegistry.sol\\\";\\nimport \\\"../personal/PersonalAccountRegistry.sol\\\";\\nimport \\\"../gateway/GatewayRecipient.sol\\\";\\nimport \\\"./PaymentDepositAccount.sol\\\";\\n\\n\\n/**\\n * @title Payment registry\\n *\\n * @notice A registry for payment and payment channels\\n *\\n * @dev the `DepositExit` process can be used in a case operator (guardian) couldn't sign commit / withdrawal message.\\n * Process will be rejected when any of senders channels will be committed.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract PaymentRegistry is Guarded, Initializable, SignatureValidator, GatewayRecipient {\\n  using ECDSALib for bytes32;\\n  using SafeMathLib for uint256;\\n\\n  struct Deposit {\\n    address account;\\n    mapping(address => uint256) withdrawnAmount;\\n    mapping(address => uint256) exitLockedUntil;\\n  }\\n\\n  struct PaymentChannel {\\n    uint256 committedAmount;\\n  }\\n\\n  struct DepositWithdrawal {\\n    address owner;\\n    address token;\\n    uint256 amount;\\n  }\\n\\n  struct PaymentChannelCommit {\\n    address sender;\\n    address recipient;\\n    address token;\\n    bytes32 uid;\\n    uint256 blockNumber;\\n    uint256 amount;\\n  }\\n\\n  uint256 private constant DEFAULT_DEPOSIT_EXIT_LOCK_PERIOD = 28 days;\\n\\n  bytes32 private constant HASH_PREFIX_DEPOSIT_WITHDRAWAL = keccak256(\\n    \\\"DepositWithdrawal(address owner,address token,uint256 amount)\\\"\\n  );\\n  bytes32 private constant HASH_PREFIX_PAYMENT_CHANNEL_COMMIT = keccak256(\\n    \\\"PaymentChannelCommit(address sender,address recipient,address token,bytes32 uid,uint256 blockNumber,uint256 amount)\\\"\\n  );\\n\\n  ExternalAccountRegistry public externalAccountRegistry;\\n  PersonalAccountRegistry public personalAccountRegistry;\\n\\n  uint256 public depositExitLockPeriod;\\n\\n  mapping(address => Deposit) private deposits;\\n  mapping(bytes32 => PaymentChannel) private paymentChannels;\\n\\n  // events\\n\\n  /**\\n   * @dev Emitted when the deposit account is deployed\\n   * @param depositAccount deposit account address\\n   * @param owner owner address\\n   */\\n  event DepositAccountDeployed(\\n    address depositAccount,\\n    address owner\\n  );\\n\\n  /**\\n   * @dev Emitted when the deposit exist is requested\\n   * @param depositAccount deposit account address\\n   * @param owner owner address\\n   * @param token token address\\n   * @param lockedUntil deposit exist locked util time\\n   */\\n  event DepositExitRequested(\\n    address depositAccount,\\n    address owner,\\n    address token,\\n    uint256 lockedUntil\\n  );\\n\\n  /**\\n   * @dev Emitted when the deposit exist is completed\\n   * @param depositAccount deposit account address\\n   * @param owner owner address\\n   * @param token token address\\n   * @param amount deposit exist amount\\n   */\\n  event DepositExitCompleted(\\n    address depositAccount,\\n    address owner,\\n    address token,\\n    uint256 amount\\n  );\\n\\n  /**\\n   * @dev Emitted when the deposit exist is rejected\\n   * @param depositAccount deposit account address\\n   * @param owner owner address\\n   * @param token token address\\n   */\\n  event DepositExitRejected(\\n    address depositAccount,\\n    address owner,\\n    address token\\n  );\\n\\n  /**\\n   * @dev Emitted when the deposit has been withdrawn\\n   * @param depositAccount deposit account address\\n   * @param owner owner address\\n   * @param token token address\\n   * @param amount withdrawn amount\\n   */\\n  event DepositWithdrawn(\\n    address depositAccount,\\n    address owner,\\n    address token,\\n    uint256 amount\\n  );\\n\\n  /**\\n   * @dev Emitted when the payment channel has been committed\\n   * @param hash channel hash\\n   * @param sender sender address\\n   * @param recipient recipient address\\n   * @param token token address\\n   * @param uid unique channel id\\n   * @param amount committed amount\\n   */\\n  event PaymentChannelCommitted(\\n    bytes32 hash,\\n    address sender,\\n    address recipient,\\n    address token,\\n    bytes32 uid,\\n    uint256 amount\\n  );\\n\\n  /**\\n   * @dev Emitted when the payment has been withdrawn\\n   * @param channelHash channel hash\\n   * @param value payment value\\n   */\\n  event PaymentWithdrawn(\\n    bytes32 channelHash,\\n    uint256 value\\n  );\\n\\n  /**\\n   * @dev Emitted when the payment has been deposited\\n   * @param channelHash channel hash\\n   * @param value payment value\\n   */\\n  event PaymentDeposited(\\n    bytes32 channelHash,\\n    uint256 value\\n  );\\n\\n  /**\\n   * @dev Emitted when the payment has been withdrawn and deposited (split)\\n   * @param channelHash channel hash\\n   * @param totalValue payment total value\\n   * @param depositValue payment deposited value\\n   */\\n  event PaymentSplit(\\n    bytes32 channelHash,\\n    uint256 totalValue,\\n    uint256 depositValue\\n  );\\n\\n  /**\\n   * @dev Public constructor\\n   */\\n  constructor() public Initializable() SignatureValidator() {}\\n\\n  // external functions\\n\\n  /**\\n   * @notice Initialize `PaymentRegistry` contract\\n   * @param externalAccountRegistry_ `ExternalAccountRegistry` contract address\\n   * @param personalAccountRegistry_ `PersonalAccountRegistry` contract address\\n   * @param depositExitLockPeriod_ deposit exit lock period\\n   * @param guardians_ array of guardians addresses\\n   * @param gateway_ `Gateway` contract address\\n   */\\n  function initialize(\\n    ExternalAccountRegistry externalAccountRegistry_,\\n    PersonalAccountRegistry personalAccountRegistry_,\\n    uint256 depositExitLockPeriod_,\\n    address[] calldata guardians_,\\n    address gateway_\\n  )\\n    external\\n    onlyInitializer\\n  {\\n    externalAccountRegistry = externalAccountRegistry_;\\n    personalAccountRegistry = personalAccountRegistry_;\\n\\n    if (depositExitLockPeriod_ == 0) {\\n      depositExitLockPeriod = DEFAULT_DEPOSIT_EXIT_LOCK_PERIOD;\\n    } else {\\n      depositExitLockPeriod = depositExitLockPeriod_;\\n    }\\n\\n    // Guarded\\n    _initializeGuarded(guardians_);\\n\\n    // GatewayRecipient\\n    _initializeGatewayRecipient(gateway_);\\n  }\\n\\n  /**\\n   * @notice Deploys deposit account\\n   * @param owner owner address\\n   */\\n  function deployDepositAccount(\\n    address owner\\n  )\\n    external\\n  {\\n    _deployDepositAccount(owner);\\n  }\\n\\n  /**\\n   * @notice Requests deposit exit\\n   * @param token token address\\n   */\\n  function requestDepositExit(\\n    address token\\n  )\\n    external\\n  {\\n    address owner = _getContextAccount();\\n    uint256 lockedUntil = deposits[owner].exitLockedUntil[token];\\n\\n    require(\\n      lockedUntil == 0,\\n      \\\"PaymentRegistry: deposit exit already requested\\\"\\n    );\\n\\n    _deployDepositAccount(owner);\\n\\n    // solhint-disable-next-line not-rely-on-time\\n    lockedUntil = now.add(depositExitLockPeriod);\\n\\n    deposits[owner].exitLockedUntil[token] = lockedUntil;\\n\\n    emit DepositExitRequested(\\n      deposits[owner].account,\\n      owner,\\n      token,\\n      lockedUntil\\n    );\\n  }\\n\\n  /**\\n   * @notice Processes deposit exit\\n   * @param token token address\\n   */\\n  function processDepositExit(\\n    address token\\n  )\\n    external\\n  {\\n    address owner = _getContextAccount();\\n    uint256 lockedUntil = deposits[owner].exitLockedUntil[token];\\n\\n    require(\\n      lockedUntil != 0,\\n      \\\"PaymentRegistry: deposit exit not requested\\\"\\n    );\\n\\n    require(\\n      // solhint-disable-next-line not-rely-on-time\\n      lockedUntil <= now,\\n      \\\"PaymentRegistry: deposit exit locked\\\"\\n    );\\n\\n    deposits[owner].exitLockedUntil[token] = 0;\\n\\n    address depositAccount = deposits[owner].account;\\n    uint256 depositValue;\\n\\n    if (token == address(0)) {\\n      depositValue = depositAccount.balance;\\n    } else {\\n      depositValue = ERC20Token(token).balanceOf(depositAccount);\\n    }\\n\\n    _transferFromDeposit(\\n      depositAccount,\\n      owner,\\n      token,\\n      depositValue\\n    );\\n\\n    emit DepositExitCompleted(\\n      depositAccount,\\n      owner,\\n      token,\\n      depositValue\\n    );\\n  }\\n\\n  /**\\n   * @notice Withdraws deposit\\n   * @param token token address\\n   * @param amount amount to withdraw\\n   * @param guardianSignature guardian signature\\n   */\\n  function withdrawDeposit(\\n    address token,\\n    uint256 amount,\\n    bytes calldata guardianSignature\\n  )\\n    external\\n  {\\n    address owner = _getContextAccount();\\n    uint256 value = amount.sub(deposits[owner].withdrawnAmount[token]);\\n\\n    require(\\n      value > 0,\\n      \\\"PaymentRegistry: invalid amount\\\"\\n    );\\n\\n    bytes32 messageHash = _hashDepositWithdrawal(\\n      owner,\\n      token,\\n      amount\\n    );\\n\\n    require(\\n      _verifyGuardianSignature(messageHash, guardianSignature),\\n      \\\"PaymentRegistry: invalid guardian signature\\\"\\n    );\\n\\n    deposits[owner].withdrawnAmount[token] = amount;\\n\\n    _verifyDepositExitOrDeployAccount(owner, token);\\n\\n    _transferFromDeposit(\\n      deposits[owner].account,\\n      owner,\\n      token,\\n      value\\n    );\\n\\n    emit DepositWithdrawn(\\n      deposits[owner].account,\\n      owner,\\n      token,\\n      amount\\n    );\\n  }\\n\\n  /**\\n   * @notice Commits payment channel and withdraw payment\\n   * @param sender sender address\\n   * @param token token address\\n   * @param uid unique channel id\\n   * @param blockNumber block number\\n   * @param amount amount to commit\\n   * @param senderSignature sender signature\\n   * @param guardianSignature guardian signature\\n   */\\n  function commitPaymentChannelAndWithdraw(\\n    address sender,\\n    address token,\\n    bytes32 uid,\\n    uint256 blockNumber,\\n    uint256 amount,\\n    bytes calldata senderSignature,\\n    bytes calldata guardianSignature\\n  )\\n    external\\n  {\\n    address recipient = _getContextAccount();\\n\\n    (bytes32 hash, address depositAccount, uint256 paymentValue) = _commitPaymentChannel(\\n      sender,\\n      recipient,\\n      token,\\n      uid,\\n      blockNumber,\\n      amount,\\n      senderSignature,\\n      guardianSignature\\n    );\\n\\n    _transferFromDeposit(\\n      depositAccount,\\n      recipient,\\n      token,\\n      paymentValue\\n    );\\n\\n    emit PaymentWithdrawn(hash, paymentValue);\\n  }\\n\\n  /**\\n   * @notice Commits payment channel and deposit payment\\n   * @param sender sender address\\n   * @param token token address\\n   * @param uid unique channel id\\n   * @param blockNumber block number\\n   * @param amount amount to commit\\n   * @param senderSignature sender signature\\n   * @param guardianSignature guardian signature\\n   */\\n  function commitPaymentChannelAndDeposit(\\n    address sender,\\n    address token,\\n    bytes32 uid,\\n    uint256 blockNumber,\\n    uint256 amount,\\n    bytes calldata senderSignature,\\n    bytes calldata guardianSignature\\n  )\\n    external\\n  {\\n    address recipient = _getContextAccount();\\n\\n    (bytes32 hash, address depositAccount, uint256 paymentValue) = _commitPaymentChannel(\\n      sender,\\n      recipient,\\n      token,\\n      uid,\\n      blockNumber,\\n      amount,\\n      senderSignature,\\n      guardianSignature\\n    );\\n\\n    _transferFromDeposit(\\n      depositAccount,\\n      _computeDepositAccountAddress(recipient),\\n      token,\\n      paymentValue\\n    );\\n\\n    emit PaymentDeposited(hash, paymentValue);\\n  }\\n\\n  /**\\n   * @notice Commits payment channel, withdraws and deposits (split) payment\\n   * @param sender sender address\\n   * @param token token address\\n   * @param uid unique channel id\\n   * @param blockNumber block number\\n   * @param amount amount to commit\\n   * @param depositPaymentValue amount to deposit\\n   * @param senderSignature sender signature\\n   * @param guardianSignature guardian signature\\n   */\\n  function commitPaymentChannelAndSplit(\\n    address sender,\\n    address token,\\n    bytes32 uid,\\n    uint256 blockNumber,\\n    uint256 amount,\\n    uint256 depositPaymentValue,\\n    bytes calldata senderSignature,\\n    bytes calldata guardianSignature\\n  )\\n    external\\n  {\\n    address recipient = _getContextAccount();\\n\\n    (bytes32 hash, address depositAccount, uint256 paymentValue) = _commitPaymentChannel(\\n      sender,\\n      recipient,\\n      token,\\n      uid,\\n      blockNumber,\\n      amount,\\n      senderSignature,\\n      guardianSignature\\n    );\\n\\n    _transferSplitFromDeposit(\\n      depositAccount,\\n      recipient,\\n      token,\\n      paymentValue,\\n      depositPaymentValue\\n    );\\n\\n    emit PaymentSplit(hash, paymentValue, depositPaymentValue);\\n  }\\n\\n  // external functions (views)\\n\\n  /**\\n   * @notice Computes deposit account address\\n   * @param owner owner address\\n   * @return deposit account address\\n   */\\n  function computeDepositAccountAddress(\\n    address owner\\n  )\\n    external\\n    view\\n    returns (address)\\n  {\\n    return _computeDepositAccountAddress(owner);\\n  }\\n\\n  /**\\n   * @notice Checks if deposit account is deployed\\n   * @param owner owner address\\n   * @return true when deposit account is deployed\\n   */\\n  function isDepositAccountDeployed(\\n    address owner\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return deposits[owner].account != address(0);\\n  }\\n\\n  /**\\n   * @notice Gets deposit exit locked until time\\n   * @param owner owner address\\n   * @param token token address\\n   * @return locked until time\\n   */\\n  function getDepositExitLockedUntil(\\n    address owner,\\n    address token\\n  )\\n    external\\n    view\\n    returns (uint256)\\n  {\\n    return deposits[owner].exitLockedUntil[token];\\n  }\\n\\n  /**\\n   * @notice Gets deposit withdrawn amount\\n   * @param owner owner address\\n   * @param token token address\\n   * @return withdrawn amount\\n   */\\n  function getDepositWithdrawnAmount(\\n    address owner,\\n    address token\\n  )\\n    external\\n    view\\n    returns (uint256)\\n  {\\n    return deposits[owner].withdrawnAmount[token];\\n  }\\n\\n  /**\\n   * @notice Gets payment channel committed amount\\n   * @param hash payment channel hash\\n   * @return committed amount\\n   */\\n  function getPaymentChannelCommittedAmount(\\n    bytes32 hash\\n  )\\n    external\\n    view\\n    returns (uint256)\\n  {\\n    return paymentChannels[hash].committedAmount;\\n  }\\n\\n  // external functions (pure)\\n\\n  /**\\n   * @notice Computes payment channel hash\\n   * @param sender sender address\\n   * @param recipient recipient address\\n   * @param token token address\\n   * @param uid unique channel id\\n   * @return hash\\n   */\\n  function computePaymentChannelHash(\\n    address sender,\\n    address recipient,\\n    address token,\\n    bytes32 uid\\n  )\\n    external\\n    pure\\n    returns (bytes32)\\n  {\\n    return _computePaymentChannelHash(\\n      sender,\\n      recipient,\\n      token,\\n      uid\\n    );\\n  }\\n\\n  // public functions (views)\\n\\n  /**\\n   * @notice Hashes `DepositWithdrawal` message payload\\n   * @param depositWithdrawal struct\\n   * @return hash\\n   */\\n  function hashDepositWithdrawal(\\n    DepositWithdrawal memory depositWithdrawal\\n  )\\n    public\\n    view\\n    returns (bytes32)\\n  {\\n    return _hashDepositWithdrawal(\\n      depositWithdrawal.owner,\\n      depositWithdrawal.token,\\n      depositWithdrawal.amount\\n    );\\n  }\\n\\n  /**\\n   * @notice Hashes `PaymentChannelCommit` message payload\\n   * @param paymentChannelCommit struct\\n   * @return hash\\n   */\\n  function hashPaymentChannelCommit(\\n    PaymentChannelCommit memory paymentChannelCommit\\n  )\\n    public\\n    view\\n    returns (bytes32)\\n  {\\n    return _hashPaymentChannelCommit(\\n      paymentChannelCommit.sender,\\n      paymentChannelCommit.recipient,\\n      paymentChannelCommit.token,\\n      paymentChannelCommit.uid,\\n      paymentChannelCommit.blockNumber,\\n      paymentChannelCommit.amount\\n    );\\n  }\\n\\n  // private functions\\n\\n  function _deployDepositAccount(\\n    address owner\\n  )\\n    private\\n  {\\n    if (deposits[owner].account == address(0)) {\\n      bytes32 salt = keccak256(\\n        abi.encodePacked(\\n          owner\\n        )\\n      );\\n\\n      deposits[owner].account = address(new PaymentDepositAccount{salt: salt}());\\n\\n      emit DepositAccountDeployed(\\n        deposits[owner].account,\\n        owner\\n      );\\n    }\\n  }\\n\\n  function _verifyDepositExitOrDeployAccount(\\n    address owner,\\n    address token\\n  )\\n    private\\n  {\\n    if (deposits[owner].exitLockedUntil[token] > 0) {\\n      deposits[owner].exitLockedUntil[token] = 0;\\n\\n      emit DepositExitRejected(\\n        deposits[owner].account,\\n        owner,\\n        token\\n      );\\n    } else {\\n      _deployDepositAccount(owner);\\n    }\\n  }\\n\\n  function _commitPaymentChannel(\\n    address sender,\\n    address recipient,\\n    address token,\\n    bytes32 uid,\\n    uint256 blockNumber,\\n    uint256 amount,\\n    bytes memory senderSignature,\\n    bytes memory guardianSignature\\n  )\\n    private\\n    returns (bytes32 hash, address depositAccount, uint256 paymentValue)\\n  {\\n    bytes32 messageHash = _hashPaymentChannelCommit(\\n      sender,\\n      recipient,\\n      token,\\n      uid,\\n      blockNumber,\\n      amount\\n    );\\n\\n    if (senderSignature.length == 0) {\\n      require(\\n        externalAccountRegistry.verifyAccountProofAtBlock(sender, messageHash, blockNumber),\\n        \\\"PaymentRegistry: invalid guardian signature\\\"\\n      );\\n    } else {\\n      address signer = messageHash.recoverAddress(senderSignature);\\n\\n      if (sender != signer) {\\n        require(\\n          personalAccountRegistry.verifyAccountOwnerAtBlock(sender, signer, blockNumber) ||\\n          externalAccountRegistry.verifyAccountOwnerAtBlock(sender, signer, blockNumber),\\n          \\\"PaymentRegistry: invalid sender signature\\\"\\n        );\\n      }\\n    }\\n\\n    require(\\n      _verifyGuardianSignature(messageHash, guardianSignature),\\n      \\\"PaymentRegistry: invalid guardian signature\\\"\\n    );\\n\\n    hash = _computePaymentChannelHash(\\n      sender,\\n      recipient,\\n      token,\\n      uid\\n    );\\n\\n    /// @dev calc payment value\\n    paymentValue = amount.sub(paymentChannels[hash].committedAmount);\\n\\n    require(\\n      paymentValue != 0,\\n      \\\"PaymentRegistry: invalid payment value\\\"\\n    );\\n\\n    paymentChannels[hash].committedAmount = amount;\\n\\n    _verifyDepositExitOrDeployAccount(sender, token);\\n\\n    depositAccount = deposits[sender].account;\\n\\n    emit PaymentChannelCommitted(\\n      hash,\\n      sender,\\n      recipient,\\n      token,\\n      uid,\\n      amount\\n    );\\n\\n    return (hash, depositAccount, paymentValue);\\n  }\\n\\n  function _transferFromDeposit(\\n    address depositAccount,\\n    address to,\\n    address token,\\n    uint256 value\\n  )\\n    private\\n  {\\n    if (token == address(0)) {\\n      PaymentDepositAccount(payable(depositAccount)).executeTransaction(\\n        to,\\n        value,\\n        new bytes(0)\\n      );\\n    } else {\\n      bytes memory response = PaymentDepositAccount(payable(depositAccount)).executeTransaction(\\n        token,\\n        0,\\n        abi.encodeWithSelector(\\n          ERC20Token(token).transfer.selector,\\n          to,\\n          value\\n        )\\n      );\\n\\n      if (response.length > 0) {\\n        require(\\n          abi.decode(response, (bool)),\\n          \\\"PaymentRegistry: ERC20Token transfer reverted\\\"\\n        );\\n      }\\n    }\\n  }\\n\\n  function _transferSplitFromDeposit(\\n    address depositAccount,\\n    address to,\\n    address token,\\n    uint256 paymentValue,\\n    uint256 depositValue\\n  )\\n    private\\n  {\\n    require(\\n      depositValue > 0,\\n      \\\"PaymentRegistry: invalid deposit value\\\"\\n    );\\n\\n    uint256 withdrawValue = paymentValue.sub(depositValue);\\n\\n    require(\\n      withdrawValue > 0,\\n      \\\"PaymentRegistry: invalid withdraw value\\\"\\n    );\\n\\n    _transferFromDeposit(\\n      depositAccount,\\n      to,\\n      token,\\n      withdrawValue\\n    );\\n\\n    _transferFromDeposit(\\n      depositAccount,\\n      _computeDepositAccountAddress(to),\\n      token,\\n      depositValue\\n    );\\n  }\\n\\n  // private functions (views)\\n\\n  function _computeDepositAccountAddress(\\n    address owner\\n  )\\n    private\\n    view\\n    returns (address)\\n  {\\n    bytes32 salt = keccak256(\\n      abi.encodePacked(\\n        owner\\n      )\\n    );\\n\\n    bytes memory creationCode = type(PaymentDepositAccount).creationCode;\\n\\n    bytes32 data = keccak256(\\n      abi.encodePacked(\\n        bytes1(0xff),\\n        address(this),\\n        salt,\\n        keccak256(creationCode)\\n      )\\n    );\\n\\n    return address(uint160(uint256(data)));\\n  }\\n\\n  function _hashDepositWithdrawal(\\n    address owner,\\n    address token,\\n    uint256 amount\\n  )\\n    private\\n    view\\n    returns (bytes32)\\n  {\\n    return _hashMessagePayload(HASH_PREFIX_DEPOSIT_WITHDRAWAL, abi.encodePacked(\\n      owner,\\n      token,\\n      amount\\n    ));\\n  }\\n\\n  function _hashPaymentChannelCommit(\\n    address sender,\\n    address recipient,\\n    address token,\\n    bytes32 uid,\\n    uint256 blockNumber,\\n    uint256 amount\\n  )\\n    private\\n    view\\n    returns (bytes32)\\n  {\\n    return _hashMessagePayload(HASH_PREFIX_PAYMENT_CHANNEL_COMMIT, abi.encodePacked(\\n      sender,\\n      recipient,\\n      token,\\n      uid,\\n      blockNumber,\\n      amount\\n    ));\\n  }\\n\\n  // private functions (pure)\\n\\n  function _computePaymentChannelHash(\\n    address sender,\\n    address recipient,\\n    address token,\\n    bytes32 uid\\n  )\\n    private\\n    pure\\n    returns (bytes32)\\n  {\\n    return keccak256(\\n      abi.encodePacked(\\n        sender,\\n        recipient,\\n        token,\\n        uid\\n      )\\n    );\\n  }\\n}\\n\",\"keccak256\":\"0x84d3f908a35ba0f9dcc3e37808b42cdad0b81285ec006c96d25302d8dffa2704\",\"license\":\"MIT\"},\"src/personal/PersonalAccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/access/Guarded.sol\\\";\\nimport \\\"../common/account/AccountController.sol\\\";\\nimport \\\"../common/account/AccountRegistry.sol\\\";\\nimport \\\"../common/libs/BlockLib.sol\\\";\\nimport \\\"../common/libs/ECDSALib.sol\\\";\\nimport \\\"../common/libs/ECDSAExtendedLib.sol\\\";\\nimport \\\"../common/libs/SafeMathLib.sol\\\";\\nimport \\\"../common/lifecycle/Initializable.sol\\\";\\nimport \\\"../common/token/ERC20Token.sol\\\";\\nimport \\\"../gateway/GatewayRecipient.sol\\\";\\n\\n\\n/**\\n * @title Personal account registry\\n *\\n * @notice A registry for personal (controlled by owners) accounts\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract PersonalAccountRegistry is Guarded, AccountController, AccountRegistry, Initializable, GatewayRecipient {\\n  using BlockLib for BlockLib.BlockRelated;\\n  using SafeMathLib for uint256;\\n  using ECDSALib for bytes32;\\n  using ECDSAExtendedLib for bytes;\\n\\n  struct Account {\\n    bool deployed;\\n    bytes32 salt;\\n    mapping(address => BlockLib.BlockRelated) owners;\\n  }\\n\\n  mapping(address => Account) private accounts;\\n\\n  // events\\n\\n  /**\\n   * @dev Emitted when the new owner is added\\n   * @param account account address\\n   * @param owner owner address\\n   */\\n  event AccountOwnerAdded(\\n    address account,\\n    address owner\\n  );\\n\\n  /**\\n   * @dev Emitted when the existing owner is removed\\n   * @param account account address\\n   * @param owner owner address\\n   */\\n  event AccountOwnerRemoved(\\n    address account,\\n    address owner\\n  );\\n\\n  /**\\n   * @dev Emitted when the call is refunded\\n   * @param account account address\\n   * @param beneficiary beneficiary address\\n   * @param token token address\\n   * @param value value\\n   */\\n  event AccountCallRefunded(\\n    address account,\\n    address beneficiary,\\n    address token,\\n    uint256 value\\n  );\\n\\n  /**\\n   * @dev Public constructor\\n   */\\n  constructor() public Initializable() {}\\n\\n  // external functions\\n\\n  /**\\n   * @notice Initializes `PersonalAccountRegistry` contract\\n   * @param guardians_ array of guardians addresses\\n   * @param accountImplementation_ account implementation address\\n   * @param gateway_ `Gateway` contract address\\n   */\\n  function initialize(\\n    address[] calldata guardians_,\\n    address accountImplementation_,\\n    address gateway_\\n  )\\n    external\\n    onlyInitializer\\n  {\\n    // Guarded\\n    _initializeGuarded(guardians_);\\n\\n    // AccountController\\n    _initializeAccountController(address(this), accountImplementation_);\\n\\n    // GatewayRecipient\\n    _initializeGatewayRecipient(gateway_);\\n  }\\n\\n  /**\\n   * @notice Upgrades `PersonalAccountRegistry` contract\\n   * @param accountImplementation_ account implementation address\\n   */\\n  function upgrade(\\n    address accountImplementation_\\n  )\\n    external\\n    onlyGuardian\\n  {\\n    _setAccountImplementation(accountImplementation_, true);\\n  }\\n\\n  /**\\n   * @notice Deploys account\\n   * @param account account address\\n   */\\n  function deployAccount(\\n    address account\\n  )\\n    external\\n  {\\n    _verifySender(account);\\n    _deployAccount(account);\\n  }\\n\\n  /**\\n   * @notice Upgrades account\\n   * @param account account address\\n   */\\n  function upgradeAccount(\\n    address account\\n  )\\n    external\\n  {\\n    _verifySender(account);\\n    _upgradeAccount(account, true);\\n  }\\n\\n  /**\\n   * @notice Adds a new account owner\\n   * @param account account address\\n   * @param owner owner address\\n   */\\n  function addAccountOwner(\\n    address account,\\n    address owner\\n  )\\n    external\\n  {\\n    _verifySender(account);\\n\\n    require(\\n      owner != address(0),\\n      \\\"PersonalAccountRegistry: cannot add 0x0 owner\\\"\\n    );\\n\\n    require(\\n      !accounts[account].owners[owner].verifyAtCurrentBlock(),\\n      \\\"PersonalAccountRegistry: owner already exists\\\"\\n    );\\n\\n    accounts[account].owners[owner].added = true;\\n    accounts[account].owners[owner].removedAtBlockNumber = 0;\\n\\n    emit AccountOwnerAdded(\\n      account,\\n      owner\\n    );\\n  }\\n\\n  /**\\n   * @notice Removes the existing account owner\\n   * @param account account address\\n   * @param owner owner address\\n   */\\n  function removeAccountOwner(\\n    address account,\\n    address owner\\n  )\\n    external\\n  {\\n    address sender = _verifySender(account);\\n\\n    require(\\n      owner != sender,\\n      \\\"PersonalAccountRegistry: cannot remove self\\\"\\n    );\\n\\n    require(\\n      accounts[account].owners[owner].verifyAtCurrentBlock(),\\n      \\\"PersonalAccountRegistry: owner doesn't exist\\\"\\n    );\\n\\n    accounts[account].owners[owner].removedAtBlockNumber = block.number;\\n\\n    emit AccountOwnerRemoved(\\n      account,\\n      owner\\n    );\\n  }\\n\\n  /**\\n   * @notice Executes account transaction\\n   * @dev Deploys an account if not deployed yet\\n   * @param account account address\\n   * @param to to address\\n   * @param value value\\n   * @param data data\\n   */\\n  function executeAccountTransaction(\\n    address account,\\n    address to,\\n    uint256 value,\\n    bytes calldata data\\n  )\\n    external\\n  {\\n    _verifySender(account);\\n\\n    _deployAccount(account);\\n\\n    _executeAccountTransaction(\\n      account,\\n      to,\\n      value,\\n      data,\\n      true\\n    );\\n  }\\n\\n  /**\\n   * @notice Refunds account call\\n   * @dev Deploys an account if not deployed yet\\n   * @param account account address\\n   * @param token token address\\n   * @param value value\\n   */\\n  function refundAccountCall(\\n    address account,\\n    address token,\\n    uint256 value\\n  )\\n    external\\n  {\\n    _verifySender(account);\\n\\n    _deployAccount(account);\\n\\n    /* solhint-disable avoid-tx-origin */\\n\\n    if (token == address(0)) {\\n      _executeAccountTransaction(\\n        account,\\n        tx.origin,\\n        value,\\n        new bytes(0),\\n        false\\n      );\\n    } else {\\n      bytes memory response = _executeAccountTransaction(\\n        account,\\n        token,\\n        0,\\n        abi.encodeWithSelector(\\n          ERC20Token(token).transfer.selector,\\n          tx.origin,\\n          value\\n        ),\\n        false\\n      );\\n\\n      if (response.length > 0) {\\n        require(\\n          abi.decode(response, (bool)),\\n          \\\"PersonalAccountRegistry: ERC20Token transfer reverted\\\"\\n        );\\n      }\\n    }\\n\\n    emit AccountCallRefunded(\\n      account,\\n      tx.origin,\\n      token,\\n      value\\n    );\\n\\n    /* solhint-enable avoid-tx-origin */\\n  }\\n\\n  // external functions (views)\\n\\n  /**\\n   * @notice Computes account address\\n   * @param saltOwner salt owner address\\n   * @return account address\\n   */\\n  function computeAccountAddress(\\n    address saltOwner\\n  )\\n    external\\n    view\\n    returns (address)\\n  {\\n    return _computeAccountAddress(saltOwner);\\n  }\\n\\n  /**\\n   * @notice Checks if account is deployed\\n   * @param account account address\\n   * @return true when account is deployed\\n   */\\n  function isAccountDeployed(\\n    address account\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return accounts[account].deployed;\\n  }\\n\\n  /**\\n   * @notice Verifies the owner of the account at the current block\\n   * @param account account address\\n   * @param owner owner address\\n   * @return true on correct account owner\\n   */\\n  function verifyAccountOwner(\\n    address account,\\n    address owner\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return _verifyAccountOwner(account, owner);\\n  }\\n\\n  /**\\n   * @notice Verifies the owner of the account at a specific block\\n   * @param account account address\\n   * @param owner owner address\\n   * @param blockNumber block number to verify\\n   * @return true on correct account owner\\n   */\\n  function verifyAccountOwnerAtBlock(\\n    address account,\\n    address owner,\\n    uint256 blockNumber\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    bool result = false;\\n\\n    if (_verifyAccountOwner(account, owner)) {\\n      result = true;\\n    } else {\\n      result = accounts[account].owners[owner].verifyAtBlock(blockNumber);\\n    }\\n\\n    return result;\\n  }\\n\\n  /**\\n   * @notice Verifies account signature\\n   * @param account account address\\n   * @param messageHash message hash\\n   * @param signature signature\\n   * @return magic hash if valid\\n   */\\n  function isValidAccountSignature(\\n    address account,\\n    bytes32 messageHash,\\n    bytes calldata signature\\n  )\\n    override\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return _verifyAccountOwner(\\n      account,\\n      messageHash.recoverAddress(signature)\\n    );\\n  }\\n\\n  /**\\n   * @notice Verifies account signature\\n   * @param account account address\\n   * @param message message\\n   * @param signature signature\\n   * @return magic hash if valid\\n   */\\n  function isValidAccountSignature(\\n    address account,\\n    bytes calldata message,\\n    bytes calldata signature\\n  )\\n    override\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return _verifyAccountOwner(\\n      account,\\n      message.toEthereumSignedMessageHash().recoverAddress(signature)\\n    );\\n  }\\n\\n  // private functions\\n\\n  function _verifySender(\\n    address account\\n  )\\n    private\\n    returns (address)\\n  {\\n    address sender = _getContextSender();\\n\\n    if (accounts[account].owners[sender].added) {\\n      require(\\n        accounts[account].owners[sender].removedAtBlockNumber == 0,\\n        \\\"PersonalAccountRegistry: sender is not the account owner\\\"\\n      );\\n    } else {\\n      require(\\n        accounts[account].salt == 0,\\n        \\\"PersonalAccountRegistry: sender is not the account owner\\\"\\n      );\\n\\n      bytes32 salt = keccak256(\\n        abi.encodePacked(sender)\\n      );\\n\\n      require(\\n        account == _computeAccountAddress(salt),\\n        \\\"PersonalAccountRegistry: sender is not the account owner\\\"\\n      );\\n\\n      accounts[account].salt = salt;\\n      accounts[account].owners[sender].added = true;\\n\\n      emit AccountOwnerAdded(\\n        account,\\n        sender\\n      );\\n    }\\n\\n    return sender;\\n  }\\n\\n  function _deployAccount(\\n    address account\\n  )\\n    internal\\n  {\\n    if (!accounts[account].deployed) {\\n      _deployAccount(\\n        accounts[account].salt,\\n        true\\n      );\\n\\n      accounts[account].deployed = true;\\n    }\\n  }\\n\\n  // private functions (views)\\n\\n  function _computeAccountAddress(\\n    address saltOwner\\n  )\\n    private\\n    view\\n    returns (address)\\n  {\\n    bytes32 salt = keccak256(\\n      abi.encodePacked(saltOwner)\\n    );\\n\\n    return _computeAccountAddress(salt);\\n  }\\n\\n  function _verifyAccountOwner(\\n    address account,\\n    address owner\\n  )\\n    private\\n    view\\n    returns (bool)\\n  {\\n    bool result;\\n\\n    if (accounts[account].owners[owner].added) {\\n      result = accounts[account].owners[owner].removedAtBlockNumber == 0;\\n    } else if (accounts[account].salt == 0) {\\n      result = account == _computeAccountAddress(owner);\\n    }\\n\\n    return result;\\n  }\\n}\\n\",\"keccak256\":\"0xdae162610e707ab8c394b3edf924b75ef1f315520935cb88f4280b29eeaf4b61\",\"license\":\"MIT\"}},\"version\":1}",
  "bytecode": "0x608060405234801561001057600080fd5b5032600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060004690508060028190555050614c138061006e6000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c80639130c06e116100de578063c36326e711610097578063da1b213d11610071578063da1b213d146104bb578063dc7d6c31146104d7578063df04338014610507578063e0fe396e146105235761018e565b8063c36326e71461043d578063d0f710d61461046d578063d2c83b9a1461049d5761018e565b80639130c06e146103915780639a85fae2146103ad5780639a8a0592146103c9578063a526d83b146103e7578063b0274a7314610403578063bdff4b3b1461041f5761018e565b80636121fcfc1161014b578063714041561161012557806371404156146102f757806384389a2b1461031357806387d31313146103435780638a1773ab146103615761018e565b80636121fcfc1461028f5780636524a947146102bf5780636866da52146102db5761018e565b80630c68ba2114610193578063116191b6146101c35780632e4f161e146101e15780632e7037a014610211578063392e53cd1461024157806360bf4df21461025f575b600080fd5b6101ad60048036038101906101a89190612f83565b61053f565b6040516101ba91906140a9565b60405180910390f35b6101cb610594565b6040516101d89190613e92565b60405180910390f35b6101fb60048036038101906101f69190612fe8565b6105ba565b60405161020891906140c4565b60405180910390f35b61022b600480360381019061022691906133f5565b6105d2565b60405161023891906140c4565b60405180910390f35b6102496105f2565b60405161025691906140a9565b60405180910390f35b61027960048036038101906102749190612f83565b61064a565b6040516102869190613e92565b60405180910390f35b6102a960048036038101906102a49190612f83565b61065c565b6040516102b691906140a9565b60405180910390f35b6102d960048036038101906102d49190612f83565b6106f7565b005b6102f560048036038101906102f0919061320c565b610703565b005b610311600480360381019061030c9190612f83565b610a28565b005b61032d6004803603810190610328919061341e565b610c40565b60405161033a91906140c4565b60405180910390f35b61034b610c6f565b6040516103589190614200565b60405180910390f35b61037b600480360381019061037691906132a1565b610c95565b604051610388919061449d565b60405180910390f35b6103ab60048036038101906103a69190612f83565b610cb5565b005b6103c760048036038101906103c2919061304b565b610fe9565b005b6103d16110f4565b6040516103de919061449d565b60405180910390f35b61040160048036038101906103fc9190612f83565b6110fa565b005b61041d60048036038101906104189190612f83565b611191565b005b6104276113ac565b604051610434919061449d565b60405180910390f35b61045760048036038101906104529190612fac565b6113b2565b604051610464919061449d565b60405180910390f35b610487600480360381019061048291906132ca565b61143c565b60405161049491906140a9565b60405180910390f35b6104a5611495565b6040516104b291906141e5565b60405180910390f35b6104d560048036038101906104d09190613121565b6114bb565b005b6104f160048036038101906104ec9190612fac565b6115c2565b6040516104fe919061449d565b60405180910390f35b610521600480360381019061051c919061304b565b61164c565b005b61053d60048036038101906105389190613363565b61174f565b005b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006105c885858585611955565b9050949350505050565b60006105eb82600001518360200151846040015161198e565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b6000610655826119e6565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b61070081611a84565b50565b600061070d611c94565b905060006107a3600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205486611ca590919063ffffffff16565b9050600081116107e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107df9061435d565b60405180910390fd5b60006107f583888861198e565b90506108458186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611cd2565b610884576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087b9061447d565b60405180910390fd5b85600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506109128388611d3f565b610980600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848985611efc565b7f95f66b073d65f18e43f6b76c7ab8557787f5f766d86cab7c9c76f41be9f8abc6600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848989604051610a179493929190613f51565b60405180910390a150505050505050565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610ab3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aaa9061433d565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff161415610b22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b199061443d565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610bad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba4906143dd565b60405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fee943cdb81826d5909c559c6b1ae6908fcaf2dbc16c4b730346736b486283e8b3282604051610c35929190613ec8565b60405180910390a150565b6000610c68826000015183602001518460400151856060015186608001518760a0015161218c565b9050919050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060086000838152602001908152602001600020600001549050919050565b6000610cbf611c94565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000811415610d89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d80906142fd565b60405180910390fd5b42811115610dcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc39061437d565b60405180910390fd5b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610f0d578173ffffffffffffffffffffffffffffffffffffffff16319050610f99565b8473ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401610f469190613e92565b60206040518083038186803b158015610f5e57600080fd5b505afa158015610f72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f969190613447565b90505b610fa582858784611efc565b7f5300d9a2838baade7cdc628c82cb80c1298853ba5f389d51e2b47330336aeffc82858784604051610fda9493929190613f51565b60405180910390a15050505050565b6000610ff3611c94565b905060008060006110928d858e8e8e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506121ed565b9250925092506110ac826110a5866119e6565b8e84611efc565b7f771bc0494e1a2fcbef19a8762845000d8c4500454c756a7370c955e39ed60fd483826040516110dd929190614140565b60405180910390a150505050505050505050505050565b60025481565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117c9061433d565b60405180910390fd5b61118e81612691565b50565b600061119b611c94565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114611264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125b9061429d565b60405180910390fd5b61126d82611a84565b6112826006544261282090919063ffffffff16565b905080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fed3c8c6cdfc6d7b91dc9db3e1f54866587c26c3c3e0f9e32cd1944974be43a50600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683858460405161139f9493929190613f51565b60405180910390a1505050565b60065481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600061148c8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611cd2565b90509392505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006114c5611c94565b905060008060006115648e858f8f8f8f8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506121ed565b92509250925061157782858f848d612875565b7f8b67efde501ee9cd0e771f7436554c44a5c076239ff3a6fbb397646a4689c0f283828b6040516115aa93929190614169565b60405180910390a15050505050505050505050505050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000611656611c94565b905060008060006116f58d858e8e8e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506121ed565b92509250925061170782858e84611efc565b7f6675346cd43846f7d47c310d39fb5c15bc7db66b3770338cdf1f133613a5ae988382604051611738929190614140565b60405180910390a150505050505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146117df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d69061427d565b60405180910390fd5b6000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008414156118bb576224ea006006819055506118c3565b836006819055505b61190d838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505061293a565b61191681612992565b7f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6326040516119459190613ead565b60405180910390a1505050505050565b60008484848460405160200161196e9493929190613cd9565b604051602081830303815290604052805190602001209050949350505050565b60006119dd7f3b3087c8f883f1f44cabe66444f5f9d96f69de6a88f364ea10959eef0331414a8585856040516020016119c993929190613d97565b6040516020818303038152906040526129d6565b90509392505050565b600080826040516020016119fa9190613cbe565b604051602081830303815290604052805190602001209050606060405180602001611a2490612cff565b6020820181038252601f19601f820116604052509050600060ff60f81b30848480519060200120604051602001611a5e9493929190613dd4565b6040516020818303038152906040528051906020012090508060001c9350505050919050565b600073ffffffffffffffffffffffffffffffffffffffff16600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611c9157600081604051602001611b2e9190613cbe565b60405160208183030381529060405280519060200120905080604051611b5390612cff565b8190604051809103906000f5905080158015611b73573d6000803e3d6000fd5b50600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd80572c0f2f24f2d9d726d831bd860ed82b12bafaf01cfb6e4d38fb23c4347e9600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683604051611c87929190613ef1565b60405180910390a1505b50565b6000611ca06028612a17565b905090565b6000611cca8383604051806060016040528060218152602001614be660219139612aac565b905092915050565b600080611ce88385612b0190919063ffffffff16565b90506000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611eee576000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fa19281a6f3163da06f6b82f3ecf0130493c52aba23cdc2a312f652742f0d1801600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168383604051611ee193929190613f1a565b60405180910390a1611ef8565b611ef782611a84565b5b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612016578373ffffffffffffffffffffffffffffffffffffffff16633f579f428483600067ffffffffffffffff81118015611f6757600080fd5b506040519080825280601f01601f191660200182016040528015611f9a5781602001600182028036833780820191505090505b506040518463ffffffff1660e01b8152600401611fb99392919061406b565b600060405180830381600087803b158015611fd357600080fd5b505af1158015611fe7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906120109190613322565b50612186565b60608473ffffffffffffffffffffffffffffffffffffffff16633f579f4284600063a9059cbb60e01b8887604051602401612052929190614042565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518463ffffffff1660e01b81526004016120cd93929190614004565b600060405180830381600087803b1580156120e757600080fd5b505af11580156120fb573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121249190613322565b905060008151111561218457808060200190518101906121449190613278565b612183576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217a9061431d565b60405180910390fd5b5b505b50505050565b60006121e17f745089e29f2abf28f618236a5dc04d214ac05ead3440ba532b69e9d160ba2e728888888888886040516020016121cd96959493929190613d27565b6040516020818303038152906040526129d6565b90509695505050505050565b6000806000806122018c8c8c8c8c8c61218c565b905060008651141561230057600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166359b52ef88d838b6040518463ffffffff1660e01b815260040161226c93929190613fcd565b60206040518083038186803b15801561228457600080fd5b505afa158015612298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122bc9190613278565b6122fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f29061447d565b60405180910390fd5b6124f1565b60006123158783612b0190919063ffffffff16565b90508073ffffffffffffffffffffffffffffffffffffffff168d73ffffffffffffffffffffffffffffffffffffffff16146124ef57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166334d323a48e838c6040518463ffffffff1660e01b81526004016123a993929190613f96565b60206040518083038186803b1580156123c157600080fd5b505afa1580156123d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f99190613278565b806124af5750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166334d323a48e838c6040518463ffffffff1660e01b815260040161245e93929190613f96565b60206040518083038186803b15801561247657600080fd5b505afa15801561248a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ae9190613278565b5b6124ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e5906143bd565b60405180910390fd5b5b505b6124fb8186611cd2565b61253a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125319061447d565b60405180910390fd5b6125468c8c8c8c611955565b9350612571600860008681526020019081526020016000206000015488611ca590919063ffffffff16565b915060008214156125b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ae906142bd565b60405180910390fd5b8660086000868152602001908152602001600020600001819055506125dc8c8b611d3f565b600760008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692507f0d1cb77d1fe491f98926195d0b885509da18bc305dd1489f45610237d971ed46848d8d8d8d8c60405161267a969594939291906140df565b60405180910390a150985098509895505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612701576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f89061425d565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561278d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127849061441d565b60405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fbc3292102fa77e083913064b282926717cdfaede4d35f553d66366c0a3da755a3282604051612815929190613ec8565b60405180910390a150565b60008082840190508381101561286b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612862906143fd565b60405180910390fd5b8091505092915050565b600081116128b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128af9061423d565b60405180910390fd5b60006128cd8284611ca590919063ffffffff16565b905060008111612912576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129099061439d565b60405180910390fd5b61291e86868684611efc565b6129328661292b876119e6565b8685611efc565b505050505050565b6000815114156129525761294d32612691565b61298f565b60008151905060005b8181101561298c5761297f83828151811061297257fe5b6020026020010151612691565b808060010191505061295b565b50505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000612a0f6002543085856040516020016129f49493929190613e48565b60405160208183030381529060405280519060200120612bbc565b905092915050565b60008060009050612a26612bec565b15612a9f576000836000369050039050612a9760003683906014850192612a4f9392919061455f565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612c99565b915050612aa3565b3390505b80915050919050565b6000838311158290612af4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612aeb919061421b565b60405180910390fd5b5082840390509392505050565b60008060009050604183511415612bb25760008060006020860151925060408601519150606086015160001a9050601b8160ff161015612b4257601b810190505b601b8160ff161480612b575750601c8160ff16145b15612bae5760018782858560405160008152602001604052604051612b7f94939291906141a0565b6020604051602081039080840390855afa158015612ba1573d6000803e3d6000fd5b5050506020604051035193505b5050505b8091505092915050565b600081604051602001612bcf9190613e22565b604051602081830303815290604052805190602001209050919050565b600080600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612c9257602c60003690501015612c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c84906142dd565b60405180910390fd5b600190505b8091505090565b6000806014835114612ce0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd79061445d565b60405180910390fd5b6c01000000000000000000000000602084015104905080915050919050565b6103f7806147ef83390190565b600081359050612d1b81614764565b92915050565b60008083601f840112612d3357600080fd5b8235905067ffffffffffffffff811115612d4c57600080fd5b602083019150836020820283011115612d6457600080fd5b9250929050565b600081519050612d7a8161477b565b92915050565b600081359050612d8f81614792565b92915050565b60008083601f840112612da757600080fd5b8235905067ffffffffffffffff811115612dc057600080fd5b602083019150836001820283011115612dd857600080fd5b9250929050565b600082601f830112612df057600080fd5b8151612e03612dfe826144e5565b6144b8565b91508082526020830160208301858383011115612e1f57600080fd5b612e2a8382846146d1565b50505092915050565b600081359050612e42816147a9565b92915050565b600081359050612e57816147c0565b92915050565b600060608284031215612e6f57600080fd5b612e7960606144b8565b90506000612e8984828501612d0c565b6000830152506020612e9d84828501612d0c565b6020830152506040612eb184828501612f59565b60408301525092915050565b600060c08284031215612ecf57600080fd5b612ed960c06144b8565b90506000612ee984828501612d0c565b6000830152506020612efd84828501612d0c565b6020830152506040612f1184828501612d0c565b6040830152506060612f2584828501612d80565b6060830152506080612f3984828501612f59565b60808301525060a0612f4d84828501612f59565b60a08301525092915050565b600081359050612f68816147d7565b92915050565b600081519050612f7d816147d7565b92915050565b600060208284031215612f9557600080fd5b6000612fa384828501612d0c565b91505092915050565b60008060408385031215612fbf57600080fd5b6000612fcd85828601612d0c565b9250506020612fde85828601612d0c565b9150509250929050565b60008060008060808587031215612ffe57600080fd5b600061300c87828801612d0c565b945050602061301d87828801612d0c565b935050604061302e87828801612d0c565b925050606061303f87828801612d80565b91505092959194509250565b600080600080600080600080600060e08a8c03121561306957600080fd5b60006130778c828d01612d0c565b99505060206130888c828d01612d0c565b98505060406130998c828d01612d80565b97505060606130aa8c828d01612f59565b96505060806130bb8c828d01612f59565b95505060a08a013567ffffffffffffffff8111156130d857600080fd5b6130e48c828d01612d95565b945094505060c08a013567ffffffffffffffff81111561310357600080fd5b61310f8c828d01612d95565b92509250509295985092959850929598565b6000806000806000806000806000806101008b8d03121561314157600080fd5b600061314f8d828e01612d0c565b9a505060206131608d828e01612d0c565b99505060406131718d828e01612d80565b98505060606131828d828e01612f59565b97505060806131938d828e01612f59565b96505060a06131a48d828e01612f59565b95505060c08b013567ffffffffffffffff8111156131c157600080fd5b6131cd8d828e01612d95565b945094505060e08b013567ffffffffffffffff8111156131ec57600080fd5b6131f88d828e01612d95565b92509250509295989b9194979a5092959850565b6000806000806060858703121561322257600080fd5b600061323087828801612d0c565b945050602061324187828801612f59565b935050604085013567ffffffffffffffff81111561325e57600080fd5b61326a87828801612d95565b925092505092959194509250565b60006020828403121561328a57600080fd5b600061329884828501612d6b565b91505092915050565b6000602082840312156132b357600080fd5b60006132c184828501612d80565b91505092915050565b6000806000604084860312156132df57600080fd5b60006132ed86828701612d80565b935050602084013567ffffffffffffffff81111561330a57600080fd5b61331686828701612d95565b92509250509250925092565b60006020828403121561333457600080fd5b600082015167ffffffffffffffff81111561334e57600080fd5b61335a84828501612ddf565b91505092915050565b60008060008060008060a0878903121561337c57600080fd5b600061338a89828a01612e33565b965050602061339b89828a01612e48565b95505060406133ac89828a01612f59565b945050606087013567ffffffffffffffff8111156133c957600080fd5b6133d589828a01612d21565b935093505060806133e889828a01612d0c565b9150509295509295509295565b60006060828403121561340757600080fd5b600061341584828501612e5d565b91505092915050565b600060c0828403121561343057600080fd5b600061343e84828501612ebd565b91505092915050565b60006020828403121561345957600080fd5b600061346784828501612f6e565b91505092915050565b61347981614641565b82525050565b61348881614592565b82525050565b61349f61349a82614592565b614704565b82525050565b6134ae816145a4565b82525050565b6134c56134c0826145b0565b614716565b82525050565b6134d4816145dc565b82525050565b6134eb6134e6826145dc565b614720565b82525050565b60006134fc82614511565b6135068185614527565b93506135168185602086016146d1565b61351f81614746565b840191505092915050565b600061353582614511565b61353f8185614538565b935061354f8185602086016146d1565b80840191505092915050565b61356481614653565b82525050565b61357381614677565b82525050565b6135828161469b565b82525050565b60006135938261451c565b61359d8185614543565b93506135ad8185602086016146d1565b6135b681614746565b840191505092915050565b60006135ce602683614543565b91507f5061796d656e7452656769737472793a20696e76616c6964206465706f73697460008301527f2076616c756500000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613634601c83614554565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b6000613674602083614543565b91507f477561726465643a2063616e6e6f74206164642030783020677561726469616e6000830152602082019050919050565b60006136b4602f83614543565b91507f496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742060008301527f74686520696e697469616c697a657200000000000000000000000000000000006020830152604082019050919050565b600061371a602f83614543565b91507f5061796d656e7452656769737472793a206465706f736974206578697420616c60008301527f72656164792072657175657374656400000000000000000000000000000000006020830152604082019050919050565b6000613780602683614543565b91507f5061796d656e7452656769737472793a20696e76616c6964207061796d656e7460008301527f2076616c756500000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137e6602283614543565b91507f47617465776179526563697069656e743a20696e76616c6964206d73672e646160008301527f74610000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061384c602b83614543565b91507f5061796d656e7452656769737472793a206465706f7369742065786974206e6f60008301527f74207265717565737465640000000000000000000000000000000000000000006020830152604082019050919050565b60006138b2602d83614543565b91507f5061796d656e7452656769737472793a204552433230546f6b656e207472616e60008301527f73666572207265766572746564000000000000000000000000000000000000006020830152604082019050919050565b6000613918602683614543565b91507f477561726465643a2074782e6f726967696e206973206e6f742074686520677560008301527f61726469616e00000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061397e601f83614543565b91507f5061796d656e7452656769737472793a20696e76616c696420616d6f756e74006000830152602082019050919050565b60006139be602483614543565b91507f5061796d656e7452656769737472793a206465706f7369742065786974206c6f60008301527f636b6564000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a24602783614543565b91507f5061796d656e7452656769737472793a20696e76616c6964207769746864726160008301527f772076616c7565000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a8a602983614543565b91507f5061796d656e7452656769737472793a20696e76616c69642073656e6465722060008301527f7369676e617475726500000000000000000000000000000000000000000000006020830152604082019050919050565b6000613af0601f83614543565b91507f477561726465643a20677561726469616e20646f65736e2774206578697374006000830152602082019050919050565b6000613b30601e83614543565b91507f536166654d6174684c69623a206164646974696f6e206f766572666c6f7700006000830152602082019050919050565b6000613b70602083614543565b91507f477561726465643a20677561726469616e20616c7265616479206578697374736000830152602082019050919050565b6000613bb0601b83614543565b91507f477561726465643a2063616e6e6f742072656d6f76652073656c6600000000006000830152602082019050919050565b6000613bf0601d83614543565b91507f42797465734c69623a20696e76616c69642064617461206c656e6774680000006000830152602082019050919050565b6000613c30602b83614543565b91507f5061796d656e7452656769737472793a20696e76616c6964206775617264696160008301527f6e207369676e61747572650000000000000000000000000000000000000000006020830152604082019050919050565b613c928161462a565b82525050565b613ca9613ca48261462a565b61473c565b82525050565b613cb881614634565b82525050565b6000613cca828461348e565b60148201915081905092915050565b6000613ce5828761348e565b601482019150613cf5828661348e565b601482019150613d05828561348e565b601482019150613d1582846134da565b60208201915081905095945050505050565b6000613d33828961348e565b601482019150613d43828861348e565b601482019150613d53828761348e565b601482019150613d6382866134da565b602082019150613d738285613c98565b602082019150613d838284613c98565b602082019150819050979650505050505050565b6000613da3828661348e565b601482019150613db3828561348e565b601482019150613dc38284613c98565b602082019150819050949350505050565b6000613de082876134b4565b600182019150613df0828661348e565b601482019150613e0082856134da565b602082019150613e1082846134da565b60208201915081905095945050505050565b6000613e2d82613627565b9150613e3982846134da565b60208201915081905092915050565b6000613e548287613c98565b602082019150613e64828661348e565b601482019150613e7482856134da565b602082019150613e84828461352a565b915081905095945050505050565b6000602082019050613ea7600083018461347f565b92915050565b6000602082019050613ec26000830184613470565b92915050565b6000604082019050613edd6000830185613470565b613eea602083018461347f565b9392505050565b6000604082019050613f06600083018561347f565b613f13602083018461347f565b9392505050565b6000606082019050613f2f600083018661347f565b613f3c602083018561347f565b613f49604083018461347f565b949350505050565b6000608082019050613f66600083018761347f565b613f73602083018661347f565b613f80604083018561347f565b613f8d6060830184613c89565b95945050505050565b6000606082019050613fab600083018661347f565b613fb8602083018561347f565b613fc56040830184613c89565b949350505050565b6000606082019050613fe2600083018661347f565b613fef60208301856134cb565b613ffc6040830184613c89565b949350505050565b6000606082019050614019600083018661347f565b6140266020830185613579565b818103604083015261403881846134f1565b9050949350505050565b6000604082019050614057600083018561347f565b6140646020830184613c89565b9392505050565b6000606082019050614080600083018661347f565b61408d6020830185613c89565b818103604083015261409f81846134f1565b9050949350505050565b60006020820190506140be60008301846134a5565b92915050565b60006020820190506140d960008301846134cb565b92915050565b600060c0820190506140f460008301896134cb565b614101602083018861347f565b61410e604083018761347f565b61411b606083018661347f565b61412860808301856134cb565b61413560a0830184613c89565b979650505050505050565b600060408201905061415560008301856134cb565b6141626020830184613c89565b9392505050565b600060608201905061417e60008301866134cb565b61418b6020830185613c89565b6141986040830184613c89565b949350505050565b60006080820190506141b560008301876134cb565b6141c26020830186613caf565b6141cf60408301856134cb565b6141dc60608301846134cb565b95945050505050565b60006020820190506141fa600083018461355b565b92915050565b6000602082019050614215600083018461356a565b92915050565b600060208201905081810360008301526142358184613588565b905092915050565b60006020820190508181036000830152614256816135c1565b9050919050565b6000602082019050818103600083015261427681613667565b9050919050565b60006020820190508181036000830152614296816136a7565b9050919050565b600060208201905081810360008301526142b68161370d565b9050919050565b600060208201905081810360008301526142d681613773565b9050919050565b600060208201905081810360008301526142f6816137d9565b9050919050565b600060208201905081810360008301526143168161383f565b9050919050565b60006020820190508181036000830152614336816138a5565b9050919050565b600060208201905081810360008301526143568161390b565b9050919050565b6000602082019050818103600083015261437681613971565b9050919050565b60006020820190508181036000830152614396816139b1565b9050919050565b600060208201905081810360008301526143b681613a17565b9050919050565b600060208201905081810360008301526143d681613a7d565b9050919050565b600060208201905081810360008301526143f681613ae3565b9050919050565b6000602082019050818103600083015261441681613b23565b9050919050565b6000602082019050818103600083015261443681613b63565b9050919050565b6000602082019050818103600083015261445681613ba3565b9050919050565b6000602082019050818103600083015261447681613be3565b9050919050565b6000602082019050818103600083015261449681613c23565b9050919050565b60006020820190506144b26000830184613c89565b92915050565b6000604051905081810181811067ffffffffffffffff821117156144db57600080fd5b8060405250919050565b600067ffffffffffffffff8211156144fc57600080fd5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000808585111561456f57600080fd5b8386111561457c57600080fd5b6001850283019150848603905094509492505050565b600061459d8261460a565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b60006145f182614592565b9050919050565b600061460382614592565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061464c826146ad565b9050919050565b600061465e82614665565b9050919050565b60006146708261460a565b9050919050565b600061468282614689565b9050919050565b60006146948261460a565b9050919050565b60006146a68261462a565b9050919050565b60006146b8826146bf565b9050919050565b60006146ca8261460a565b9050919050565b60005b838110156146ef5780820151818401526020810190506146d4565b838111156146fe576000848401525b50505050565b600061470f8261472a565b9050919050565b6000819050919050565b6000819050919050565b600061473582614757565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b61476d81614592565b811461477857600080fd5b50565b614784816145a4565b811461478f57600080fd5b50565b61479b816145dc565b81146147a657600080fd5b50565b6147b2816145e6565b81146147bd57600080fd5b50565b6147c9816145f8565b81146147d457600080fd5b50565b6147e08161462a565b81146147eb57600080fd5b5056fe6080604052336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506103a4806100536000396000f3fe60806040526004361061002d5760003560e01c80633f579f4214610039578063f77c47911461016257610034565b3661003457005b600080fd5b34801561004557600080fd5b506100e76004803603606081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156100a357600080fd5b8201836020820111156100b557600080fd5b803590602001918460018302840111640100000000831117156100d757600080fd5b90919293919293905050506101a3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561012757808201518184015260208101905061010c565b50505050905090810190601f1680156101545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561016e57600080fd5b50610177610347565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061036c602c913960400191505060405180910390fd5b606060008673ffffffffffffffffffffffffffffffffffffffff1686868660405180838380828437808301925050509250505060006040518083038185875af1925050503d80600081146102b9576040519150601f19603f3d011682016040523d82523d6000602084013e6102be565b606091505b5080935081925050508061033a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4163636f756e743a207472616e73616374696f6e20726576657274656400000081525060200191505060405180910390fd5b8192505050949350505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156fe436f6e74726f6c6c65643a206d73672e73656e646572206973206e6f742074686520636f6e74726f6c6c6572a164736f6c634300060c000a536166654d6174684c69623a207375627472616374696f6e206f766572666c6f77a164736f6c634300060c000a",
  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061018e5760003560e01c80639130c06e116100de578063c36326e711610097578063da1b213d11610071578063da1b213d146104bb578063dc7d6c31146104d7578063df04338014610507578063e0fe396e146105235761018e565b8063c36326e71461043d578063d0f710d61461046d578063d2c83b9a1461049d5761018e565b80639130c06e146103915780639a85fae2146103ad5780639a8a0592146103c9578063a526d83b146103e7578063b0274a7314610403578063bdff4b3b1461041f5761018e565b80636121fcfc1161014b578063714041561161012557806371404156146102f757806384389a2b1461031357806387d31313146103435780638a1773ab146103615761018e565b80636121fcfc1461028f5780636524a947146102bf5780636866da52146102db5761018e565b80630c68ba2114610193578063116191b6146101c35780632e4f161e146101e15780632e7037a014610211578063392e53cd1461024157806360bf4df21461025f575b600080fd5b6101ad60048036038101906101a89190612f83565b61053f565b6040516101ba91906140a9565b60405180910390f35b6101cb610594565b6040516101d89190613e92565b60405180910390f35b6101fb60048036038101906101f69190612fe8565b6105ba565b60405161020891906140c4565b60405180910390f35b61022b600480360381019061022691906133f5565b6105d2565b60405161023891906140c4565b60405180910390f35b6102496105f2565b60405161025691906140a9565b60405180910390f35b61027960048036038101906102749190612f83565b61064a565b6040516102869190613e92565b60405180910390f35b6102a960048036038101906102a49190612f83565b61065c565b6040516102b691906140a9565b60405180910390f35b6102d960048036038101906102d49190612f83565b6106f7565b005b6102f560048036038101906102f0919061320c565b610703565b005b610311600480360381019061030c9190612f83565b610a28565b005b61032d6004803603810190610328919061341e565b610c40565b60405161033a91906140c4565b60405180910390f35b61034b610c6f565b6040516103589190614200565b60405180910390f35b61037b600480360381019061037691906132a1565b610c95565b604051610388919061449d565b60405180910390f35b6103ab60048036038101906103a69190612f83565b610cb5565b005b6103c760048036038101906103c2919061304b565b610fe9565b005b6103d16110f4565b6040516103de919061449d565b60405180910390f35b61040160048036038101906103fc9190612f83565b6110fa565b005b61041d60048036038101906104189190612f83565b611191565b005b6104276113ac565b604051610434919061449d565b60405180910390f35b61045760048036038101906104529190612fac565b6113b2565b604051610464919061449d565b60405180910390f35b610487600480360381019061048291906132ca565b61143c565b60405161049491906140a9565b60405180910390f35b6104a5611495565b6040516104b291906141e5565b60405180910390f35b6104d560048036038101906104d09190613121565b6114bb565b005b6104f160048036038101906104ec9190612fac565b6115c2565b6040516104fe919061449d565b60405180910390f35b610521600480360381019061051c919061304b565b61164c565b005b61053d60048036038101906105389190613363565b61174f565b005b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006105c885858585611955565b9050949350505050565b60006105eb82600001518360200151846040015161198e565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b6000610655826119e6565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b61070081611a84565b50565b600061070d611c94565b905060006107a3600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205486611ca590919063ffffffff16565b9050600081116107e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107df9061435d565b60405180910390fd5b60006107f583888861198e565b90506108458186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611cd2565b610884576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087b9061447d565b60405180910390fd5b85600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506109128388611d3f565b610980600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848985611efc565b7f95f66b073d65f18e43f6b76c7ab8557787f5f766d86cab7c9c76f41be9f8abc6600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848989604051610a179493929190613f51565b60405180910390a150505050505050565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610ab3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aaa9061433d565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff161415610b22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b199061443d565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610bad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba4906143dd565b60405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fee943cdb81826d5909c559c6b1ae6908fcaf2dbc16c4b730346736b486283e8b3282604051610c35929190613ec8565b60405180910390a150565b6000610c68826000015183602001518460400151856060015186608001518760a0015161218c565b9050919050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060086000838152602001908152602001600020600001549050919050565b6000610cbf611c94565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000811415610d89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d80906142fd565b60405180910390fd5b42811115610dcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc39061437d565b60405180910390fd5b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610f0d578173ffffffffffffffffffffffffffffffffffffffff16319050610f99565b8473ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401610f469190613e92565b60206040518083038186803b158015610f5e57600080fd5b505afa158015610f72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f969190613447565b90505b610fa582858784611efc565b7f5300d9a2838baade7cdc628c82cb80c1298853ba5f389d51e2b47330336aeffc82858784604051610fda9493929190613f51565b60405180910390a15050505050565b6000610ff3611c94565b905060008060006110928d858e8e8e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506121ed565b9250925092506110ac826110a5866119e6565b8e84611efc565b7f771bc0494e1a2fcbef19a8762845000d8c4500454c756a7370c955e39ed60fd483826040516110dd929190614140565b60405180910390a150505050505050505050505050565b60025481565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117c9061433d565b60405180910390fd5b61118e81612691565b50565b600061119b611c94565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114611264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125b9061429d565b60405180910390fd5b61126d82611a84565b6112826006544261282090919063ffffffff16565b905080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fed3c8c6cdfc6d7b91dc9db3e1f54866587c26c3c3e0f9e32cd1944974be43a50600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683858460405161139f9493929190613f51565b60405180910390a1505050565b60065481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600061148c8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611cd2565b90509392505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006114c5611c94565b905060008060006115648e858f8f8f8f8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506121ed565b92509250925061157782858f848d612875565b7f8b67efde501ee9cd0e771f7436554c44a5c076239ff3a6fbb397646a4689c0f283828b6040516115aa93929190614169565b60405180910390a15050505050505050505050505050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000611656611c94565b905060008060006116f58d858e8e8e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506121ed565b92509250925061170782858e84611efc565b7f6675346cd43846f7d47c310d39fb5c15bc7db66b3770338cdf1f133613a5ae988382604051611738929190614140565b60405180910390a150505050505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146117df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d69061427d565b60405180910390fd5b6000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008414156118bb576224ea006006819055506118c3565b836006819055505b61190d838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505061293a565b61191681612992565b7f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6326040516119459190613ead565b60405180910390a1505050505050565b60008484848460405160200161196e9493929190613cd9565b604051602081830303815290604052805190602001209050949350505050565b60006119dd7f3b3087c8f883f1f44cabe66444f5f9d96f69de6a88f364ea10959eef0331414a8585856040516020016119c993929190613d97565b6040516020818303038152906040526129d6565b90509392505050565b600080826040516020016119fa9190613cbe565b604051602081830303815290604052805190602001209050606060405180602001611a2490612cff565b6020820181038252601f19601f820116604052509050600060ff60f81b30848480519060200120604051602001611a5e9493929190613dd4565b6040516020818303038152906040528051906020012090508060001c9350505050919050565b600073ffffffffffffffffffffffffffffffffffffffff16600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611c9157600081604051602001611b2e9190613cbe565b60405160208183030381529060405280519060200120905080604051611b5390612cff565b8190604051809103906000f5905080158015611b73573d6000803e3d6000fd5b50600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd80572c0f2f24f2d9d726d831bd860ed82b12bafaf01cfb6e4d38fb23c4347e9600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683604051611c87929190613ef1565b60405180910390a1505b50565b6000611ca06028612a17565b905090565b6000611cca8383604051806060016040528060218152602001614be660219139612aac565b905092915050565b600080611ce88385612b0190919063ffffffff16565b90506000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611eee576000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fa19281a6f3163da06f6b82f3ecf0130493c52aba23cdc2a312f652742f0d1801600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168383604051611ee193929190613f1a565b60405180910390a1611ef8565b611ef782611a84565b5b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612016578373ffffffffffffffffffffffffffffffffffffffff16633f579f428483600067ffffffffffffffff81118015611f6757600080fd5b506040519080825280601f01601f191660200182016040528015611f9a5781602001600182028036833780820191505090505b506040518463ffffffff1660e01b8152600401611fb99392919061406b565b600060405180830381600087803b158015611fd357600080fd5b505af1158015611fe7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906120109190613322565b50612186565b60608473ffffffffffffffffffffffffffffffffffffffff16633f579f4284600063a9059cbb60e01b8887604051602401612052929190614042565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518463ffffffff1660e01b81526004016120cd93929190614004565b600060405180830381600087803b1580156120e757600080fd5b505af11580156120fb573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121249190613322565b905060008151111561218457808060200190518101906121449190613278565b612183576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217a9061431d565b60405180910390fd5b5b505b50505050565b60006121e17f745089e29f2abf28f618236a5dc04d214ac05ead3440ba532b69e9d160ba2e728888888888886040516020016121cd96959493929190613d27565b6040516020818303038152906040526129d6565b90509695505050505050565b6000806000806122018c8c8c8c8c8c61218c565b905060008651141561230057600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166359b52ef88d838b6040518463ffffffff1660e01b815260040161226c93929190613fcd565b60206040518083038186803b15801561228457600080fd5b505afa158015612298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122bc9190613278565b6122fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f29061447d565b60405180910390fd5b6124f1565b60006123158783612b0190919063ffffffff16565b90508073ffffffffffffffffffffffffffffffffffffffff168d73ffffffffffffffffffffffffffffffffffffffff16146124ef57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166334d323a48e838c6040518463ffffffff1660e01b81526004016123a993929190613f96565b60206040518083038186803b1580156123c157600080fd5b505afa1580156123d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f99190613278565b806124af5750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166334d323a48e838c6040518463ffffffff1660e01b815260040161245e93929190613f96565b60206040518083038186803b15801561247657600080fd5b505afa15801561248a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ae9190613278565b5b6124ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e5906143bd565b60405180910390fd5b5b505b6124fb8186611cd2565b61253a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125319061447d565b60405180910390fd5b6125468c8c8c8c611955565b9350612571600860008681526020019081526020016000206000015488611ca590919063ffffffff16565b915060008214156125b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ae906142bd565b60405180910390fd5b8660086000868152602001908152602001600020600001819055506125dc8c8b611d3f565b600760008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692507f0d1cb77d1fe491f98926195d0b885509da18bc305dd1489f45610237d971ed46848d8d8d8d8c60405161267a969594939291906140df565b60405180910390a150985098509895505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612701576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f89061425d565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561278d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127849061441d565b60405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fbc3292102fa77e083913064b282926717cdfaede4d35f553d66366c0a3da755a3282604051612815929190613ec8565b60405180910390a150565b60008082840190508381101561286b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612862906143fd565b60405180910390fd5b8091505092915050565b600081116128b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128af9061423d565b60405180910390fd5b60006128cd8284611ca590919063ffffffff16565b905060008111612912576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129099061439d565b60405180910390fd5b61291e86868684611efc565b6129328661292b876119e6565b8685611efc565b505050505050565b6000815114156129525761294d32612691565b61298f565b60008151905060005b8181101561298c5761297f83828151811061297257fe5b6020026020010151612691565b808060010191505061295b565b50505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000612a0f6002543085856040516020016129f49493929190613e48565b60405160208183030381529060405280519060200120612bbc565b905092915050565b60008060009050612a26612bec565b15612a9f576000836000369050039050612a9760003683906014850192612a4f9392919061455f565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612c99565b915050612aa3565b3390505b80915050919050565b6000838311158290612af4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612aeb919061421b565b60405180910390fd5b5082840390509392505050565b60008060009050604183511415612bb25760008060006020860151925060408601519150606086015160001a9050601b8160ff161015612b4257601b810190505b601b8160ff161480612b575750601c8160ff16145b15612bae5760018782858560405160008152602001604052604051612b7f94939291906141a0565b6020604051602081039080840390855afa158015612ba1573d6000803e3d6000fd5b5050506020604051035193505b5050505b8091505092915050565b600081604051602001612bcf9190613e22565b604051602081830303815290604052805190602001209050919050565b600080600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612c9257602c60003690501015612c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c84906142dd565b60405180910390fd5b600190505b8091505090565b6000806014835114612ce0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd79061445d565b60405180910390fd5b6c01000000000000000000000000602084015104905080915050919050565b6103f7806147ef83390190565b600081359050612d1b81614764565b92915050565b60008083601f840112612d3357600080fd5b8235905067ffffffffffffffff811115612d4c57600080fd5b602083019150836020820283011115612d6457600080fd5b9250929050565b600081519050612d7a8161477b565b92915050565b600081359050612d8f81614792565b92915050565b60008083601f840112612da757600080fd5b8235905067ffffffffffffffff811115612dc057600080fd5b602083019150836001820283011115612dd857600080fd5b9250929050565b600082601f830112612df057600080fd5b8151612e03612dfe826144e5565b6144b8565b91508082526020830160208301858383011115612e1f57600080fd5b612e2a8382846146d1565b50505092915050565b600081359050612e42816147a9565b92915050565b600081359050612e57816147c0565b92915050565b600060608284031215612e6f57600080fd5b612e7960606144b8565b90506000612e8984828501612d0c565b6000830152506020612e9d84828501612d0c565b6020830152506040612eb184828501612f59565b60408301525092915050565b600060c08284031215612ecf57600080fd5b612ed960c06144b8565b90506000612ee984828501612d0c565b6000830152506020612efd84828501612d0c565b6020830152506040612f1184828501612d0c565b6040830152506060612f2584828501612d80565b6060830152506080612f3984828501612f59565b60808301525060a0612f4d84828501612f59565b60a08301525092915050565b600081359050612f68816147d7565b92915050565b600081519050612f7d816147d7565b92915050565b600060208284031215612f9557600080fd5b6000612fa384828501612d0c565b91505092915050565b60008060408385031215612fbf57600080fd5b6000612fcd85828601612d0c565b9250506020612fde85828601612d0c565b9150509250929050565b60008060008060808587031215612ffe57600080fd5b600061300c87828801612d0c565b945050602061301d87828801612d0c565b935050604061302e87828801612d0c565b925050606061303f87828801612d80565b91505092959194509250565b600080600080600080600080600060e08a8c03121561306957600080fd5b60006130778c828d01612d0c565b99505060206130888c828d01612d0c565b98505060406130998c828d01612d80565b97505060606130aa8c828d01612f59565b96505060806130bb8c828d01612f59565b95505060a08a013567ffffffffffffffff8111156130d857600080fd5b6130e48c828d01612d95565b945094505060c08a013567ffffffffffffffff81111561310357600080fd5b61310f8c828d01612d95565b92509250509295985092959850929598565b6000806000806000806000806000806101008b8d03121561314157600080fd5b600061314f8d828e01612d0c565b9a505060206131608d828e01612d0c565b99505060406131718d828e01612d80565b98505060606131828d828e01612f59565b97505060806131938d828e01612f59565b96505060a06131a48d828e01612f59565b95505060c08b013567ffffffffffffffff8111156131c157600080fd5b6131cd8d828e01612d95565b945094505060e08b013567ffffffffffffffff8111156131ec57600080fd5b6131f88d828e01612d95565b92509250509295989b9194979a5092959850565b6000806000806060858703121561322257600080fd5b600061323087828801612d0c565b945050602061324187828801612f59565b935050604085013567ffffffffffffffff81111561325e57600080fd5b61326a87828801612d95565b925092505092959194509250565b60006020828403121561328a57600080fd5b600061329884828501612d6b565b91505092915050565b6000602082840312156132b357600080fd5b60006132c184828501612d80565b91505092915050565b6000806000604084860312156132df57600080fd5b60006132ed86828701612d80565b935050602084013567ffffffffffffffff81111561330a57600080fd5b61331686828701612d95565b92509250509250925092565b60006020828403121561333457600080fd5b600082015167ffffffffffffffff81111561334e57600080fd5b61335a84828501612ddf565b91505092915050565b60008060008060008060a0878903121561337c57600080fd5b600061338a89828a01612e33565b965050602061339b89828a01612e48565b95505060406133ac89828a01612f59565b945050606087013567ffffffffffffffff8111156133c957600080fd5b6133d589828a01612d21565b935093505060806133e889828a01612d0c565b9150509295509295509295565b60006060828403121561340757600080fd5b600061341584828501612e5d565b91505092915050565b600060c0828403121561343057600080fd5b600061343e84828501612ebd565b91505092915050565b60006020828403121561345957600080fd5b600061346784828501612f6e565b91505092915050565b61347981614641565b82525050565b61348881614592565b82525050565b61349f61349a82614592565b614704565b82525050565b6134ae816145a4565b82525050565b6134c56134c0826145b0565b614716565b82525050565b6134d4816145dc565b82525050565b6134eb6134e6826145dc565b614720565b82525050565b60006134fc82614511565b6135068185614527565b93506135168185602086016146d1565b61351f81614746565b840191505092915050565b600061353582614511565b61353f8185614538565b935061354f8185602086016146d1565b80840191505092915050565b61356481614653565b82525050565b61357381614677565b82525050565b6135828161469b565b82525050565b60006135938261451c565b61359d8185614543565b93506135ad8185602086016146d1565b6135b681614746565b840191505092915050565b60006135ce602683614543565b91507f5061796d656e7452656769737472793a20696e76616c6964206465706f73697460008301527f2076616c756500000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613634601c83614554565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b6000613674602083614543565b91507f477561726465643a2063616e6e6f74206164642030783020677561726469616e6000830152602082019050919050565b60006136b4602f83614543565b91507f496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742060008301527f74686520696e697469616c697a657200000000000000000000000000000000006020830152604082019050919050565b600061371a602f83614543565b91507f5061796d656e7452656769737472793a206465706f736974206578697420616c60008301527f72656164792072657175657374656400000000000000000000000000000000006020830152604082019050919050565b6000613780602683614543565b91507f5061796d656e7452656769737472793a20696e76616c6964207061796d656e7460008301527f2076616c756500000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137e6602283614543565b91507f47617465776179526563697069656e743a20696e76616c6964206d73672e646160008301527f74610000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061384c602b83614543565b91507f5061796d656e7452656769737472793a206465706f7369742065786974206e6f60008301527f74207265717565737465640000000000000000000000000000000000000000006020830152604082019050919050565b60006138b2602d83614543565b91507f5061796d656e7452656769737472793a204552433230546f6b656e207472616e60008301527f73666572207265766572746564000000000000000000000000000000000000006020830152604082019050919050565b6000613918602683614543565b91507f477561726465643a2074782e6f726967696e206973206e6f742074686520677560008301527f61726469616e00000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061397e601f83614543565b91507f5061796d656e7452656769737472793a20696e76616c696420616d6f756e74006000830152602082019050919050565b60006139be602483614543565b91507f5061796d656e7452656769737472793a206465706f7369742065786974206c6f60008301527f636b6564000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a24602783614543565b91507f5061796d656e7452656769737472793a20696e76616c6964207769746864726160008301527f772076616c7565000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a8a602983614543565b91507f5061796d656e7452656769737472793a20696e76616c69642073656e6465722060008301527f7369676e617475726500000000000000000000000000000000000000000000006020830152604082019050919050565b6000613af0601f83614543565b91507f477561726465643a20677561726469616e20646f65736e2774206578697374006000830152602082019050919050565b6000613b30601e83614543565b91507f536166654d6174684c69623a206164646974696f6e206f766572666c6f7700006000830152602082019050919050565b6000613b70602083614543565b91507f477561726465643a20677561726469616e20616c7265616479206578697374736000830152602082019050919050565b6000613bb0601b83614543565b91507f477561726465643a2063616e6e6f742072656d6f76652073656c6600000000006000830152602082019050919050565b6000613bf0601d83614543565b91507f42797465734c69623a20696e76616c69642064617461206c656e6774680000006000830152602082019050919050565b6000613c30602b83614543565b91507f5061796d656e7452656769737472793a20696e76616c6964206775617264696160008301527f6e207369676e61747572650000000000000000000000000000000000000000006020830152604082019050919050565b613c928161462a565b82525050565b613ca9613ca48261462a565b61473c565b82525050565b613cb881614634565b82525050565b6000613cca828461348e565b60148201915081905092915050565b6000613ce5828761348e565b601482019150613cf5828661348e565b601482019150613d05828561348e565b601482019150613d1582846134da565b60208201915081905095945050505050565b6000613d33828961348e565b601482019150613d43828861348e565b601482019150613d53828761348e565b601482019150613d6382866134da565b602082019150613d738285613c98565b602082019150613d838284613c98565b602082019150819050979650505050505050565b6000613da3828661348e565b601482019150613db3828561348e565b601482019150613dc38284613c98565b602082019150819050949350505050565b6000613de082876134b4565b600182019150613df0828661348e565b601482019150613e0082856134da565b602082019150613e1082846134da565b60208201915081905095945050505050565b6000613e2d82613627565b9150613e3982846134da565b60208201915081905092915050565b6000613e548287613c98565b602082019150613e64828661348e565b601482019150613e7482856134da565b602082019150613e84828461352a565b915081905095945050505050565b6000602082019050613ea7600083018461347f565b92915050565b6000602082019050613ec26000830184613470565b92915050565b6000604082019050613edd6000830185613470565b613eea602083018461347f565b9392505050565b6000604082019050613f06600083018561347f565b613f13602083018461347f565b9392505050565b6000606082019050613f2f600083018661347f565b613f3c602083018561347f565b613f49604083018461347f565b949350505050565b6000608082019050613f66600083018761347f565b613f73602083018661347f565b613f80604083018561347f565b613f8d6060830184613c89565b95945050505050565b6000606082019050613fab600083018661347f565b613fb8602083018561347f565b613fc56040830184613c89565b949350505050565b6000606082019050613fe2600083018661347f565b613fef60208301856134cb565b613ffc6040830184613c89565b949350505050565b6000606082019050614019600083018661347f565b6140266020830185613579565b818103604083015261403881846134f1565b9050949350505050565b6000604082019050614057600083018561347f565b6140646020830184613c89565b9392505050565b6000606082019050614080600083018661347f565b61408d6020830185613c89565b818103604083015261409f81846134f1565b9050949350505050565b60006020820190506140be60008301846134a5565b92915050565b60006020820190506140d960008301846134cb565b92915050565b600060c0820190506140f460008301896134cb565b614101602083018861347f565b61410e604083018761347f565b61411b606083018661347f565b61412860808301856134cb565b61413560a0830184613c89565b979650505050505050565b600060408201905061415560008301856134cb565b6141626020830184613c89565b9392505050565b600060608201905061417e60008301866134cb565b61418b6020830185613c89565b6141986040830184613c89565b949350505050565b60006080820190506141b560008301876134cb565b6141c26020830186613caf565b6141cf60408301856134cb565b6141dc60608301846134cb565b95945050505050565b60006020820190506141fa600083018461355b565b92915050565b6000602082019050614215600083018461356a565b92915050565b600060208201905081810360008301526142358184613588565b905092915050565b60006020820190508181036000830152614256816135c1565b9050919050565b6000602082019050818103600083015261427681613667565b9050919050565b60006020820190508181036000830152614296816136a7565b9050919050565b600060208201905081810360008301526142b68161370d565b9050919050565b600060208201905081810360008301526142d681613773565b9050919050565b600060208201905081810360008301526142f6816137d9565b9050919050565b600060208201905081810360008301526143168161383f565b9050919050565b60006020820190508181036000830152614336816138a5565b9050919050565b600060208201905081810360008301526143568161390b565b9050919050565b6000602082019050818103600083015261437681613971565b9050919050565b60006020820190508181036000830152614396816139b1565b9050919050565b600060208201905081810360008301526143b681613a17565b9050919050565b600060208201905081810360008301526143d681613a7d565b9050919050565b600060208201905081810360008301526143f681613ae3565b9050919050565b6000602082019050818103600083015261441681613b23565b9050919050565b6000602082019050818103600083015261443681613b63565b9050919050565b6000602082019050818103600083015261445681613ba3565b9050919050565b6000602082019050818103600083015261447681613be3565b9050919050565b6000602082019050818103600083015261449681613c23565b9050919050565b60006020820190506144b26000830184613c89565b92915050565b6000604051905081810181811067ffffffffffffffff821117156144db57600080fd5b8060405250919050565b600067ffffffffffffffff8211156144fc57600080fd5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000808585111561456f57600080fd5b8386111561457c57600080fd5b6001850283019150848603905094509492505050565b600061459d8261460a565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b60006145f182614592565b9050919050565b600061460382614592565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061464c826146ad565b9050919050565b600061465e82614665565b9050919050565b60006146708261460a565b9050919050565b600061468282614689565b9050919050565b60006146948261460a565b9050919050565b60006146a68261462a565b9050919050565b60006146b8826146bf565b9050919050565b60006146ca8261460a565b9050919050565b60005b838110156146ef5780820151818401526020810190506146d4565b838111156146fe576000848401525b50505050565b600061470f8261472a565b9050919050565b6000819050919050565b6000819050919050565b600061473582614757565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b61476d81614592565b811461477857600080fd5b50565b614784816145a4565b811461478f57600080fd5b50565b61479b816145dc565b81146147a657600080fd5b50565b6147b2816145e6565b81146147bd57600080fd5b50565b6147c9816145f8565b81146147d457600080fd5b50565b6147e08161462a565b81146147eb57600080fd5b5056fe6080604052336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506103a4806100536000396000f3fe60806040526004361061002d5760003560e01c80633f579f4214610039578063f77c47911461016257610034565b3661003457005b600080fd5b34801561004557600080fd5b506100e76004803603606081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156100a357600080fd5b8201836020820111156100b557600080fd5b803590602001918460018302840111640100000000831117156100d757600080fd5b90919293919293905050506101a3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561012757808201518184015260208101905061010c565b50505050905090810190601f1680156101545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561016e57600080fd5b50610177610347565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061036c602c913960400191505060405180910390fd5b606060008673ffffffffffffffffffffffffffffffffffffffff1686868660405180838380828437808301925050509250505060006040518083038185875af1925050503d80600081146102b9576040519150601f19603f3d011682016040523d82523d6000602084013e6102be565b606091505b5080935081925050508061033a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4163636f756e743a207472616e73616374696f6e20726576657274656400000081525060200191505060405180910390fd5b8192505050949350505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156fe436f6e74726f6c6c65643a206d73672e73656e646572206973206e6f742074686520636f6e74726f6c6c6572a164736f6c634300060c000a536166654d6174684c69623a207375627472616374696f6e206f766572666c6f77a164736f6c634300060c000a",
  "devdoc": {
    "author": "Stanisław Głogowski <stan@pillarproject.io>",
    "details": "the `DepositExit` process can be used in a case operator (guardian) couldn't sign commit / withdrawal message. Process will be rejected when any of senders channels will be committed.",
    "events": {
      "DepositAccountDeployed(address,address)": {
        "details": "Emitted when the deposit account is deployed",
        "params": {
          "depositAccount": "deposit account address",
          "owner": "owner address"
        }
      },
      "DepositExitCompleted(address,address,address,uint256)": {
        "details": "Emitted when the deposit exist is completed",
        "params": {
          "amount": "deposit exist amount",
          "depositAccount": "deposit account address",
          "owner": "owner address",
          "token": "token address"
        }
      },
      "DepositExitRejected(address,address,address)": {
        "details": "Emitted when the deposit exist is rejected",
        "params": {
          "depositAccount": "deposit account address",
          "owner": "owner address",
          "token": "token address"
        }
      },
      "DepositExitRequested(address,address,address,uint256)": {
        "details": "Emitted when the deposit exist is requested",
        "params": {
          "depositAccount": "deposit account address",
          "lockedUntil": "deposit exist locked util time",
          "owner": "owner address",
          "token": "token address"
        }
      },
      "DepositWithdrawn(address,address,address,uint256)": {
        "details": "Emitted when the deposit has been withdrawn",
        "params": {
          "amount": "withdrawn amount",
          "depositAccount": "deposit account address",
          "owner": "owner address",
          "token": "token address"
        }
      },
      "PaymentChannelCommitted(bytes32,address,address,address,bytes32,uint256)": {
        "details": "Emitted when the payment channel has been committed",
        "params": {
          "amount": "committed amount",
          "hash": "channel hash",
          "recipient": "recipient address",
          "sender": "sender address",
          "token": "token address",
          "uid": "unique channel id"
        }
      },
      "PaymentDeposited(bytes32,uint256)": {
        "details": "Emitted when the payment has been deposited",
        "params": {
          "channelHash": "channel hash",
          "value": "payment value"
        }
      },
      "PaymentSplit(bytes32,uint256,uint256)": {
        "details": "Emitted when the payment has been withdrawn and deposited (split)",
        "params": {
          "channelHash": "channel hash",
          "depositValue": "payment deposited value",
          "totalValue": "payment total value"
        }
      },
      "PaymentWithdrawn(bytes32,uint256)": {
        "details": "Emitted when the payment has been withdrawn",
        "params": {
          "channelHash": "channel hash",
          "value": "payment value"
        }
      }
    },
    "kind": "dev",
    "methods": {
      "addGuardian(address)": {
        "params": {
          "guardian": "guardian address"
        }
      },
      "commitPaymentChannelAndDeposit(address,address,bytes32,uint256,uint256,bytes,bytes)": {
        "params": {
          "amount": "amount to commit",
          "blockNumber": "block number",
          "guardianSignature": "guardian signature",
          "sender": "sender address",
          "senderSignature": "sender signature",
          "token": "token address",
          "uid": "unique channel id"
        }
      },
      "commitPaymentChannelAndSplit(address,address,bytes32,uint256,uint256,uint256,bytes,bytes)": {
        "params": {
          "amount": "amount to commit",
          "blockNumber": "block number",
          "depositPaymentValue": "amount to deposit",
          "guardianSignature": "guardian signature",
          "sender": "sender address",
          "senderSignature": "sender signature",
          "token": "token address",
          "uid": "unique channel id"
        }
      },
      "commitPaymentChannelAndWithdraw(address,address,bytes32,uint256,uint256,bytes,bytes)": {
        "params": {
          "amount": "amount to commit",
          "blockNumber": "block number",
          "guardianSignature": "guardian signature",
          "sender": "sender address",
          "senderSignature": "sender signature",
          "token": "token address",
          "uid": "unique channel id"
        }
      },
      "computeDepositAccountAddress(address)": {
        "params": {
          "owner": "owner address"
        },
        "returns": {
          "_0": "deposit account address"
        }
      },
      "computePaymentChannelHash(address,address,address,bytes32)": {
        "params": {
          "recipient": "recipient address",
          "sender": "sender address",
          "token": "token address",
          "uid": "unique channel id"
        },
        "returns": {
          "_0": "hash"
        }
      },
      "constructor": {
        "details": "Public constructor"
      },
      "deployDepositAccount(address)": {
        "params": {
          "owner": "owner address"
        }
      },
      "getDepositExitLockedUntil(address,address)": {
        "params": {
          "owner": "owner address",
          "token": "token address"
        },
        "returns": {
          "_0": "locked until time"
        }
      },
      "getDepositWithdrawnAmount(address,address)": {
        "params": {
          "owner": "owner address",
          "token": "token address"
        },
        "returns": {
          "_0": "withdrawn amount"
        }
      },
      "getPaymentChannelCommittedAmount(bytes32)": {
        "params": {
          "hash": "payment channel hash"
        },
        "returns": {
          "_0": "committed amount"
        }
      },
      "hashDepositWithdrawal((address,address,uint256))": {
        "params": {
          "depositWithdrawal": "struct"
        },
        "returns": {
          "_0": "hash"
        }
      },
      "hashPaymentChannelCommit((address,address,address,bytes32,uint256,uint256))": {
        "params": {
          "paymentChannelCommit": "struct"
        },
        "returns": {
          "_0": "hash"
        }
      },
      "initialize(address,address,uint256,address[],address)": {
        "params": {
          "depositExitLockPeriod_": "deposit exit lock period",
          "externalAccountRegistry_": "`ExternalAccountRegistry` contract address",
          "gateway_": "`Gateway` contract address",
          "guardians_": "array of guardians addresses",
          "personalAccountRegistry_": "`PersonalAccountRegistry` contract address"
        }
      },
      "isDepositAccountDeployed(address)": {
        "params": {
          "owner": "owner address"
        },
        "returns": {
          "_0": "true when deposit account is deployed"
        }
      },
      "isGuardian(address)": {
        "params": {
          "guardian": "guardian address"
        },
        "returns": {
          "_0": "true when guardian exists"
        }
      },
      "isInitialized()": {
        "returns": {
          "_0": "true when contract is initialized"
        }
      },
      "processDepositExit(address)": {
        "params": {
          "token": "token address"
        }
      },
      "removeGuardian(address)": {
        "params": {
          "guardian": "guardian address"
        }
      },
      "requestDepositExit(address)": {
        "params": {
          "token": "token address"
        }
      },
      "verifyGuardianSignature(bytes32,bytes)": {
        "params": {
          "messageHash": "message hash",
          "signature": "signature"
        },
        "returns": {
          "_0": "true on correct guardian signature"
        }
      },
      "withdrawDeposit(address,uint256,bytes)": {
        "params": {
          "amount": "amount to withdraw",
          "guardianSignature": "guardian signature",
          "token": "token address"
        }
      }
    },
    "title": "Payment registry",
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {
      "addGuardian(address)": {
        "notice": "Adds a new guardian"
      },
      "commitPaymentChannelAndDeposit(address,address,bytes32,uint256,uint256,bytes,bytes)": {
        "notice": "Commits payment channel and deposit payment"
      },
      "commitPaymentChannelAndSplit(address,address,bytes32,uint256,uint256,uint256,bytes,bytes)": {
        "notice": "Commits payment channel, withdraws and deposits (split) payment"
      },
      "commitPaymentChannelAndWithdraw(address,address,bytes32,uint256,uint256,bytes,bytes)": {
        "notice": "Commits payment channel and withdraw payment"
      },
      "computeDepositAccountAddress(address)": {
        "notice": "Computes deposit account address"
      },
      "computePaymentChannelHash(address,address,address,bytes32)": {
        "notice": "Computes payment channel hash"
      },
      "deployDepositAccount(address)": {
        "notice": "Deploys deposit account"
      },
      "getDepositExitLockedUntil(address,address)": {
        "notice": "Gets deposit exit locked until time"
      },
      "getDepositWithdrawnAmount(address,address)": {
        "notice": "Gets deposit withdrawn amount"
      },
      "getPaymentChannelCommittedAmount(bytes32)": {
        "notice": "Gets payment channel committed amount"
      },
      "hashDepositWithdrawal((address,address,uint256))": {
        "notice": "Hashes `DepositWithdrawal` message payload"
      },
      "hashPaymentChannelCommit((address,address,address,bytes32,uint256,uint256))": {
        "notice": "Hashes `PaymentChannelCommit` message payload"
      },
      "initialize(address,address,uint256,address[],address)": {
        "notice": "Initialize `PaymentRegistry` contract"
      },
      "isDepositAccountDeployed(address)": {
        "notice": "Checks if deposit account is deployed"
      },
      "isGuardian(address)": {
        "notice": "Check if guardian exists"
      },
      "isInitialized()": {
        "notice": "Check if contract is initialized"
      },
      "processDepositExit(address)": {
        "notice": "Processes deposit exit"
      },
      "removeGuardian(address)": {
        "notice": "Removes the existing guardian"
      },
      "requestDepositExit(address)": {
        "notice": "Requests deposit exit"
      },
      "verifyGuardianSignature(bytes32,bytes)": {
        "notice": "Verifies guardian signature"
      },
      "withdrawDeposit(address,uint256,bytes)": {
        "notice": "Withdraws deposit"
      }
    },
    "notice": "A registry for payment and payment channels",
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 40,
        "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
        "label": "guardians",
        "offset": 0,
        "slot": "0",
        "type": "t_mapping(t_address,t_bool)"
      },
      {
        "astId": 1871,
        "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
        "label": "initializer",
        "offset": 0,
        "slot": "1",
        "type": "t_address"
      },
      {
        "astId": 1935,
        "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
        "label": "chainId",
        "offset": 0,
        "slot": "2",
        "type": "t_uint256"
      },
      {
        "astId": 5197,
        "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
        "label": "gateway",
        "offset": 0,
        "slot": "3",
        "type": "t_address"
      },
      {
        "astId": 5526,
        "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
        "label": "externalAccountRegistry",
        "offset": 0,
        "slot": "4",
        "type": "t_contract(ExternalAccountRegistry)4591"
      },
      {
        "astId": 5528,
        "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
        "label": "personalAccountRegistry",
        "offset": 0,
        "slot": "5",
        "type": "t_contract(PersonalAccountRegistry)7452"
      },
      {
        "astId": 5530,
        "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
        "label": "depositExitLockPeriod",
        "offset": 0,
        "slot": "6",
        "type": "t_uint256"
      },
      {
        "astId": 5534,
        "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
        "label": "deposits",
        "offset": 0,
        "slot": "7",
        "type": "t_mapping(t_address,t_struct(Deposit)5488_storage)"
      },
      {
        "astId": 5538,
        "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
        "label": "paymentChannels",
        "offset": 0,
        "slot": "8",
        "type": "t_mapping(t_bytes32,t_struct(PaymentChannel)5491_storage)"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_bool": {
        "encoding": "inplace",
        "label": "bool",
        "numberOfBytes": "1"
      },
      "t_bytes32": {
        "encoding": "inplace",
        "label": "bytes32",
        "numberOfBytes": "32"
      },
      "t_contract(ExternalAccountRegistry)4591": {
        "encoding": "inplace",
        "label": "contract ExternalAccountRegistry",
        "numberOfBytes": "20"
      },
      "t_contract(PersonalAccountRegistry)7452": {
        "encoding": "inplace",
        "label": "contract PersonalAccountRegistry",
        "numberOfBytes": "20"
      },
      "t_mapping(t_address,t_bool)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => bool)",
        "numberOfBytes": "32",
        "value": "t_bool"
      },
      "t_mapping(t_address,t_struct(Deposit)5488_storage)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => struct PaymentRegistry.Deposit)",
        "numberOfBytes": "32",
        "value": "t_struct(Deposit)5488_storage"
      },
      "t_mapping(t_address,t_uint256)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => uint256)",
        "numberOfBytes": "32",
        "value": "t_uint256"
      },
      "t_mapping(t_bytes32,t_struct(PaymentChannel)5491_storage)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => struct PaymentRegistry.PaymentChannel)",
        "numberOfBytes": "32",
        "value": "t_struct(PaymentChannel)5491_storage"
      },
      "t_struct(Deposit)5488_storage": {
        "encoding": "inplace",
        "label": "struct PaymentRegistry.Deposit",
        "members": [
          {
            "astId": 5479,
            "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
            "label": "account",
            "offset": 0,
            "slot": "0",
            "type": "t_address"
          },
          {
            "astId": 5483,
            "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
            "label": "withdrawnAmount",
            "offset": 0,
            "slot": "1",
            "type": "t_mapping(t_address,t_uint256)"
          },
          {
            "astId": 5487,
            "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
            "label": "exitLockedUntil",
            "offset": 0,
            "slot": "2",
            "type": "t_mapping(t_address,t_uint256)"
          }
        ],
        "numberOfBytes": "96"
      },
      "t_struct(PaymentChannel)5491_storage": {
        "encoding": "inplace",
        "label": "struct PaymentRegistry.PaymentChannel",
        "members": [
          {
            "astId": 5490,
            "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry",
            "label": "committedAmount",
            "offset": 0,
            "slot": "0",
            "type": "t_uint256"
          }
        ],
        "numberOfBytes": "32"
      },
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      }
    }
  }
}