text: CREATE TYPE ContractType AS ENUM ('ERC20', 'ERC721', 'other');
  
  CREATE TABLE IF NOT EXISTS contract (
    address VARCHAR(48),
    extrinsic_id BIGINT,
    signer VARCHAR NOT NULL,
  
    bytecode TEXT NOT NULL,
    bytecode_context TEXT NOT NULL,
    bytecode_arguments TEXT NOT NULL,
    gas_limit BIGINT NOT NULL,
    storage_limit BIGINT NOT NULL,
  
    timestamp timestamptz NOT NULL,
  
    PRIMARY KEY (address),
    CONSTRAINT fk_extrinsic
      FOREIGN KEY (extrinsic_id)
        REFERENCES extrinsic(id)
        ON DELETE CASCADE,
    CONSTRAINT fk_signer
      FOREIGN KEY (signer)
        REFERENCES account(address)
        ON DELETE CASCADE
  );
  
  CREATE INDEX IF NOT EXISTS contract_signer ON contract (signer);
  CREATE INDEX IF NOT EXISTS contract_extrinsic_id ON contract (extrinsic_id);
  
  CREATE TABLE IF NOT EXISTS verified_contract (
    address VARCHAR(48),
    
    name TEXT NOT NULL,
    filename TEXT NOT NULL,
    source JSON NOT NULL,
    optimization BOOLEAN NOT NULL,
    compiler_version TEXT NOT NULL, -- TODO maybe change to custom enum type?
    compiled_data JSON NOT NULL,
    args JSON NOT NULL,
    runs INT NOT NULL,
    target TEXT NOT NULL,
  
    type ContractType DEFAULT 'other',
    contract_data JSON,
  
    timestamp timestamptz default current_timestamp,
  
    UNIQUE (address),
    CONSTRAINT fk_address
      FOREIGN KEY (address)
        REFERENCES contract(address)
  );
  
  CREATE INDEX IF NOT EXISTS verified_contract_name ON verified_contract (name);
  CREATE INDEX IF NOT EXISTS verified_contract_type ON verified_contract (type);
  CREATE INDEX IF NOT EXISTS verified_contract_address ON verified_contract (address);
  CREATE INDEX IF NOT EXISTS verified_contract_filename ON verified_contract (filename);
  
  CREATE TABLE IF NOT EXISTS newly_verified_contract_queue (
    address VARCHAR(48),
    CONSTRAINT fk_verified_contract
      FOREIGN KEY (address)
        REFERENCES verified_contract(address)
        ON DELETE NO ACTION
  );
  
  CREATE TABLE IF NOT EXISTS verification_request (
    id BIGSERIAL,
    address VARCHAR(48),
  
    name TEXT NOT NULL,
    filename TEXT NOT NULL,
    source JSON NOT NULL,
    runs INT NOT NULL,
    optimization BOOLEAN NOT NULL,
    compiler_version TEXT NOT NULL, -- TODO maybe change to custom enum type?
    args JSON NOT NULL,
    target TEXT NOT NULL,
  
    success BOOLEAN NOT NULL,
    message TEXT,
  
    timestamp timestamptz default current_timestamp,
  
    PRIMARY KEY (id)
  );
  
  CREATE INDEX IF NOT EXISTS verification_request_name ON verification_request (name);
  CREATE INDEX IF NOT EXISTS verification_request_address ON verification_request (address);
  CREATE INDEX IF NOT EXISTS verification_request_success ON verification_request (success);
  CREATE INDEX IF NOT EXISTS verification_request_filename ON verification_request (filename);
  
  -- Genisis contract insert
  INSERT INTO contract
    (address, extrinsic_id, signer, bytecode, bytecode_context, bytecode_arguments, gas_limit, storage_limit, timestamp)
  VALUES
  -- REEF
    (
      '0x0000000000000000000000000000000001000000', -- address
      -1, 
      '0x',
      '0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80633950935111610071578063395093511461028857806370a08231146102ee57806395d89b4114610346578063a457c2d7146103c9578063a9059cbb1461042f578063dd62ed3e14610495576100b4565b806306fdde03146100b9578063095ea7b31461013c57806318160ddd146101a25780631feeece2146101c057806323b872dd146101de578063313ce56714610264575b600080fd5b6100c161050d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101015780820151818401526020810190506100e6565b50505050905090810190601f16801561012e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101886004803603604081101561015257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061054a565b604051808215151515815260200191505060405180910390f35b6101aa610561565b6040518082815260200191505060405180910390f35b6101c8610572565b6040518082815260200191505060405180910390f35b61024a600480360360608110156101f457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061057a565b604051808215151515815260200191505060405180910390f35b61026c610644565b604051808260ff1660ff16815260200191505060405180910390f35b6102d46004803603604081101561029e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061064d565b604051808215151515815260200191505060405180910390f35b6103306004803603602081101561030457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506106f1565b6040518082815260200191505060405180910390f35b61034e610705565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561038e578082015181840152602081019050610373565b50505050905090810190601f1680156103bb5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610415600480360360408110156103df57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610742565b604051808215151515815260200191505060405180910390f35b61047b6004803603604081101561044557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610800565b604051808215151515815260200191505060405180910390f35b6104f7600480360360408110156104ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610817565b6040518082815260200191505060405180910390f35b60606040518060400160405280600481526020017f5265656600000000000000000000000000000000000000000000000000000000815250905090565b600061055733848461089d565b6001905092915050565b600061056d6000610a93565b905090565b600080905090565b6000610587848484610b03565b610639843361063485604051806060016040528060288152602001610ffd602891396000808b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c869092919063ffffffff16565b61089d565b600190509392505050565b60006012905090565b60006106e733846106e2856000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610d4690919063ffffffff16565b61089d565b6001905092915050565b60006106fe600083610dce565b9050919050565b60606040518060400160405280600481526020017f5245454600000000000000000000000000000000000000000000000000000000815250905090565b60006107f633846107f18560405180606001604052806025815260200161106e602591396000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c869092919063ffffffff16565b61089d565b6001905092915050565b600061080d338484610b03565b6001905092915050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610923576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602481526020018061104a6024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156109a9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610fdb6022913960400191505060405180910390fd5b806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b6000610a9d610f2f565b600081600060028110610aac57fe5b6020020181815250508281600160028110610ac357fe5b602002018181525050610ad4610f51565b6020816040846104005afa610ae857600080fd5b80600060018110610af557fe5b602002015192505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610b89576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806110256025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610c0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180610fb86023913960400191505060405180910390fd5b610c1c6000848484610e6c565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290610d33576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610cf8578082015181840152602081019050610cdd565b50505050905090810190601f168015610d255780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080828401905083811015610dc4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6000610dd8610f73565b600181600060038110610de757fe5b6020020181815250508381600160038110610dfe57fe5b6020020181815250508273ffffffffffffffffffffffffffffffffffffffff1681600260038110610e2b57fe5b602002018181525050610e3c610f51565b6020816060846104005afa610e5057600080fd5b80600060018110610e5d57fe5b60200201519250505092915050565b610e74610f95565b600281600060058110610e8357fe5b6020020181815250508481600160058110610e9a57fe5b6020020181815250508373ffffffffffffffffffffffffffffffffffffffff1681600260058110610ec757fe5b6020020181815250508273ffffffffffffffffffffffffffffffffffffffff1681600360058110610ef457fe5b6020020181815250508181600460058110610f0b57fe5b60200201818152505060008060a0836104005afa610f2857600080fd5b5050505050565b6040518060400160405280600290602082028038833980820191505090505090565b6040518060200160405280600190602082028038833980820191505090505090565b6040518060600160405280600390602082028038833980820191505090505090565b6040518060a0016040528060059060208202803883398082019150509050509056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212207f0d7ea0316b4993ca5b9a6d117724e55da822413094fde716c771acdd2d4c2c64736f6c63430006000033',
      '',
      'a2646970667358221220ca5c764db385f7a72f31e6e1a0ed4e18a4de5062832e0e616ba8b7d30cc6398964736f6c63430006000033',
      0,
      0,
      '2020-10-01 00:00:00'
    ),
  -- RUSD
    (
      '0x0000000000000000000000000000000001000001', -- address
      -1, 
      '0x',
      '0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80633950935111610071578063395093511461028857806370a08231146102ee57806395d89b4114610346578063a457c2d7146103c9578063a9059cbb1461042f578063dd62ed3e14610495576100b4565b806306fdde03146100b9578063095ea7b31461013c57806318160ddd146101a25780631feeece2146101c057806323b872dd146101de578063313ce56714610264575b600080fd5b6100c161050d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101015780820151818401526020810190506100e6565b50505050905090810190601f16801561012e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101886004803603604081101561015257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061054a565b604051808215151515815260200191505060405180910390f35b6101aa610561565b6040518082815260200191505060405180910390f35b6101c8610573565b6040518082815260200191505060405180910390f35b61024a600480360360608110156101f457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061057d565b604051808215151515815260200191505060405180910390f35b61026c610647565b604051808260ff1660ff16815260200191505060405180910390f35b6102d46004803603604081101561029e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610650565b604051808215151515815260200191505060405180910390f35b6103306004803603602081101561030457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506106f4565b6040518082815260200191505060405180910390f35b61034e610709565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561038e578082015181840152602081019050610373565b50505050905090810190601f1680156103bb5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610415600480360360408110156103df57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610746565b604051808215151515815260200191505060405180910390f35b61047b6004803603604081101561044557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610804565b604051808215151515815260200191505060405180910390f35b6104f7600480360360408110156104ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061081b565b6040518082815260200191505060405180910390f35b60606040518060400160405280600b81526020017f5265656620446f6c6c6172000000000000000000000000000000000000000000815250905090565b60006105573384846108a1565b6001905092915050565b600061056e610100610a97565b905090565b6000610100905090565b600061058a848484610b07565b61063c843361063785604051806060016040528060288152602001611002602891396000808b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c8b9092919063ffffffff16565b6108a1565b600190509392505050565b60006012905090565b60006106ea33846106e5856000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610d4b90919063ffffffff16565b6108a1565b6001905092915050565b600061070261010083610dd3565b9050919050565b60606040518060400160405280600481526020017f5255534400000000000000000000000000000000000000000000000000000000815250905090565b60006107fa33846107f585604051806060016040528060258152602001611073602591396000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c8b9092919063ffffffff16565b6108a1565b6001905092915050565b6000610811338484610b07565b6001905092915050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610927576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602481526020018061104f6024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156109ad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610fe06022913960400191505060405180910390fd5b806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b6000610aa1610f34565b600081600060028110610ab057fe5b6020020181815250508281600160028110610ac757fe5b602002018181525050610ad8610f56565b6020816040846104005afa610aec57600080fd5b80600060018110610af957fe5b602002015192505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602581526020018061102a6025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610c13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180610fbd6023913960400191505060405180910390fd5b610c21610100848484610e71565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290610d38576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610cfd578082015181840152602081019050610ce2565b50505050905090810190601f168015610d2a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080828401905083811015610dc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6000610ddd610f78565b600181600060038110610dec57fe5b6020020181815250508381600160038110610e0357fe5b6020020181815250508273ffffffffffffffffffffffffffffffffffffffff1681600260038110610e3057fe5b602002018181525050610e41610f56565b6020816060846104005afa610e5557600080fd5b80600060018110610e6257fe5b60200201519250505092915050565b610e79610f9a565b600281600060058110610e8857fe5b6020020181815250508481600160058110610e9f57fe5b6020020181815250508373ffffffffffffffffffffffffffffffffffffffff1681600260058110610ecc57fe5b6020020181815250508273ffffffffffffffffffffffffffffffffffffffff1681600360058110610ef957fe5b6020020181815250508181600460058110610f1057fe5b60200201818152505060008060a0836104005afa610f2d57600080fd5b5050505050565b6040518060400160405280600290602082028038833980820191505090505090565b6040518060200160405280600190602082028038833980820191505090505090565b6040518060600160405280600390602082028038833980820191505090505090565b6040518060a0016040528060059060208202803883398082019150509050509056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220a6949233ed4c6693d0c8c97f7d7a9f7ffaab104485faefa710afebe9ea7b166f64736f6c63430006000033',
      '',
      'a2646970667358221220a6949233ed4c6693d0c8c97f7d7a9f7ffaab104485faefa710afebe9ea7b166f64736f6c63430006000033',
      0,
      0,
      '2020-10-01 00:00:00'
    ),
  -- StateRent
    (
      '0x0000000000000000000000000000000000000800', -- address
      -1, 
      '0x',
      '0x608060405234801561001057600080fd5b50600436106100625760003560e01c806306ad13551461006757806368a18855146100eb5780636e04399814610109578063a23e8b8214610127578063cfbd33d714610145578063f2cff57f146101c1575b600080fd5b6100a96004803603602081101561007d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101df565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100f36101f1565b6040518082815260200191505060405180910390f35b610111610200565b6040518082815260200191505060405180910390f35b61012f61020f565b6040518082815260200191505060405180910390f35b6101a76004803603604081101561015b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061021e565b604051808215151515815260200191505060405180910390f35b6101c9610235565b6040518082815260200191505060405180910390f35b60006101ea82610244565b9050919050565b60006101fb6102ca565b905090565b600061020a610321565b905090565b6000610219610378565b905090565b600061022b3384846103cf565b6001905092915050565b600061023f6105cb565b905090565b600061024e6106e3565b60028160006002811061025d57fe5b6020020181815250508273ffffffffffffffffffffffffffffffffffffffff168160016002811061028a57fe5b60200201818152505061029b610705565b6020816040846104025afa6102af57600080fd5b806000600181106102bc57fe5b602002015192505050919050565b60006102d4610705565b6003816000600181106102e357fe5b6020020181815250506102f4610705565b6020816020846104025afa61030857600080fd5b8060006001811061031557fe5b60200201519250505090565b600061032b610705565b60018160006001811061033a57fe5b60200201818152505061034b610705565b6020816020846104025afa61035f57600080fd5b8060006001811061036c57fe5b60200201519250505090565b6000610382610705565b60008160006001811061039157fe5b6020020181815250506103a2610705565b6020816020846104025afa6103b657600080fd5b806000600181106103c357fe5b60200201519250505090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610455576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602981526020018061074a6029913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156104db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806107a46033913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610561576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806107736031913960400191505060405180910390fd5b61056c338383610622565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8cee443d7a0c7dbd8a490dab604d0ed84f4138ba66b3dce2f78ed58bb63f56b760405160405180910390a3505050565b60006105d5610705565b6004816000600181106105e457fe5b6020020181815250506105f5610705565b6020816020846104025afa61060957600080fd5b8060006001811061061657fe5b60200201519250505090565b61062a610727565b60808160006004811061063957fe5b6020020181815250508373ffffffffffffffffffffffffffffffffffffffff168160016004811061066657fe5b6020020181815250508273ffffffffffffffffffffffffffffffffffffffff168160026004811061069357fe5b6020020181815250508173ffffffffffffffffffffffffffffffffffffffff16816003600481106106c057fe5b6020020181815250506000806080836104025afa6106dd57600080fd5b50505050565b6040518060400160405280600290602082028038833980820191505090505090565b6040518060200160405280600190602082028038833980820191505090505090565b604051806080016040528060049060208202803883398082019150509050509056fe537461746552656e743a207468652073656e64657220697320746865207a65726f2061646472657373537461746552656e743a20746865206e65775f6d61696e7461696e657220697320746865207a65726f2061646472657373537461746552656e743a2074686520636f6e74726163745f6164647265737320697320746865207a65726f2061646472657373a26469706673582212208f9fcccb00b243a8a1ca97eba7bec39378123acbc541f72ad47c56ca7b6073e764736f6c63430006000033',
      '',
      'a26469706673582212208f9fcccb00b243a8a1ca97eba7bec39378123acbc541f72ad47c56ca7b6073e764736f6c63430006000033',
      0,
      0,
      '2020-10-01 00:00:00'
    ),
  -- Oracle
    (
      '0x0000000000000000000000000000000000000801', -- address
      -1, 
      '0x',
      '0x608060405234801561001057600080fd5b506004361061002b5760003560e01c806341976e0914610030575b600080fd5b6100726004803603602081101561004657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061008f565b604051808381526020018281526020019250505060405180910390f35b60008082606081604051602001808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401915050604051602081830303815290604052905060008090505b600c8110156101b357600060f81b82828151811061010657fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146101a6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f6e6f7420612073797374656d20636f6e7472616374000000000000000000000081525060200191505060405180910390fd5b80806001019150506100ec565b50600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610257576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4f7261636c653a20746f6b656e206973207a65726f206164647265737300000081525060200191505060405180910390fd5b60008573ffffffffffffffffffffffffffffffffffffffff16631feeece26040518163ffffffff1660e01b815260040160206040518083038186803b15801561029f57600080fd5b505afa1580156102b3573d6000803e3d6000fd5b505050506040513d60208110156102c957600080fd5b810190808051906020019092919050505090506102e4610361565b6000816000600281106102f357fe5b602002018181525050818160016002811061030a57fe5b60200201818152505061031b610361565b6040816040846104035afa61032f57600080fd5b8060006002811061033c57fe5b60200201518160016002811061034e57fe5b6020020151965096505050505050915091565b604051806040016040528060029060208202803883398082019150509050509056fea26469706673582212200ab4066d46955f90fc2882320523757ba3fbb9ae3cb2ba76fef520dc50c2552364736f6c63430006000033',
      '',
      'a26469706673582212200ab4066d46955f90fc2882320523757ba3fbb9ae3cb2ba76fef520dc50c2552364736f6c63430006000033',
      0,
      0,
      '2020-10-01 00:00:00'
    ),
  -- Schedule
    (
      '0x0000000000000000000000000000000000000802', -- address
      -1, 
      '0x',
      '0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063168d560d1461004657806380770aa214610161578063ed67982b1461023e575b600080fd5b610147600480360360c081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190929190803590602001906401000000008111156100c157600080fd5b8201836020820111156100d357600080fd5b803590602001918460018302840111640100000000831117156100f557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610311565b604051808215151515815260200191505060405180910390f35b6102246004803603604081101561017757600080fd5b81019080803590602001909291908035906020019064010000000081111561019e57600080fd5b8201836020820111156101b057600080fd5b803590602001918460018302840111640100000000831117156101d257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610330565b604051808215151515815260200191505060405180910390f35b6102f76004803603602081101561025457600080fd5b810190808035906020019064010000000081111561027157600080fd5b82018360208201111561028357600080fd5b803590602001918460018302840111640100000000831117156102a557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610347565b604051808215151515815260200191505060405180910390f35b60006103223388888888888861035c565b600190509695505050505050565b600061033d3384846105c6565b6001905092915050565b6000610353338361070f565b60019050919050565b600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614156103e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180610dbc602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415610468576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180610de86036913960400191505060405180910390fd5b60008151116104df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f5363686564756c6543616c6c3a20696e707574206973206e756c6c000000000081525060200191505060405180910390fd5b60606104f033888888888888610856565b90508673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ff50ab0aa329811f23150e5490fc00ea0baf136a55280b7e88703b4753d4097ce836040518080602001828103825283818151815260200191508051906020019080838360005b83811015610582578082015181840152602081019050610567565b50505050905090810190601f1680156105af5780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561064c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180610dbc602c913960400191505060405180910390fd5b610657338383610b27565b3373ffffffffffffffffffffffffffffffffffffffff167f3d7c2a1f4334df8f13c937065d5a5505918af3e28136cf2ac1273b96d1ed996a826040518080602001828103825283818151815260200191508051906020019080838360005b838110156106d05780820151818401526020810190506106b5565b50505050905090810190601f1680156106fd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610795576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180610dbc602c913960400191505060405180910390fd5b61079f3382610c5e565b3373ffffffffffffffffffffffffffffffffffffffff167fe53347c2cd79d58390b73e62c658e8893996a9f82a3be212c9971859c79a9644826040518080602001828103825283818151815260200191508051906020019080838360005b838110156108185780820151818401526020810190506107fd565b50505050905090810190601f1680156108455780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b606060006020601f8451018161086857fe5b04905060008160080190506060816040519080825280602002602001820160405280156108a45781602001602082028038833980820191505090505b5090506000816000815181106108b657fe5b6020026020010181815250508a73ffffffffffffffffffffffffffffffffffffffff16816001815181106108e657fe5b6020026020010181815250508973ffffffffffffffffffffffffffffffffffffffff168160028151811061091657fe5b602002602001018181525050888160038151811061093057fe5b602002602001018181525050878160048151811061094a57fe5b602002602001018181525050868160058151811061096457fe5b602002602001018181525050858160068151811061097e57fe5b60200260200101818152505084518160078151811061099957fe5b60200260200101818152505060008090505b838110156109e5576109bd8682610d7a565b8282600801815181106109cc57fe5b60200260200101818152505080806001019150506109ab565b5060006020600184010290506109f9610d99565b60608183856104045afa610a0c57600080fd5b606081600060038110610a1b57fe5b60200201516040519080825280601f01601f191660200182016040528015610a525781602001600182028038833980820191505090505b509050606082600160038110610a6457fe5b602002015183600260038110610a7657fe5b60200201516040516020018083815260200182815260200192505050604051602081830303815290604052905060008090505b8251811015610b1157818181518110610abe57fe5b602001015160f81c60f81b838281518110610ad557fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080600101915050610aa9565b5081975050505050505050979650505050505050565b60006020601f83510181610b3757fe5b0490506000816004019050606081604051908082528060200260200182016040528015610b735781602001602082028038833980820191505090505b509050600281600081518110610b8557fe5b6020026020010181815250508573ffffffffffffffffffffffffffffffffffffffff1681600181518110610bb557fe5b6020026020010181815250508481600281518110610bcf57fe5b602002602001018181525050835181600381518110610bea57fe5b60200260200101818152505060008090505b83811015610c3657610c0e8582610d7a565b828260040181518110610c1d57fe5b6020026020010181815250508080600101915050610bfc565b50600060206001840102905060008082846104045afa610c5557600080fd5b50505050505050565b60006020601f83510181610c6e57fe5b0490506000816003019050606081604051908082528060200260200182016040528015610caa5781602001602082028038833980820191505090505b509050600181600081518110610cbc57fe5b6020026020010181815250508473ffffffffffffffffffffffffffffffffffffffff1681600181518110610cec57fe5b602002602001018181525050835181600281518110610d0757fe5b60200260200101818152505060008090505b83811015610d5357610d2b8582610d7a565b828260030181518110610d3a57fe5b6020026020010181815250508080600101915050610d19565b50600060206001840102905060008082846104045afa610d7257600080fd5b505050505050565b6000806020830290506000816020018501519050809250505092915050565b604051806060016040528060039060208202803883398082019150509050509056fe5363686564756c6543616c6c3a207468652073656e64657220697320746865207a65726f20616464726573735363686564756c6543616c6c3a2074686520636f6e74726163745f6164647265737320697320746865207a65726f2061646472657373a26469706673582212208cb1aaf45825063deccbd79372e77cc77abb5031b261cce27c89766e6fd7f2e164736f6c63430006000033',
      '',
      'a26469706673582212208cb1aaf45825063deccbd79372e77cc77abb5031b261cce27c89766e6fd7f2e164736f6c63430006000033',
      0,
      0,
      '2020-10-01 00:00:00'
    ),
  -- DEX
    (
      '0x0000000000000000000000000000000000000803', -- address
      -1, 
      '0x',
      '0x608060405234801561001057600080fd5b50600436106100365760003560e01c806364b899ac1461003b578063ea526de7146100c7575b600080fd5b6100b16004803603608081101561005157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050610146565b6040518082815260200191505060405180910390f35b610129600480360360408110156100dd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061073c565b604051808381526020018281526020019250505060405180910390f35b600084606081604051602001808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401915050604051602081830303815290604052905060008090505b600c81101561026957600060f81b8282815181106101bc57fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461025c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f6e6f7420612073797374656d20636f6e7472616374000000000000000000000081525060200191505060405180910390fd5b80806001019150506101a2565b5085606081604051602001808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401915050604051602081830303815290604052905060008090505b600c81101561038b57600060f81b8282815181106102de57fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461037e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f6e6f7420612073797374656d20636f6e7472616374000000000000000000000081525060200191505060405180910390fd5b80806001019150506102c4565b50600073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff16141561042f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4445583a20746f6b656e41206973207a65726f2061646472657373000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614156104d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4445583a20746f6b656e42206973207a65726f2061646472657373000000000081525060200191505060405180910390fd5b6000871415610549576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4445583a20737570706c79416d6f756e74206973207a65726f0000000000000081525060200191505060405180910390fd5b60008973ffffffffffffffffffffffffffffffffffffffff16631feeece26040518163ffffffff1660e01b815260040160206040518083038186803b15801561059157600080fd5b505afa1580156105a5573d6000803e3d6000fd5b505050506040513d60208110156105bb57600080fd5b8101908080519060200190929190505050905060008973ffffffffffffffffffffffffffffffffffffffff16631feeece26040518163ffffffff1660e01b815260040160206040518083038186803b15801561061657600080fd5b505afa15801561062a573d6000803e3d6000fd5b505050506040513d602081101561064057600080fd5b8101908080519060200190929190505050905061065b610c74565b60018160006006811061066a57fe5b6020020181815250503373ffffffffffffffffffffffffffffffffffffffff168160016006811061069757fe5b60200201818152505082816002600681106106ae57fe5b60200201818152505081816003600681106106c557fe5b60200201818152505089816004600681106106dc57fe5b60200201818152505088816005600681106106f357fe5b602002018181525050610704610c96565b60208160c0846104055afa61071857600080fd5b8060006001811061072557fe5b602002015198505050505050505050949350505050565b60008083606081604051602001808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401915050604051602081830303815290604052905060008090505b600c81101561086057600060f81b8282815181106107b357fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614610853576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f6e6f7420612073797374656d20636f6e7472616374000000000000000000000081525060200191505060405180910390fd5b8080600101915050610799565b5084606081604051602001808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401915050604051602081830303815290604052905060008090505b600c81101561098257600060f81b8282815181106108d557fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614610975576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f6e6f7420612073797374656d20636f6e7472616374000000000000000000000081525060200191505060405180910390fd5b80806001019150506108bb565b50600073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161415610a26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4445583a20746f6b656e41206973207a65726f2061646472657373000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161415610ac9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4445583a20746f6b656e42206973207a65726f2061646472657373000000000081525060200191505060405180910390fd5b60008873ffffffffffffffffffffffffffffffffffffffff16631feeece26040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1157600080fd5b505afa158015610b25573d6000803e3d6000fd5b505050506040513d6020811015610b3b57600080fd5b8101908080519060200190929190505050905060008873ffffffffffffffffffffffffffffffffffffffff16631feeece26040518163ffffffff1660e01b815260040160206040518083038186803b158015610b9657600080fd5b505afa158015610baa573d6000803e3d6000fd5b505050506040513d6020811015610bc057600080fd5b81019080805190602001909291905050509050610bdb610cb8565b600081600060038110610bea57fe5b6020020181815250508281600160038110610c0157fe5b6020020181815250508181600260038110610c1857fe5b602002018181525050610c29610cda565b6040816060846104055afa610c3d57600080fd5b80600060028110610c4a57fe5b602002015181600160028110610c5c57fe5b60200201519950995050505050505050509250929050565b6040518060c00160405280600690602082028038833980820191505090505090565b6040518060200160405280600190602082028038833980820191505090505090565b6040518060600160405280600390602082028038833980820191505090505090565b604051806040016040528060029060208202803883398082019150509050509056fea26469706673582212203320fbc23d712e9537ae08f7e2655ceecce971fb8d224e37c1aa527fa73b7c8264736f6c63430006000033',
      '',
      'a26469706673582212203320fbc23d712e9537ae08f7e2655ceecce971fb8d224e37c1aa527fa73b7c8264736f6c63430006000033',
      0,
      0,
      '2020-10-01 00:00:00'
    );
  
  INSERT INTO verified_contract 
    (address, name, filename, source, runs, optimization, compiler_version, compiled_data, args, target, type, contract_data)
  VALUES
  -- REEF
    (
      '0x0000000000000000000000000000000001000000',
      'REEFERC20',
      'contracts/tmp/ReefERC20.sol',
      '{"contracts/tmp/ReefERC20.sol":"// SPDX-License-Identifier: Apache-2.0\n\n// Based on ERC20 implementation of @openzeppelin/contracts (v2.5.0 and v3.1.0):\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20.sol\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.1.0/contracts/token/ERC20/ERC20.sol\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../token/IMultiCurrency.sol\";\nimport \"../token/MultiCurrency.sol\";\n\ncontract REEFERC20 is IERC20, IMultiCurrency {\n    using SafeMath for uint256;\n\n    mapping (address => mapping (address => uint256)) private _allowances;\n\n    uint256 private constant _currencyId = 0x0;\n\n    string private constant _name = \"Reef\";\n    string private constant _symbol = \"REEF\";\n    uint8 private constant _decimals = 18;\n\n    /**\n     * @dev Returns the currencyId of the token.\n     */\n    function currencyId() public view override returns (uint256) {\n        return _currencyId;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     */\n    function decimals() public view returns (uint8) {\n        return _decimals;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view override returns (uint256) {\n        return MultiCurrency.totalSupply (_currencyId);\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view override returns (uint256) {\n        return MultiCurrency.balanceOf (_currencyId, account);\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `recipient` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address recipient, uint256 amount) public override returns (bool) {\n        _transfer(msg.sender, recipient, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public override returns (bool) {\n        _approve(msg.sender, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20};\n     *\n     * Requirements:\n     * - `sender` and `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     * - the caller must have allowance for `sender`\"s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {\n        _transfer(sender, recipient, amount);\n        _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n        _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n        _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n        return true;\n    }\n\n    /**\n     * @dev Moves tokens `amount` from `sender` to `recipient`.\n     *\n     * This is internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `sender` cannot be the zero address.\n     * - `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     */\n    function _transfer(address sender, address recipient, uint256 amount) internal {\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n        MultiCurrency.transfer(_currencyId, sender, recipient, amount);\n\n        emit Transfer(sender, recipient, amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n     *\n     * This is internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n}\n","contracts/token/MultiCurrency.sol":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\nlibrary MultiCurrency {\n    function totalSupply(uint256 currencyId) internal view returns (uint256) {\n        uint256[2] memory input;\n\n        input[0] = 0;\n        input[1] = currencyId;\n\n        uint256[1] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000400, input, 0x40, output, 0x20)\n            ) {\n                revert(0, 0)\n            }\n        }\n\n        return output[0];\n    }\n\n    function balanceOf(uint256 currencyId, address account) internal view returns (uint256) {\n        uint256[3] memory input;\n\n        input[0] = 1;\n        input[1] = currencyId;\n        input[2] = uint256(account);\n\n        uint256[1] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000400, input, 0x60, output, 0x20)\n            ) {\n                revert(0, 0)\n            }\n        }\n\n        return output[0];\n    }\n\n    function transfer(uint256 currencyId, address sender, address recipient, uint256 amount) internal view {\n        uint256[5] memory input;\n\n        input[0] = 2;\n        input[1] = currencyId;\n        input[2] = uint256(sender);\n        input[3] = uint256(recipient);\n        input[4] = amount;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000400, input, 0xA0, 0x00, 0x00)\n            ) {\n                revert(0, 0)\n            }\n        }\n    }\n}\n","contracts/token/IMultiCurrency.sol":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\ninterface IMultiCurrency {\n    function currencyId() external view returns (uint256);\n}\n","@openzeppelin/contracts/math/SafeMath.sol":"pragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity\"s arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it\"s recommended to use it always.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity\"s `+` operator.\n     *\n     * Requirements:\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity\"s `-` operator.\n     *\n     * Requirements:\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return sub(a, b, \"SafeMath: subtraction overflow\");\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity\"s `-` operator.\n     *\n     * Requirements:\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b <= a, errorMessage);\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity\"s `*` operator.\n     *\n     * Requirements:\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring \"a\" not being zero, but the\n        // benefit is lost if \"b\" is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity\"s `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return div(a, b, \"SafeMath: division by zero\");\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity\"s `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        // Solidity only automatically asserts when dividing by 0\n        require(b > 0, errorMessage);\n        uint256 c = a / b;\n        // assert(a == b * c + a % b); // There is no case in which this doesn\"t hold\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts when dividing by zero.\n     *\n     * Counterpart to Solidity\"s `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return mod(a, b, \"SafeMath: modulo by zero\");\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts with custom message when dividing by zero.\n     *\n     * Counterpart to Solidity\"s `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b != 0, errorMessage);\n        return a % b;\n    }\n}\n","@openzeppelin/contracts/token/ERC20/IERC20.sol":"pragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller\"s account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller\"s tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender\"s allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller\"s\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"}',
      200,
      true,
      'v0.6.0+commit.26b70077',
      '{"REEFERC20":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"currencyId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}],"MultiCurrency":[],"IMultiCurrency":[{"inputs":[],"name":"currencyId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"SafeMath":[],"IERC20":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]}',
      '[]',
      '',
      'ERC20',
      '{"name": "REEF", "symbol": "REEF", "decimals": 18}'
    ),
  -- RUSD
    (
      '0x0000000000000000000000000000000001000001',
      'RUSDERC20',
      'contracts/tmp/Reef DollarERC20.sol',
      '{"contracts/tmp/Reef DollarERC20.sol":"// SPDX-License-Identifier: Apache-2.0\n\n// Based on ERC20 implementation of @openzeppelin/contracts (v2.5.0 and v3.1.0):\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20.sol\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.1.0/contracts/token/ERC20/ERC20.sol\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../token/IMultiCurrency.sol\";\nimport \"../token/MultiCurrency.sol\";\n\ncontract RUSDERC20 is IERC20, IMultiCurrency {\n    using SafeMath for uint256;\n\n    mapping (address => mapping (address => uint256)) private _allowances;\n\n    uint256 private constant _currencyId = 0x100;\n\n    string private constant _name = \"Reef Dollar\";\n    string private constant _symbol = \"RUSD\";\n    uint8 private constant _decimals = 18;\n\n    /**\n     * @dev Returns the currencyId of the token.\n     */\n    function currencyId() public view override returns (uint256) {\n        return _currencyId;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     */\n    function decimals() public view returns (uint8) {\n        return _decimals;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view override returns (uint256) {\n        return MultiCurrency.totalSupply (_currencyId);\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view override returns (uint256) {\n        return MultiCurrency.balanceOf (_currencyId, account);\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `recipient` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address recipient, uint256 amount) public override returns (bool) {\n        _transfer(msg.sender, recipient, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public override returns (bool) {\n        _approve(msg.sender, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20};\n     *\n     * Requirements:\n     * - `sender` and `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     * - the caller must have allowance for `sender`\"s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {\n        _transfer(sender, recipient, amount);\n        _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n        _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n        _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n        return true;\n    }\n\n    /**\n     * @dev Moves tokens `amount` from `sender` to `recipient`.\n     *\n     * This is internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `sender` cannot be the zero address.\n     * - `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     */\n    function _transfer(address sender, address recipient, uint256 amount) internal {\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n        MultiCurrency.transfer(_currencyId, sender, recipient, amount);\n\n        emit Transfer(sender, recipient, amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n     *\n     * This is internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n}\n","contracts/token/MultiCurrency.sol":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\nlibrary MultiCurrency {\n    function totalSupply(uint256 currencyId) internal view returns (uint256) {\n        uint256[2] memory input;\n\n        input[0] = 0;\n        input[1] = currencyId;\n\n        uint256[1] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000400, input, 0x40, output, 0x20)\n            ) {\n                revert(0, 0)\n            }\n        }\n\n        return output[0];\n    }\n\n    function balanceOf(uint256 currencyId, address account) internal view returns (uint256) {\n        uint256[3] memory input;\n\n        input[0] = 1;\n        input[1] = currencyId;\n        input[2] = uint256(account);\n\n        uint256[1] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000400, input, 0x60, output, 0x20)\n            ) {\n                revert(0, 0)\n            }\n        }\n\n        return output[0];\n    }\n\n    function transfer(uint256 currencyId, address sender, address recipient, uint256 amount) internal view {\n        uint256[5] memory input;\n\n        input[0] = 2;\n        input[1] = currencyId;\n        input[2] = uint256(sender);\n        input[3] = uint256(recipient);\n        input[4] = amount;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000400, input, 0xA0, 0x00, 0x00)\n            ) {\n                revert(0, 0)\n            }\n        }\n    }\n}\n","contracts/token/IMultiCurrency.sol":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\ninterface IMultiCurrency {\n    function currencyId() external view returns (uint256);\n}\n","@openzeppelin/contracts/math/SafeMath.sol":"pragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity\"s arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it\"s recommended to use it always.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity\"s `+` operator.\n     *\n     * Requirements:\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity\"s `-` operator.\n     *\n     * Requirements:\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return sub(a, b, \"SafeMath: subtraction overflow\");\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity\"s `-` operator.\n     *\n     * Requirements:\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b <= a, errorMessage);\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity\"s `*` operator.\n     *\n     * Requirements:\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring \"a\" not being zero, but the\n        // benefit is lost if \"b\" is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity\"s `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return div(a, b, \"SafeMath: division by zero\");\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity\"s `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        // Solidity only automatically asserts when dividing by 0\n        require(b > 0, errorMessage);\n        uint256 c = a / b;\n        // assert(a == b * c + a % b); // There is no case in which this doesn\"t hold\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts when dividing by zero.\n     *\n     * Counterpart to Solidity\"s `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return mod(a, b, \"SafeMath: modulo by zero\");\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts with custom message when dividing by zero.\n     *\n     * Counterpart to Solidity\"s `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b != 0, errorMessage);\n        return a % b;\n    }\n}\n","@openzeppelin/contracts/token/ERC20/IERC20.sol":"pragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller\"s account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller\"s tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender\"s allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller\"s\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"}',
      200,
      true,
      'v0.6.0+commit.26b70077',
      '{"RUSDERC20":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"currencyId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}],"MultiCurrency":[],"IMultiCurrency":[{"inputs":[],"name":"currencyId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"SafeMath":[],"IERC20":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]}', 
      '[]',
      '',
      'ERC20',
      '{"name": "RUSD", "symbol": "RUSD", "decimals": 18}'
    ),
  -- StateRent
    (
      '0x0000000000000000000000000000000000000800',
      'StateRent',
      'contracts/state_rent/StateRent.sol',
      '{"contracts/state_rent/StateRent.sol":"pragma solidity ^0.6.0;\n\nimport \"./StateRentLib.sol\";\n\ncontract StateRent {\n    event TransferredMaintainer(address indexed contract_address, address indexed new_maintainer);\n    \n    /**\n     * @dev Returns the const of NewContractExtraBytes.\n     */\n    function newContractExtraBytes() public view returns (uint256) {\n        return StateRentLib.newContractExtraBytes();\n    }\n\n    /**\n     * @dev Returns the const of StorageDepositPerByte.\n     */\n    function storageDepositPerByte() public view returns (uint256) {\n        return StateRentLib.storageDepositPerByte();\n    }\n\n    /**\n     * @dev Returns the maintainer of the contract.\n     */\n    function maintainerOf(address contract_address)\n        public\n        view\n        returns (address)\n    {\n        return StateRentLib.maintainerOf(contract_address);\n    }\n\n    /**\n     * @dev Returns the const of DeveloperDeposit.\n     */\n    function developerDeposit() public view returns (uint256) {\n        return StateRentLib.developerDeposit();\n    }\n\n    /**\n     * @dev Returns the const of DeploymentFee.\n     */\n    function deploymentFee() public view returns (uint256) {\n        return StateRentLib.deploymentFee();\n    }\n\n    /**\n     * @dev Transfer the maintainer of the contract.\n     * Returns a boolean value indicating whether the operation succeeded.\n     */\n    function transferMaintainer(\n        address contract_address,\n        address new_maintainer\n    ) public returns (bool) {\n        _transferMaintainer(msg.sender, contract_address, new_maintainer);\n        return true;\n    }\n\n    function _transferMaintainer(\n        address sender,\n        address contract_address,\n        address new_maintainer\n    ) internal {\n        require(sender != address(0), \"StateRent: the sender is the zero address\");\n        require(contract_address != address(0), \"StateRent: the contract_address is the zero address\");\n        require(new_maintainer != address(0), \"StateRent: the new_maintainer is the zero address\");\n\n        StateRentLib.transferMaintainer(msg.sender, contract_address, new_maintainer);\n        emit TransferredMaintainer(contract_address, new_maintainer);\n    }\n}\n\n","contracts/state_rent/StateRentLit.sol":"pragma solidity ^0.6.0;\n\nlibrary StateRentLib {\n    function newContractExtraBytes() internal view returns (uint256) {\n        uint256[1] memory input;\n\n        input[0] = 0;\n\n        uint256[1] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000402, input, 0x20, output, 0x20)\n            ) {\n                revert(0, 0)\n            }\n        }\n        return output[0];\n    }\n\n    function storageDepositPerByte() internal view returns (uint256) {\n        uint256[1] memory input;\n\n        input[0] = 1;\n\n        uint256[1] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000402, input, 0x20, output, 0x20)\n            ) {\n                revert(0, 0)\n            }\n        }\n        return output[0];\n    }\n\n    function maintainerOf(address contract_address)\n        internal\n        view\n        returns (address)\n    {\n        uint256[2] memory input;\n\n        input[0] = 2;\n        input[1] = uint256(contract_address);\n\n        uint256[1] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000402, input, 0x40, output, 0x20)\n            ) {\n                revert(0, 0)\n            }\n        }\n        return address(output[0]);\n    }\n\n    function developerDeposit() internal view returns (uint256) {\n        uint256[1] memory input;\n\n        input[0] = 3;\n\n        uint256[1] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000402, input, 0x20, output, 0x20)\n            ) {\n                revert(0, 0)\n            }\n        }\n        return output[0];\n    }\n\n    function deploymentFee() internal view returns (uint256) {\n        uint256[1] memory input;\n\n        input[0] = 4;\n\n        uint256[1] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000402, input, 0x20, output, 0x20)\n            ) {\n                revert(0, 0)\n            }\n        }\n        return output[0];\n    }\n\n    function transferMaintainer(\n        address sender,\n        address contract_address,\n        address new_maintainer\n    ) internal view {\n        uint256[4] memory input;\n\n        input[0] = 128;\n        input[1] = uint256(sender);\n        input[2] = uint256(contract_address);\n        input[3] = uint256(new_maintainer);\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000402, input, 0x80, 0x00, 0x00)\n            ) {\n                revert(0, 0)\n            }\n        }\n    }\n}\n\n"}',
      200,
      true,
      'v0.6.0+commit.26b70077',
      '{"StateRent":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contract_address","type":"address"},{"indexed":true,"internalType":"address","name":"new_maintainer","type":"address"}],"name":"TransferredMaintainer","type":"event"},{"inputs":[],"name":"newContractExtraBytes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"storageDepositPerByte","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contract_address","type":"address"}],"name":"maintainerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"developerDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deploymentFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contract_address","type":"address"},{"internalType":"address","name":"new_maintainer","type":"address"}],"name":"transferMaintainer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}],"StateRentLib":[]}',
      '[]', 
      '',
      'other',
      null
    ),
  -- Oracle
    (
      '0x0000000000000000000000000000000000000801',
      'Oracle',
      'contracts/oracle/Oracle.sol',
      '{"contracts/oracle/Oracle.sol":"pragma solidity ^0.6.0;\n\nimport \"../utils/SystemContract.sol\";\nimport \"../token/IMultiCurrency.sol\";\n\ncontract Oracle is SystemContract {\n    /**\n     * @dev Get the price of the currency_id.\n     * Returns the (price, timestamp)\n     */\n    function getPrice(address token)\n    public\n    view\n    systemContract(token)\n    returns (uint256, uint256)\n    {\n        require(token != address(0), \"Oracle: token is zero address\");\n\n        uint256 currencyId = IMultiCurrency(token).currencyId();\n\n        uint256[2] memory input;\n\n        input[0] = 0;\n        input[1] = currencyId;\n\n        uint256[2] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000403, input, 0x40, output, 0x40)\n            ) {\n                revert(0, 0)\n            }\n        }\n        return (output[0], output[1]);\n    }\n}\n","contracts/token/IMultiCurrency.sol":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\ninterface IMultiCurrency {\n    function currencyId() external view returns (uint256);\n}\n","contracts/utils/SystemContract.sol":"pragma solidity ^0.6.0;\n\ncontract SystemContract {\n    modifier systemContract(address addr) {\n        bytes memory addrBytes = abi.encodePacked(addr);\n        for (uint i = 0; i < 12; i++) {\n            require(addrBytes[i] == 0, \"not a system contract\");\n        }\n        _;\n    }\n}\n"}',
      200,
      true,
      'v0.6.0+commit.26b70077',
      '{"Oracle":[{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"IMultiCurrency":[{"inputs":[],"name":"currencyId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"SystemContract":[]}',
      '[]', 
      '',
      'other',
      null
    ),
  -- Schedule
    (
      '0x0000000000000000000000000000000000000802',
      'Schedule',
      'contracts/schedule/Schedule.sol',
      '{"contracts/schedule/Schedule.sol":"pragma solidity ^0.6.0;\n\ncontract SystemContract {\n    modifier systemContract(address addr) {\n        bytes memory addrBytes = abi.encodePacked(addr);\n        for (uint i = 0; i < 12; i++) {\n            require(addrBytes[i] == 0, \"not a system contract\");\n        }\n        _;\n    }\n}\n","contracts/schedule/ISchedule.sol":"pragma solidity ^0.6.0;\n\ninterface ISchedule {\n    event ScheduledCall(address indexed sender, address indexed contract_address, bytes task_id);\n    event CanceledCall(address indexed sender, bytes task_id);\n    event RescheduledCall(address indexed sender, bytes task_id);\n\n    // Schedule call the contract.\n    // Returns a boolean value indicating whether the operation succeeded.\n    function scheduleCall(\n        address contract_address, // The contract address to be called in future.\n        uint256 value, // How much native token to send alone with the call.\n        uint256 gas_limit, // The gas limit for the call. Corresponding fee will be reserved upfront and refunded after call.\n        uint256 storage_limit, // The storage limit for the call. Corresponding fee will be reserved upfront and refunded after call.\n        uint256 min_delay, // Minimum number of blocks before the scheduled call will be called.\n        bytes calldata input_data // The input data to the call.\n    )\n    external\n    returns (bool); // Returns a boolean value indicating whether the operation succeeded.\n\n    // Cancel schedule call the contract.\n    // Returns a boolean value indicating whether the operation succeeded.\n    function cancelCall(\n        bytes calldata task_id // The task id of the scheduler. Get it from the `ScheduledCall` event.\n    )\n    external\n    returns (bool); // Returns a boolean value indicating whether the operation succeeded.\n\n    // Reschedule call the contract.\n    // Returns a boolean value indicating whether the operation succeeded.\n    function rescheduleCall(\n        uint256 min_delay, // Minimum number of blocks before the scheduled call will be called.\n        bytes calldata task_id // The task id of the scheduler. Get it from the `ScheduledCall` event.\n    )\n    external\n    returns (bool); // Returns a boolean value indicating whether the operation succeeded.\n}\n","contracts/schedule/ScheduleLib.sol":"pragma solidity ^0.6.0;\n\nlibrary ScheduleCallLib {\n    function scheduleCall(\n        address sender,\n        address contract_address,\n        uint256 value,\n        uint256 gas_limit,\n        uint256 storage_limit,\n        uint256 min_delay,\n        bytes memory input_data\n    ) internal view returns (bytes memory) {\n        uint input_data_capacity = (input_data.length + 31)/32;\n        // param + input_len + input_data\n        uint input_size = 7 + 1 + input_data_capacity;\n\n        // Dynamic arrays will add the array size to the front of the array, pre-compile needs to deal with the `size`.\n        uint256[] memory input = new uint256[](input_size);\n\n        input[0] = 0;\n        input[1] = uint256(sender);\n        input[2] = uint256(contract_address);\n        input[3] = uint256(value);\n        input[4] = uint256(gas_limit);\n        input[5] = uint256(storage_limit);\n        input[6] = uint256(min_delay);\n\n        // input_len\n        input[7] = uint256(input_data.length);\n\n        for (uint i = 0; i < input_data_capacity; i++) {\n            input[8 + i] = bytes2Uint(input_data, i);\n        }\n\n        // Dynamic arrays will add the array size to the front of the array, so need extra 1 size.\n        uint input_size_32 = (input_size + 1) * 32;\n\n        uint256[3] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000404, input, input_size_32, output, 0x60)\n            ) {\n                revert(0, 0)\n            }\n        }\n\n        bytes memory task_id = new bytes(output[0]);\n        bytes memory result = abi.encodePacked(output[1], output[2]);\n        for (uint i = 0; i < task_id.length; i++) {\n            task_id[i] = result[i];\n        }\n\n        return task_id;\n    }\n\n    function cancelCall(\n        address sender,\n        bytes memory task_id\n    ) internal {\n        uint input_data_capacity = (task_id.length + 31)/32;\n        // param + task_id_len + task_id\n        uint input_size = 2 + 1 + input_data_capacity;\n        uint256[] memory input = new uint256[](input_size);\n\n        input[0] = 1;\n        input[1] = uint256(sender);\n\n        // task_id_len\n        input[2] = uint256(task_id.length);\n\n        for (uint i = 0; i < input_data_capacity; i++) {\n            input[3 + i] = bytes2Uint(task_id, i);\n        }\n\n        // Dynamic arrays will add the array size to the front of the array, so need extra 1 size.\n        uint input_size_32 = (input_size + 1) * 32;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000404, input, input_size_32, 0x00, 0x00)\n            ) {\n                revert(0, 0)\n            }\n        }\n    }\n\n    function rescheduleCall(\n        address sender,\n        uint256 min_delay,\n        bytes memory task_id\n    ) internal {\n        uint input_data_capacity = (task_id.length + 31)/32;\n        // param + task_id_len + task_id\n        uint input_size = 3 + 1 + input_data_capacity;\n        uint256[] memory input = new uint256[](input_size);\n\n        input[0] = 2;\n        input[1] = uint256(sender);\n        input[2] = uint256(min_delay);\n\n        // task_id_len\n        input[3] = uint256(task_id.length);\n\n        for (uint i = 0; i < input_data_capacity; i++) {\n            input[4 + i] = bytes2Uint(task_id, i);\n        }\n\n        // Dynamic arrays will add the array size to the front of the array, so need extra 1 size.\n        uint input_size_32 = (input_size + 1) * 32;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000404, input, input_size_32, 0x00, 0x00)\n            ) {\n                revert(0, 0)\n            }\n        }\n    }\n\n    function bytes2Uint(bytes memory bs, uint index) public pure returns (uint) {\n        // require(bs.length >= start + 32, \"slicing out of range\");\n        // if bs.length < start + 32, 0 will be added at the end.\n        uint start = index * 32;\n        uint x;\n        assembly {\n            x := mload(add(bs, add(0x20, start)))\n        }\n        return x;\n    }\n}\n\n"}',
      200,
      true,
      'v0.6.0+commit.26b70077',
      '{"Schedule":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes","name":"task_id","type":"bytes"}],"name":"CanceledCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes","name":"task_id","type":"bytes"}],"name":"RescheduledCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"contract_address","type":"address"},{"indexed":false,"internalType":"bytes","name":"task_id","type":"bytes"}],"name":"ScheduledCall","type":"event"},{"inputs":[{"internalType":"address","name":"contract_address","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"gas_limit","type":"uint256"},{"internalType":"uint256","name":"storage_limit","type":"uint256"},{"internalType":"uint256","name":"min_delay","type":"uint256"},{"internalType":"bytes","name":"input_data","type":"bytes"}],"name":"scheduleCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"task_id","type":"bytes"}],"name":"cancelCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"min_delay","type":"uint256"},{"internalType":"bytes","name":"task_id","type":"bytes"}],"name":"rescheduleCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}],"ISchedule":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes","name":"task_id","type":"bytes"}],"name":"CanceledCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes","name":"task_id","type":"bytes"}],"name":"RescheduledCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"contract_address","type":"address"},{"indexed":false,"internalType":"bytes","name":"task_id","type":"bytes"}],"name":"ScheduledCall","type":"event"},{"inputs":[{"internalType":"address","name":"contract_address","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"gas_limit","type":"uint256"},{"internalType":"uint256","name":"storage_limit","type":"uint256"},{"internalType":"uint256","name":"min_delay","type":"uint256"},{"internalType":"bytes","name":"input_data","type":"bytes"}],"name":"scheduleCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"task_id","type":"bytes"}],"name":"cancelCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"min_delay","type":"uint256"},{"internalType":"bytes","name":"task_id","type":"bytes"}],"name":"rescheduleCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}],"ScheduleCallLib":[{"inputs":[{"internalType":"bytes","name":"bs","type":"bytes"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"bytes2Uint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}]}', 
      '[]', 
      '',
      'other',
      null
    ),
  -- DEX
    (
      '0x0000000000000000000000000000000000000803',
      'DEX',
      'contracts/dex/DEX.sol',
      '{"contracts/dex/DEX.sol":"pragma solidity ^0.6.0;\n\nimport \"./IDEX.sol\";\nimport \"../utils/SystemContract.sol\";\nimport \"../token/IMultiCurrency.sol\";\n\ncontract DEX is SystemContract, IDEX {\n    /**\n     * @dev Get liquidity of the currency_id_a and currency_id_b.\n     * Returns (liquidity_a, liquidity_b)\n     */\n    function getLiquidity(address tokenA, address tokenB)\n    public\n    view\n    override\n    systemContract(tokenA)\n    systemContract(tokenB)\n    returns (uint256, uint256)\n    {\n        require(tokenA != address(0), \"DEX: tokenA is zero address\");\n        require(tokenB != address(0), \"DEX: tokenB is zero address\");\n\n        uint256 currencyIdA = IMultiCurrency(tokenA).currencyId();\n        uint256 currencyIdB = IMultiCurrency(tokenB).currencyId();\n\n        uint256[3] memory input;\n\n        input[0] = 0;\n        input[1] = currencyIdA;\n        input[2] = currencyIdB;\n\n        uint256[2] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000405, input, 0x60, output, 0x40)\n            ) {\n                revert(0, 0)\n            }\n        }\n        return (output[0], output[1]);\n    }\n\n    /**\n     * @dev Swap with exact supply.\n     * Returns (target_amount)\n     */\n    function swapWithExactSupply(address tokenA, address tokenB, uint256 supplyAmount, uint256 minTargetAmount)\n    public\n    view\n    override\n    systemContract(tokenA)\n    systemContract(tokenB)\n    returns (uint256) {\n        require(tokenA != address(0), \"DEX: tokenA is zero address\");\n        require(tokenB != address(0), \"DEX: tokenB is zero address\");\n        require(supplyAmount != 0, \"DEX: supplyAmount is zero\");\n\n        uint256 currencyIdA = IMultiCurrency(tokenA).currencyId();\n        uint256 currencyIdB = IMultiCurrency(tokenB).currencyId();\n\n        uint256[6] memory input;\n\n        input[0] = 1;\n        input[1] = uint256(msg.sender);\n        input[2] = currencyIdA;\n        input[3] = currencyIdB;\n        input[4] = supplyAmount;\n        input[5] = minTargetAmount;\n\n        uint256[1] memory output;\n\n        assembly {\n            if iszero(\n                staticcall(gas(), 0x0000000000000000405, input, 0xC0, output, 0x20)\n            ) {\n                revert(0, 0)\n            }\n        }\n        return output[0];\n    }\n}\n","contracts/dex/IDEX.sol":"pragma solidity ^0.6.0;\n\ninterface IDEX {\n    // Get liquidity of the currency_id_a and currency_id_b.\n    // Returns (liquidity_a, liquidity_b)\n    function getLiquidity(address tokenA, address tokenB) external view returns (uint256, uint256);\n\n    // Swap with exact supply.\n    // Returns (target_amount)\n    function swapWithExactSupply(address tokenA, address tokenB, uint256 supplyAmount, uint256 minTargetAmount) external view returns (uint256);\n}\n","contracts/token/IMultiCurrency.sol":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\ninterface IMultiCurrency {\n    function currencyId() external view returns (uint256);\n}\n","contracts/utils/SystemContract.sol":"pragma solidity ^0.6.0;\n\ncontract SystemContract {\n    modifier systemContract(address addr) {\n        bytes memory addrBytes = abi.encodePacked(addr);\n        for (uint i = 0; i < 12; i++) {\n            require(addrBytes[i] == 0, \"not a system contract\");\n        }\n        _;\n    }\n}\n"}',
      200,
      true,
      'v0.6.0+commit.26b70077',
      '{"DEX":[{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"getLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"supplyAmount","type":"uint256"},{"internalType":"uint256","name":"minTargetAmount","type":"uint256"}],"name":"swapWithExactSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"IDEX":[{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"getLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"supplyAmount","type":"uint256"},{"internalType":"uint256","name":"minTargetAmount","type":"uint256"}],"name":"swapWithExactSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"IMultiCurrency":[{"inputs":[],"name":"currencyId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"SystemContract":[]}',
      '[]', 
      '',
      'other',
      null
    );
  