{
  "address": "0x58e0383e21f25dab957f6664240445a514e9f5e8",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "offset",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "length",
          "type": "uint256"
        }
      ],
      "name": "OffsetOutOfBoundsError",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "key",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "data",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "sig",
          "type": "bytes"
        }
      ],
      "name": "verify",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
  ],
  "contractName": "RSASHA1Algorithm",
  "sourceName": "contracts/dnssec-oracle/algorithms/RSASHA1Algorithm.sol",
  "bytecode": "0x6080604052348015600f57600080fd5b506110c48061001f6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063de8f50a114610030575b600080fd5b61004361003e366004610eaf565b610057565b604051901515815260200160405180910390f35b600060608060006100a260048b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506102c39050565b60ff169050801561016e576100f760058261ffff168c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294939250506102fc9050565b9250610167610107826005610f84565b61ffff9081169060059061011d9085168d610f9e565b6101279190610f9e565b8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294939250506102fc9050565b9150610227565b6101b260058b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506103599050565b90506101fe60078261ffff168c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294939250506102fc9050565b925061022461020e826007610f84565b61ffff9081169060079061011d9085168d610f9e565b91505b6102b5828488888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506102b08c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061037692505050565b610945565b9a9950505050505050505050565b60006102d9836102d4846001610fb1565b6109e2565b8282815181106102eb576102eb610fc4565b016020015160f81c90505b92915050565b60608167ffffffffffffffff81111561031757610317610ff3565b6040519080825280601f01601f191660200182016040528015610341576020820181803683370190505b509050610352848483600086610a37565b9392505050565b600061036a836102d4846002610fb1565b50016020015160f01c90565b60006040518251602084019350604067ffffffffffffffc0600183011601600982820310600181036103a9576040820191505b50776745230100efcdab890098badcfe001032547600c3d2e1f0610419565b60008383101561035257508082015192829003926020841015610352577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208590036101000a0119169392505050565b60005b828110156108c55761042f8482896103c8565b855261043f8460208301896103c8565b60208601526040818503106001810361045b5760808286038701535b506040830381146001810361047857602086018051600887021790525b5060405b6080811015610578578581017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08101517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc88201517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08301517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff48401516002911891909218189081027ffffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffe1663800000009091047c010000000100000001000000010000000100000001000000010000000116179052600c0161047c565b5060805b610140811015610679578581017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808101517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff908201517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08301517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe88401516004911891909218189081027ffffffffcfffffffcfffffffcfffffffcfffffffcfffffffcfffffffcfffffffc1663400000009091047c03000000030000000300000003000000030000000300000003000000031617905260180161057c565b508160008060005b605081101561089b576014810480156106b157600181146106ed576002811461072757600381146107665761079c565b6501000000000085046a0100000000000000000000860481186f01000000000000000000000000000000870416189350635a827999925061079c565b6501000000000085046f0100000000000000000000000000000086046a0100000000000000000000870418189350636ed9eba1925061079c565b6a010000000000000000000085046f010000000000000000000000000000008604818117650100000000008804169116179350638f1bbcdc925061079c565b6501000000000085046f0100000000000000000000000000000086046a010000000000000000000087041818935063ca62c1d692505b50601f770800000000000000000000000000000000000000000000008504168063ffffffe073080000000000000000000000000000000000000087041617905080840190508063ffffffff86160190508083019050807c0100000000000000000000000000000000000000000000000000000000600484028c015104019050740100000000000000000000000000000000000000008102650100000000008604179450506a0100000000000000000000633fffffff6a040000000000000000000086041663c00000006604000000000000870416170277ffffffff00ffffffff000000000000ffffffff00ffffffff8516179350600181019050610681565b5050509190910177ffffffff00ffffffff00ffffffff00ffffffff00ffffffff169060400161041c565b506c0100000000000000000000000063ffffffff821667ffffffff000000006101008404166bffffffff0000000000000000620100008504166fffffffff000000000000000000000000630100000086041673ffffffff000000000000000000000000000000006401000000008704161717171702945050505050919050565b600080600061098b8787876040518060400160405280600f81526020017f3021300906052b0e03021a050004140000000000000000000000000000000000815250610a6f565b915091508180156109d757506109af601482516109a89190610f9e565b8290610cd4565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008581169116145b979650505050505050565b8151811115610a335781516040517f8a3c1cfb000000000000000000000000000000000000000000000000000000008152610a2a918391600401918252602082015260400190565b60405180910390fd5b5050565b610a45856102d48387610fb1565b610a53836102d48385610fb1565b610a6882602085010185602088010183610cf1565b5050505050565b60006060600080610a81888888610d77565b91509150811580610a9457508751815114155b15610aa657600093509150610ccb9050565b80600081518110610ab957610ab9610fc4565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016151580610b47575080600181518110610afb57610afb610fc4565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f010000000000000000000000000000000000000000000000000000000000000014155b15610b5957600093509150610ccb9050565b60008551600f14610b6b576020610b6e565b60145b60ff1690506000818351610b829190610f9e565b90506000875182610b939190610f9e565b905083610ba1600183610f9e565b81518110610bb157610bb1610fc4565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615610bee57600084965096505050505050610ccb565b8751610c0290859083908b90600090610d92565b610c1757600084965096505050505050610ccb565b60006002610c26600184610f9e565b610c309190610f9e565b90506008811015610c4d5760008597509750505050505050610ccb565b60025b610c5b600184610f9e565b811015610cbd57858181518110610c7457610c74610fc4565b01602001517fff0000000000000000000000000000000000000000000000000000000000000090811614610cb5576000869850985050505050505050610ccb565b600101610c50565b506001975093955050505050505b94509492505050565b6000610ce5836102d4846014610fb1565b50016014015160601b90565b5b601f811115610d305781518352602092830192909101907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001610cf2565b8015610d7257815183516001602084900360031b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161783525b505050565b60006060610d86838587610db5565b91509150935093915050565b6000610d9f848484610e4c565b610daa878785610e4c565b149695505050505050565b600060606000855185518551888888604051602001610dd996959493929190611052565b6040516020818303038152906040529050835167ffffffffffffffff811115610e0457610e04610ff3565b6040519080825280601f01601f191660200182016040528015610e2e576020820181803683370190505b50915083516020830182516020840160055afa925050935093915050565b6000610e5c846102d48486610fb1565b5091016020012090565b60008083601f840112610e7857600080fd5b50813567ffffffffffffffff811115610e9057600080fd5b602083019150836020828501011115610ea857600080fd5b9250929050565b60008060008060008060608789031215610ec857600080fd5b863567ffffffffffffffff811115610edf57600080fd5b610eeb89828a01610e66565b909750955050602087013567ffffffffffffffff811115610f0b57600080fd5b610f1789828a01610e66565b909550935050604087013567ffffffffffffffff811115610f3757600080fd5b610f4389828a01610e66565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff81811683821601908111156102f6576102f6610f55565b818103818111156102f6576102f6610f55565b808201808211156102f6576102f6610f55565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000815160005b818110156110435760208185018101518683015201611029565b50600093019283525090919050565b868152856020820152846040820152600061108261107c6110766060850188611022565b86611022565b84611022565b9897505050505050505056fea264697066735822122016a90630cdc11b5bbd0fa46e4576311b3615cc9991b0025f3ed883bf3156890b64736f6c634300081a0033",
  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063de8f50a114610030575b600080fd5b61004361003e366004610eaf565b610057565b604051901515815260200160405180910390f35b600060608060006100a260048b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506102c39050565b60ff169050801561016e576100f760058261ffff168c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294939250506102fc9050565b9250610167610107826005610f84565b61ffff9081169060059061011d9085168d610f9e565b6101279190610f9e565b8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294939250506102fc9050565b9150610227565b6101b260058b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506103599050565b90506101fe60078261ffff168c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294939250506102fc9050565b925061022461020e826007610f84565b61ffff9081169060079061011d9085168d610f9e565b91505b6102b5828488888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506102b08c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061037692505050565b610945565b9a9950505050505050505050565b60006102d9836102d4846001610fb1565b6109e2565b8282815181106102eb576102eb610fc4565b016020015160f81c90505b92915050565b60608167ffffffffffffffff81111561031757610317610ff3565b6040519080825280601f01601f191660200182016040528015610341576020820181803683370190505b509050610352848483600086610a37565b9392505050565b600061036a836102d4846002610fb1565b50016020015160f01c90565b60006040518251602084019350604067ffffffffffffffc0600183011601600982820310600181036103a9576040820191505b50776745230100efcdab890098badcfe001032547600c3d2e1f0610419565b60008383101561035257508082015192829003926020841015610352577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208590036101000a0119169392505050565b60005b828110156108c55761042f8482896103c8565b855261043f8460208301896103c8565b60208601526040818503106001810361045b5760808286038701535b506040830381146001810361047857602086018051600887021790525b5060405b6080811015610578578581017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08101517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc88201517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08301517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff48401516002911891909218189081027ffffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffe1663800000009091047c010000000100000001000000010000000100000001000000010000000116179052600c0161047c565b5060805b610140811015610679578581017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808101517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff908201517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08301517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe88401516004911891909218189081027ffffffffcfffffffcfffffffcfffffffcfffffffcfffffffcfffffffcfffffffc1663400000009091047c03000000030000000300000003000000030000000300000003000000031617905260180161057c565b508160008060005b605081101561089b576014810480156106b157600181146106ed576002811461072757600381146107665761079c565b6501000000000085046a0100000000000000000000860481186f01000000000000000000000000000000870416189350635a827999925061079c565b6501000000000085046f0100000000000000000000000000000086046a0100000000000000000000870418189350636ed9eba1925061079c565b6a010000000000000000000085046f010000000000000000000000000000008604818117650100000000008804169116179350638f1bbcdc925061079c565b6501000000000085046f0100000000000000000000000000000086046a010000000000000000000087041818935063ca62c1d692505b50601f770800000000000000000000000000000000000000000000008504168063ffffffe073080000000000000000000000000000000000000087041617905080840190508063ffffffff86160190508083019050807c0100000000000000000000000000000000000000000000000000000000600484028c015104019050740100000000000000000000000000000000000000008102650100000000008604179450506a0100000000000000000000633fffffff6a040000000000000000000086041663c00000006604000000000000870416170277ffffffff00ffffffff000000000000ffffffff00ffffffff8516179350600181019050610681565b5050509190910177ffffffff00ffffffff00ffffffff00ffffffff00ffffffff169060400161041c565b506c0100000000000000000000000063ffffffff821667ffffffff000000006101008404166bffffffff0000000000000000620100008504166fffffffff000000000000000000000000630100000086041673ffffffff000000000000000000000000000000006401000000008704161717171702945050505050919050565b600080600061098b8787876040518060400160405280600f81526020017f3021300906052b0e03021a050004140000000000000000000000000000000000815250610a6f565b915091508180156109d757506109af601482516109a89190610f9e565b8290610cd4565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008581169116145b979650505050505050565b8151811115610a335781516040517f8a3c1cfb000000000000000000000000000000000000000000000000000000008152610a2a918391600401918252602082015260400190565b60405180910390fd5b5050565b610a45856102d48387610fb1565b610a53836102d48385610fb1565b610a6882602085010185602088010183610cf1565b5050505050565b60006060600080610a81888888610d77565b91509150811580610a9457508751815114155b15610aa657600093509150610ccb9050565b80600081518110610ab957610ab9610fc4565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016151580610b47575080600181518110610afb57610afb610fc4565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f010000000000000000000000000000000000000000000000000000000000000014155b15610b5957600093509150610ccb9050565b60008551600f14610b6b576020610b6e565b60145b60ff1690506000818351610b829190610f9e565b90506000875182610b939190610f9e565b905083610ba1600183610f9e565b81518110610bb157610bb1610fc4565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615610bee57600084965096505050505050610ccb565b8751610c0290859083908b90600090610d92565b610c1757600084965096505050505050610ccb565b60006002610c26600184610f9e565b610c309190610f9e565b90506008811015610c4d5760008597509750505050505050610ccb565b60025b610c5b600184610f9e565b811015610cbd57858181518110610c7457610c74610fc4565b01602001517fff0000000000000000000000000000000000000000000000000000000000000090811614610cb5576000869850985050505050505050610ccb565b600101610c50565b506001975093955050505050505b94509492505050565b6000610ce5836102d4846014610fb1565b50016014015160601b90565b5b601f811115610d305781518352602092830192909101907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001610cf2565b8015610d7257815183516001602084900360031b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161783525b505050565b60006060610d86838587610db5565b91509150935093915050565b6000610d9f848484610e4c565b610daa878785610e4c565b149695505050505050565b600060606000855185518551888888604051602001610dd996959493929190611052565b6040516020818303038152906040529050835167ffffffffffffffff811115610e0457610e04610ff3565b6040519080825280601f01601f191660200182016040528015610e2e576020820181803683370190505b50915083516020830182516020840160055afa925050935093915050565b6000610e5c846102d48486610fb1565b5091016020012090565b60008083601f840112610e7857600080fd5b50813567ffffffffffffffff811115610e9057600080fd5b602083019150836020828501011115610ea857600080fd5b9250929050565b60008060008060008060608789031215610ec857600080fd5b863567ffffffffffffffff811115610edf57600080fd5b610eeb89828a01610e66565b909750955050602087013567ffffffffffffffff811115610f0b57600080fd5b610f1789828a01610e66565b909550935050604087013567ffffffffffffffff811115610f3757600080fd5b610f4389828a01610e66565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff81811683821601908111156102f6576102f6610f55565b818103818111156102f6576102f6610f55565b808201808211156102f6576102f6610f55565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000815160005b818110156110435760208185018101518683015201611029565b50600093019283525090919050565b868152856020820152846040820152600061108261107c6110766060850188611022565b86611022565b84611022565b9897505050505050505056fea264697066735822122016a90630cdc11b5bbd0fa46e4576311b3615cc9991b0025f3ed883bf3156890b64736f6c634300081a0033",
  "linkReferences": {},
  "deployedLinkReferences": {},
  "immutableReferences": {},
  "inputSourceName": "project/contracts/dnssec-oracle/algorithms/RSASHA1Algorithm.sol",
  "devdoc": {
    "details": "Implements the DNSSEC RSASHA1 algorithm.",
    "errors": {
      "OffsetOutOfBoundsError(uint256,uint256)": [
        {
          "details": "`offset` was beyond `length`.       Error selector: `0x8a3c1cfb`"
        }
      ]
    },
    "kind": "dev",
    "methods": {},
    "version": 1
  },
  "evm": {
    "gasEstimates": {
      "creation": {
        "codeDepositCost": "858400",
        "executionCost": "896",
        "totalCost": "859296"
      },
      "external": {
        "verify(bytes,bytes,bytes)": "infinite"
      }
    }
  },
  "metadata": "{\"compiler\":{\"version\":\"0.8.26+commit.8a97fa7a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"OffsetOutOfBoundsError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"key\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sig\",\"type\":\"bytes\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Implements the DNSSEC RSASHA1 algorithm.\",\"errors\":{\"OffsetOutOfBoundsError(uint256,uint256)\":[{\"details\":\"`offset` was beyond `length`.       Error selector: `0x8a3c1cfb`\"}]},\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"project/contracts/dnssec-oracle/algorithms/RSASHA1Algorithm.sol\":\"RSASHA1Algorithm\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[\"project/:@ensdomains/solsha1/=npm/@ensdomains/solsha1@0.0.3/\"]},\"sources\":{\"npm/@ensdomains/solsha1@0.0.3/contracts/SHA1.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nlibrary SHA1 {\\n    event Debug(bytes32 x);\\n\\n    function sha1(bytes memory data) internal pure returns(bytes20 ret) {\\n        assembly {\\n            // Get a safe scratch location\\n            let scratch := mload(0x40)\\n\\n            // Get the data length, and point data at the first byte\\n            let len := mload(data)\\n            data := add(data, 32)\\n\\n            // Find the length after padding\\n            let totallen := add(and(add(len, 1), 0xFFFFFFFFFFFFFFC0), 64)\\n            switch lt(sub(totallen, len), 9)\\n            case 1 { totallen := add(totallen, 64) }\\n\\n            let h := 0x6745230100EFCDAB890098BADCFE001032547600C3D2E1F0\\n\\n            function readword(ptr, off, count) -> result {\\n                result := 0\\n                if lt(off, count) {\\n                    result := mload(add(ptr, off))\\n                    count := sub(count, off)\\n                    if lt(count, 32) {\\n                        let mask := not(sub(exp(256, sub(32, count)), 1))\\n                        result := and(result, mask)\\n                    }\\n                }\\n            }\\n\\n            for { let i := 0 } lt(i, totallen) { i := add(i, 64) } {\\n                mstore(scratch, readword(data, i, len))\\n                mstore(add(scratch, 32), readword(data, add(i, 32), len))\\n\\n                // If we loaded the last byte, store the terminator byte\\n                switch lt(sub(len, i), 64)\\n                case 1 { mstore8(add(scratch, sub(len, i)), 0x80) }\\n\\n                // If this is the last block, store the length\\n                switch eq(i, sub(totallen, 64))\\n                case 1 { mstore(add(scratch, 32), or(mload(add(scratch, 32)), mul(len, 8))) }\\n\\n                // Expand the 16 32-bit words into 80\\n                for { let j := 64 } lt(j, 128) { j := add(j, 12) } {\\n                    let temp := xor(xor(mload(add(scratch, sub(j, 12))), mload(add(scratch, sub(j, 32)))), xor(mload(add(scratch, sub(j, 56))), mload(add(scratch, sub(j, 64)))))\\n                    temp := or(and(mul(temp, 2), 0xFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFE), and(div(temp, 0x80000000), 0x0000000100000001000000010000000100000001000000010000000100000001))\\n                    mstore(add(scratch, j), temp)\\n                }\\n                for { let j := 128 } lt(j, 320) { j := add(j, 24) } {\\n                    let temp := xor(xor(mload(add(scratch, sub(j, 24))), mload(add(scratch, sub(j, 64)))), xor(mload(add(scratch, sub(j, 112))), mload(add(scratch, sub(j, 128)))))\\n                    temp := or(and(mul(temp, 4), 0xFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFC), and(div(temp, 0x40000000), 0x0000000300000003000000030000000300000003000000030000000300000003))\\n                    mstore(add(scratch, j), temp)\\n                }\\n\\n                let x := h\\n                let f := 0\\n                let k := 0\\n                for { let j := 0 } lt(j, 80) { j := add(j, 1) } {\\n                    switch div(j, 20)\\n                    case 0 {\\n                        // f = d xor (b and (c xor d))\\n                        f := xor(div(x, 0x100000000000000000000), div(x, 0x10000000000))\\n                        f := and(div(x, 0x1000000000000000000000000000000), f)\\n                        f := xor(div(x, 0x10000000000), f)\\n                        k := 0x5A827999\\n                    }\\n                    case 1{\\n                        // f = b xor c xor d\\n                        f := xor(div(x, 0x1000000000000000000000000000000), div(x, 0x100000000000000000000))\\n                        f := xor(div(x, 0x10000000000), f)\\n                        k := 0x6ED9EBA1\\n                    }\\n                    case 2 {\\n                        // f = (b and c) or (d and (b or c))\\n                        f := or(div(x, 0x1000000000000000000000000000000), div(x, 0x100000000000000000000))\\n                        f := and(div(x, 0x10000000000), f)\\n                        f := or(and(div(x, 0x1000000000000000000000000000000), div(x, 0x100000000000000000000)), f)\\n                        k := 0x8F1BBCDC\\n                    }\\n                    case 3 {\\n                        // f = b xor c xor d\\n                        f := xor(div(x, 0x1000000000000000000000000000000), div(x, 0x100000000000000000000))\\n                        f := xor(div(x, 0x10000000000), f)\\n                        k := 0xCA62C1D6\\n                    }\\n                    // temp = (a leftrotate 5) + f + e + k + w[i]\\n                    let temp := and(div(x, 0x80000000000000000000000000000000000000000000000), 0x1F)\\n                    temp := or(and(div(x, 0x800000000000000000000000000000000000000), 0xFFFFFFE0), temp)\\n                    temp := add(f, temp)\\n                    temp := add(and(x, 0xFFFFFFFF), temp)\\n                    temp := add(k, temp)\\n                    temp := add(div(mload(add(scratch, mul(j, 4))), 0x100000000000000000000000000000000000000000000000000000000), temp)\\n                    x := or(div(x, 0x10000000000), mul(temp, 0x10000000000000000000000000000000000000000))\\n                    x := or(and(x, 0xFFFFFFFF00FFFFFFFF000000000000FFFFFFFF00FFFFFFFF), mul(or(and(div(x, 0x4000000000000), 0xC0000000), and(div(x, 0x400000000000000000000), 0x3FFFFFFF)), 0x100000000000000000000))\\n                }\\n\\n                h := and(add(h, x), 0xFFFFFFFF00FFFFFFFF00FFFFFFFF00FFFFFFFF00FFFFFFFF)\\n            }\\n            ret := mul(or(or(or(or(and(div(h, 0x100000000), 0xFFFFFFFF00000000000000000000000000000000), and(div(h, 0x1000000), 0xFFFFFFFF000000000000000000000000)), and(div(h, 0x10000), 0xFFFFFFFF0000000000000000)), and(div(h, 0x100), 0xFFFFFFFF00000000)), and(h, 0xFFFFFFFF)), 0x1000000000000000000000000)\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x746d9b85de197afbc13182cbe4ba4f7917f19594e07c655d6a0c85fdf7460a8a\"},\"project/contracts/dnssec-oracle/algorithms/Algorithm.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\n/// @dev An interface for contracts implementing a DNSSEC (signing) algorithm.\\ninterface Algorithm {\\n    /// @dev Verifies a signature.\\n    /// @param key The public key to verify with.\\n    /// @param data The signed data to verify.\\n    /// @param signature The signature to verify.\\n    /// @return True iff the signature is valid.\\n    function verify(\\n        bytes calldata key,\\n        bytes calldata data,\\n        bytes calldata signature\\n    ) external view virtual returns (bool);\\n}\\n\",\"keccak256\":\"0xbcbdc06d72b64903e733e7ddfbf59c35c984c3eb0022baacab12c97292cc13df\"},\"project/contracts/dnssec-oracle/algorithms/ModexpPrecompile.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nlibrary ModexpPrecompile {\\n    /// @dev Computes (base ^ exponent) % modulus over big numbers.\\n    function modexp(\\n        bytes memory base,\\n        bytes memory exponent,\\n        bytes memory modulus\\n    ) internal view returns (bool success, bytes memory output) {\\n        bytes memory input = abi.encodePacked(\\n            uint256(base.length),\\n            uint256(exponent.length),\\n            uint256(modulus.length),\\n            base,\\n            exponent,\\n            modulus\\n        );\\n\\n        output = new bytes(modulus.length);\\n\\n        assembly {\\n            success := staticcall(\\n                gas(),\\n                5,\\n                add(input, 32),\\n                mload(input),\\n                add(output, 32),\\n                mload(modulus)\\n            )\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x06457e4fc1eda1e2ba6ef08cb270983756e760bdeaa3155e1ca69a5f4bc5dd1f\"},\"project/contracts/dnssec-oracle/algorithms/RSAPKCS1Verify.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nimport \\\"./RSAVerify.sol\\\";\\nimport \\\"../../utils/BytesUtils.sol\\\";\\n\\n/// @dev Library for PKCS#1 v1.5 signature verification\\nlibrary RSAPKCS1Verify {\\n    using BytesUtils for *;\\n\\n    /// @dev PKCS#1 v1.5 DigestInfo prefix for SHA-1\\n    bytes constant SHA1_DIGEST_INFO = hex\\\"3021300906052b0e03021a05000414\\\";\\n\\n    /// @dev PKCS#1 v1.5 DigestInfo prefix for SHA-256\\n    bytes constant SHA256_DIGEST_INFO = hex\\\"3031300d060960864801650304020105000420\\\";\\n\\n    /// @dev Verifies an RSA signature with PKCS#1 v1.5 padding for SHA-1\\n    function verifySHA1(\\n        bytes memory modulus,\\n        bytes memory exponent,\\n        bytes memory sig,\\n        bytes20 hash\\n    ) internal view returns (bool) {\\n        (bool ok, bytes memory result) = recoverAndVerify(modulus, exponent, sig, SHA1_DIGEST_INFO);\\n        return ok && hash == result.readBytes20(result.length - 20);\\n    }\\n\\n    /// @dev Verifies an RSA signature with PKCS#1 v1.5 padding for SHA-256\\n    function verifySHA256(\\n        bytes memory modulus,\\n        bytes memory exponent,\\n        bytes memory sig,\\n        bytes32 hash\\n    ) internal view returns (bool) {\\n        (bool ok, bytes memory result) = recoverAndVerify(modulus, exponent, sig, SHA256_DIGEST_INFO);\\n        return ok && hash == result.readBytes32(result.length - 32);\\n    }\\n\\n    /// @dev Recovers RSA signature and verifies PKCS#1 v1.5 structure\\n    /// Format: 0x00 0x01 [0xFF padding] 0x00 [DigestInfo] [Hash]\\n    /// https://datatracker.ietf.org/doc/html/rfc8017#section-9.2\\n    function recoverAndVerify(\\n        bytes memory modulus,\\n        bytes memory exponent,\\n        bytes memory sig,\\n        bytes memory digestInfo\\n    ) private view returns (bool, bytes memory) {\\n        (bool ok, bytes memory result) = RSAVerify.rsarecover(modulus, exponent, sig);\\n        if (!ok || result.length != modulus.length) {\\n            return (false, result);\\n        }\\n\\n        // Check leading bytes: 0x00 0x01\\n        if (result[0] != 0x00 || result[1] != 0x01) {\\n            return (false, result);\\n        }\\n\\n        // Calculate positions working backwards from the end\\n        uint256 hashLen = digestInfo.length == 15 ? 20 : 32;\\n        uint256 hashStart = result.length - hashLen;\\n        uint256 digestInfoStart = hashStart - digestInfo.length;\\n\\n        // Verify 0x00 separator before DigestInfo\\n        if (result[digestInfoStart - 1] != 0x00) {\\n            return (false, result);\\n        }\\n\\n        // Verify DigestInfo matches expected value\\n        if (!result.equals(digestInfoStart, digestInfo, 0, digestInfo.length)) {\\n            return (false, result);\\n        }\\n\\n        // Verify padding: all bytes from position 2 to separator must be 0xFF\\n        // Minimum 8 bytes of 0xFF padding required (RFC 3447)\\n        uint256 paddingLen = digestInfoStart - 1 - 2;\\n        if (paddingLen < 8) {\\n            return (false, result);\\n        }\\n        for (uint256 i = 2; i < digestInfoStart - 1; i++) {\\n            if (result[i] != 0xFF) {\\n                return (false, result);\\n            }\\n        }\\n\\n        return (true, result);\\n    }\\n}\\n\",\"keccak256\":\"0x92c872f6bb94670de46829d61122fcb0b0642dbd8e0e6fe31d2e8d387c890e87\"},\"project/contracts/dnssec-oracle/algorithms/RSASHA1Algorithm.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nimport \\\"./Algorithm.sol\\\";\\nimport \\\"./RSAPKCS1Verify.sol\\\";\\nimport \\\"../../utils/BytesUtils.sol\\\";\\nimport \\\"@ensdomains/solsha1/contracts/SHA1.sol\\\";\\n\\n/// @dev Implements the DNSSEC RSASHA1 algorithm.\\ncontract RSASHA1Algorithm is Algorithm {\\n    using BytesUtils for *;\\n\\n    function verify(\\n        bytes calldata key,\\n        bytes calldata data,\\n        bytes calldata sig\\n    ) external view override returns (bool) {\\n        bytes memory exponent;\\n        bytes memory modulus;\\n\\n        uint16 exponentLen = uint16(key.readUint8(4));\\n        if (exponentLen != 0) {\\n            exponent = key.substring(5, exponentLen);\\n            modulus = key.substring(\\n                exponentLen + 5,\\n                key.length - exponentLen - 5\\n            );\\n        } else {\\n            exponentLen = key.readUint16(5);\\n            exponent = key.substring(7, exponentLen);\\n            modulus = key.substring(\\n                exponentLen + 7,\\n                key.length - exponentLen - 7\\n            );\\n        }\\n\\n        return RSAPKCS1Verify.verifySHA1(modulus, exponent, sig, SHA1.sha1(data));\\n    }\\n}\\n\",\"keccak256\":\"0x2e6a435fe7ce7804e885e57aa0c8c81b384a519181805fecbdeca8b1de9ddd1b\"},\"project/contracts/dnssec-oracle/algorithms/RSAVerify.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nimport \\\"./ModexpPrecompile.sol\\\";\\nimport \\\"../../utils/BytesUtils.sol\\\";\\n\\nlibrary RSAVerify {\\n    /// @dev Recovers the input data from an RSA signature, returning the result in S.\\n    /// @param N The RSA public modulus.\\n    /// @param E The RSA public exponent.\\n    /// @param S The signature to recover.\\n    /// @return True if the recovery succeeded.\\n    function rsarecover(\\n        bytes memory N,\\n        bytes memory E,\\n        bytes memory S\\n    ) internal view returns (bool, bytes memory) {\\n        return ModexpPrecompile.modexp(S, E, N);\\n    }\\n}\\n\",\"keccak256\":\"0x3de747c1a48c82031e79a35c6b844697e48c8d0549cb3475783b1447895ef8ab\"},\"project/contracts/utils/BytesUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport {LibMem} from \\\"./LibMem/LibMem.sol\\\";\\n\\nlibrary BytesUtils {\\n    /// @dev `offset` was beyond `length`.\\n    ///       Error selector: `0x8a3c1cfb`\\n    error OffsetOutOfBoundsError(uint256 offset, uint256 length);\\n\\n    /// @dev Assert `end` is not beyond the length of `v`.\\n    function _checkBound(bytes memory v, uint256 end) internal pure {\\n        if (end > v.length) {\\n            revert OffsetOutOfBoundsError(end, v.length);\\n        }\\n    }\\n\\n    /// @dev Compute `keccak256(v[off:off+len])`.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @param len The number of bytes to hash.\\n    /// @return ret The corresponding hash.\\n    function keccak(\\n        bytes memory v,\\n        uint256 off,\\n        uint256 len\\n    ) internal pure returns (bytes32 ret) {\\n        _checkBound(v, off + len);\\n        assembly (\\\"memory-safe\\\") {\\n            ret := keccak256(add(add(v, 32), off), len)\\n        }\\n    }\\n\\n    /// @dev Lexicographically compare two byte strings.\\n    /// @param vA The first bytes to compare.\\n    /// @param vB The second bytes to compare.\\n    /// @return Positive number if `A > B`, negative number if `A < B`, or zero if `A == B`.\\n    function compare(\\n        bytes memory vA,\\n        bytes memory vB\\n    ) internal pure returns (int256) {\\n        return compare(vA, 0, vA.length, vB, 0, vB.length);\\n    }\\n\\n    /// @dev Lexicographically compare two byte ranges: `A = vA[offA:offA+lenA]` and `B = vB[offB:offB+lenB]`.\\n    /// @param vA The first bytes.\\n    /// @param offA The offset of the first bytes.\\n    /// @param lenA The length of the first bytes.\\n    /// @param vB The second bytes.\\n    /// @param offB The offset of the second bytes.\\n    /// @param lenB The length of the second bytes.\\n    /// @return Positive number if `A > B`, negative number if `A < B`, or zero if `A == B`.\\n    function compare(\\n        bytes memory vA,\\n        uint256 offA,\\n        uint256 lenA,\\n        bytes memory vB,\\n        uint256 offB,\\n        uint256 lenB\\n    ) internal pure returns (int256) {\\n        _checkBound(vA, offA + lenA);\\n        _checkBound(vB, offB + lenB);\\n        unchecked {\\n            uint256 ptrA = LibMem.ptr(vA) + offA;\\n            uint256 ptrB = LibMem.ptr(vB) + offB;\\n            uint256 shortest = lenA < lenB ? lenA : lenB;\\n            for (uint256 i; i < shortest; i += 32) {\\n                uint256 a = LibMem.load(ptrA + i);\\n                uint256 b = LibMem.load(ptrB + i);\\n                if (a != b) {\\n                    uint256 rest = shortest - i;\\n                    if (rest < 32) {\\n                        rest = (32 - rest) << 3; // bits to drop\\n                        a >>= rest; // shift out the\\n                        b >>= rest; // irrelevant bits\\n                    }\\n                    if (a < b) {\\n                        return -1;\\n                    } else if (a > b) {\\n                        return 1;\\n                    }\\n                }\\n            }\\n        }\\n        return int256(lenA) - int256(lenB);\\n    }\\n\\n    /// @dev Determine if `a[offA:offA+len] == b[offB:offB+len]`.\\n    /// @param vA The first bytes.\\n    /// @param offA The offset into the first bytes.\\n    /// @param vB The second bytes.\\n    /// @param offB The offset into the second bytes.\\n    /// @param len The number of bytes to compare.\\n    /// @return True if the byte ranges are equal.\\n    function equals(\\n        bytes memory vA,\\n        uint256 offA,\\n        bytes memory vB,\\n        uint256 offB,\\n        uint256 len\\n    ) internal pure returns (bool) {\\n        return keccak(vA, offA, len) == keccak(vB, offB, len);\\n    }\\n\\n    /// @dev Determine if `a[offA:] == b[offB:]`.\\n    /// @param vA The first bytes.\\n    /// @param offA The offset into the first bytes.\\n    /// @param vB The second bytes.\\n    /// @param offB The offset into the second bytes.\\n    /// @return True if the byte ranges are equal.\\n    function equals(\\n        bytes memory vA,\\n        uint256 offA,\\n        bytes memory vB,\\n        uint256 offB\\n    ) internal pure returns (bool) {\\n        _checkBound(vA, offA);\\n        _checkBound(vB, offB);\\n        unchecked {\\n            return\\n                keccak(vA, offA, vA.length - offA) ==\\n                keccak(vB, offB, vB.length - offB);\\n        }\\n    }\\n\\n    /// @dev Determine if `a[offA:] == b`.\\n    /// @param vA The first bytes.\\n    /// @param offA The offset into the first bytes.\\n    /// @param vB The second bytes.\\n    /// @return True if the byte ranges are equal.\\n    function equals(\\n        bytes memory vA,\\n        uint256 offA,\\n        bytes memory vB\\n    ) internal pure returns (bool) {\\n        return\\n            vA.length == offA + vB.length &&\\n            keccak(vA, offA, vB.length) == keccak256(vB);\\n    }\\n\\n    /// @dev Determine if `a == b`.\\n    /// @param vA The first bytes.\\n    /// @param vB The second bytes.\\n    /// @return True if the bytes are equal.\\n    function equals(\\n        bytes memory vA,\\n        bytes memory vB\\n    ) internal pure returns (bool) {\\n        return vA.length == vB.length && keccak256(vA) == keccak256(vB);\\n    }\\n\\n    /// @dev Returns `uint8(v[off])`.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @return The corresponding `uint8`.\\n    function readUint8(\\n        bytes memory v,\\n        uint256 off\\n    ) internal pure returns (uint8) {\\n        _checkBound(v, off + 1);\\n        unchecked {\\n            return uint8(v[off]);\\n        }\\n    }\\n\\n    /// @dev Returns `uint16(bytes2(v[off:off+2]))`.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @return ret The corresponding `uint16`.\\n    function readUint16(\\n        bytes memory v,\\n        uint256 off\\n    ) internal pure returns (uint16 ret) {\\n        _checkBound(v, off + 2);\\n        assembly (\\\"memory-safe\\\") {\\n            ret := shr(240, mload(add(add(v, 32), off)))\\n        }\\n    }\\n\\n    /// @dev Returns `uint32(bytes4(v[off:off+4]))`.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @return ret The corresponding `uint32`.\\n    function readUint32(\\n        bytes memory v,\\n        uint256 off\\n    ) internal pure returns (uint32 ret) {\\n        _checkBound(v, off + 4);\\n        assembly (\\\"memory-safe\\\") {\\n            ret := shr(224, mload(add(add(v, 32), off)))\\n        }\\n    }\\n\\n    /// @dev Returns `bytes20(v[off:off+20])`.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @return ret The corresponding `bytes20`.\\n    function readBytes20(\\n        bytes memory v,\\n        uint256 off\\n    ) internal pure returns (bytes20 ret) {\\n        _checkBound(v, off + 20);\\n        assembly (\\\"memory-safe\\\") {\\n            ret := shl(96, mload(add(add(v, 20), off)))\\n        }\\n    }\\n\\n    /// @dev Returns `bytes32(v[off:off+32])`.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @return ret The corresponding `bytes32`.\\n    function readBytes32(\\n        bytes memory v,\\n        uint256 off\\n    ) internal pure returns (bytes32 ret) {\\n        _checkBound(v, off + 32);\\n        assembly (\\\"memory-safe\\\") {\\n            ret := mload(add(add(v, 32), off))\\n        }\\n    }\\n\\n    /// @dev Returns `bytes32(bytesN(v[off:off+len]))`.\\n    ///      Accepts 0-32 bytes or reverts.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @param len The number of bytes.\\n    /// @return ret The corresponding N-bytes left-aligned in a `bytes32`.\\n    function readBytesN(\\n        bytes memory v,\\n        uint256 off,\\n        uint256 len\\n    ) internal pure returns (bytes32 ret) {\\n        assert(len <= 32);\\n        _checkBound(v, off + len);\\n        assembly (\\\"memory-safe\\\") {\\n            let mask := sub(shl(shl(3, sub(32, len)), 1), 1) // <(32-N)x00><NxFF>\\n            ret := and(mload(add(add(v, 32), off)), not(mask))\\n        }\\n    }\\n\\n    /// @dev Copy `vSrc[offSrc:offSrc+len]` to `vDst[offDst:offDst:len]`.\\n    /// @param vSrc The source bytes.\\n    /// @param offSrc The offset into the source to begin the copy.\\n    /// @param vDst The destination bytes.\\n    /// @param offDst The offset into the destination to place the copy.\\n    /// @param len The number of bytes to copy.\\n    function copyBytes(\\n        bytes memory vSrc,\\n        uint256 offSrc,\\n        bytes memory vDst,\\n        uint256 offDst,\\n        uint256 len\\n    ) internal pure {\\n        _checkBound(vSrc, offSrc + len);\\n        _checkBound(vDst, offDst + len);\\n        unchecked {\\n            LibMem.copy(\\n                LibMem.ptr(vDst) + offDst,\\n                LibMem.ptr(vSrc) + offSrc,\\n                len\\n            );\\n        }\\n    }\\n\\n    /// @dev Copies a substring into a new byte string.\\n    /// @param vSrc The byte string to copy from.\\n    /// @param off The offset to start copying at.\\n    /// @param len The number of bytes to copy.\\n    /// @return vDst The copied substring.\\n    function substring(\\n        bytes memory vSrc,\\n        uint256 off,\\n        uint256 len\\n    ) internal pure returns (bytes memory vDst) {\\n        vDst = new bytes(len);\\n        copyBytes(vSrc, off, vDst, 0, len);\\n    }\\n\\n    /// @dev Find the first occurrence of `needle`.\\n    /// @param v The bytes to search.\\n    /// @param off The offset to start searching.\\n    /// @param len The number of bytes to search.\\n    /// @param needle The byte to search for.\\n    /// @return The offset of `needle`, or `type(uint256).max` if not found.\\n    function find(\\n        bytes memory v,\\n        uint256 off,\\n        uint256 len,\\n        bytes1 needle\\n    ) internal pure returns (uint256) {\\n        for (uint256 end = off + len; off < end; off++) {\\n            if (v[off] == needle) {\\n                return off;\\n            }\\n        }\\n        return type(uint256).max;\\n    }\\n\\n    /// @dev Returns `true` if word contains a zero byte.\\n    function hasZeroByte(uint256 word) internal pure returns (bool) {\\n        unchecked {\\n            return\\n                ((~word &\\n                    (word -\\n                        0x0101010101010101010101010101010101010101010101010101010101010101)) &\\n                    0x8080808080808080808080808080808080808080808080808080808080808080) !=\\n                0;\\n        }\\n    }\\n\\n    /// @dev Efficiently check if `v[off:off+len]` contains `needle` byte.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @param len The number of bytes to search.\\n    /// @param needle The byte to search for.\\n    /// @return found `true` if `needle` was found.\\n    function includes(\\n        bytes memory v,\\n        uint256 off,\\n        uint256 len,\\n        bytes1 needle\\n    ) internal pure returns (bool found) {\\n        _checkBound(v, off + len);\\n        unchecked {\\n            uint256 wide = uint8(needle);\\n            wide |= wide << 8;\\n            wide |= wide << 16;\\n            wide |= wide << 32;\\n            wide |= wide << 64;\\n            wide |= wide << 128; // broadcast byte across word\\n            off += LibMem.ptr(v);\\n            len += off;\\n            while (off < len) {\\n                uint256 word = LibMem.load(off) ^ wide; // zero needle byte\\n                off += 32;\\n                if (hasZeroByte(word)) {\\n                    return\\n                        off <= len ||\\n                        hasZeroByte(\\n                            word | ((1 << ((off - len) << 3)) - 1) // recheck overflow by making it nonzero\\n                        );\\n                }\\n            }\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xcda2585a719e1a8974b5b44357e5d21417e1308b1d1f4d26b244d4ff0bb5b02d\",\"license\":\"MIT\"},\"project/contracts/utils/LibMem/LibMem.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nlibrary LibMem {\\n    /// @dev Copy `mem[src:src+len]` to `mem[dst:dst+len]`.\\n    ///      Equivalent to `mcopy()`.\\n    ///\\n    /// @param src The source memory offset.\\n    /// @param dst The destination memory offset.\\n    /// @param len The number of bytes to copy.\\n    function copy(uint256 dst, uint256 src, uint256 len) internal pure {\\n        assembly {\\n            // Copy word-length chunks while possible\\n            // prettier-ignore\\n            for {} gt(len, 31) {} {\\n                mstore(dst, mload(src))\\n                dst := add(dst, 32)\\n                src := add(src, 32)\\n                len := sub(len, 32)\\n            }\\n            // Copy remaining bytes\\n            if len {\\n                let mask := sub(shl(shl(3, sub(32, len)), 1), 1)\\n                let wSrc := and(mload(src), not(mask))\\n                let wDst := and(mload(dst), mask)\\n                mstore(dst, or(wSrc, wDst))\\n            }\\n        }\\n    }\\n\\n    /// @dev Convert bytes to a memory offset.\\n    ///\\n    /// @param v The bytes to convert.\\n    ///\\n    /// @return ret The corresponding memory offset.\\n    function ptr(bytes memory v) internal pure returns (uint256 ret) {\\n        assembly {\\n            ret := add(v, 32)\\n        }\\n    }\\n\\n    /// @dev Read word at memory offset.\\n    ///\\n    /// @param src The memory offset.\\n    ///\\n    /// @return ret The read word.\\n    function load(uint256 src) internal pure returns (uint256 ret) {\\n        assembly {\\n            ret := mload(src)\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x066f29ad3a39392786ff3caf9ba120104ffaa55502f71158631411db46d1ec89\",\"license\":\"MIT\"}},\"version\":1}",
  "storageLayout": {
    "storage": [],
    "types": null
  },
  "userdoc": {
    "kind": "user",
    "methods": {},
    "version": 1
  },
  "argsData": "0x",
  "transaction": {
    "hash": "0x8b40f778842c7e97332d4630d48bb015ce04b155d3de9c1f322f126bf25dbe3e",
    "nonce": "0x0",
    "origin": "0x4e472d50f3d735e76a143afcadae7f03db6995de"
  },
  "receipt": {
    "blockHash": "0x90041d39d8241731c6f9114a1daaf0975fbebebd309253b177d32ff912a167d9",
    "blockNumber": "0x1763f17",
    "transactionIndex": "0x9"
  }
}