Address: 0x7808dF0A1F1d58c6Ad0F3bA07E749D730F02f13A
Balance (XRP): 0 XRP
Bytecode: 0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612388565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125a8565b61035c565b60405161015a929190612686565b610197610192366004612731565b610392565b60405161015a92919061279a565b6101b86101b3366004612823565b61047f565b60405161015a949392919061288f565b6101d061056f565b005b6101976101e03660046128cb565b610583565b61020c7f000000000000000000000000ec58c26b8e0a4bc0fe1ad21d216e4ecad9e037a881565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b61017661024336600461292a565b6105ab565b6101d06102563660046129f0565b61064e565b610176610269366004612a2d565b61066d565b61028161027c366004612a8c565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612ace565b61078c565b60405161015a9190612ae7565b6101b86102d4366004612afa565b610838565b6101976102e7366004612823565b61092a565b6101766102fa366004612823565b61096e565b6101b861030d366004612a8c565b6109e0565b6101d0610320366004612b6e565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612b8b565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612b8b565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612bc5565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612ae7565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c20565b91509150600083602001518060200190518101906105319190612c72565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612bc5565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612bc5565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b80516106699060019060208401906122b5565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612b8b565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612b8b565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b88886000611310565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612b8b565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612b8b565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115be9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612bc5565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612b8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612b8b565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612c9d565b90925090506060610bf98a8c018c612d55565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d6123ee565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca06123ee565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612bc5565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612bc5565b60200260200101516020015186602001518281518110610d4257610d42612bc5565b6020026020010181905250610ea5565b848281518110610d6457610d64612bc5565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612bc5565b602002602001019015159081151581525050838281518110610dad57610dad612bc5565b602002602001015186602001518281518110610dcb57610dcb612bc5565b6020026020010181905250610e97565b828181518110610ded57610ded612bc5565b602002602001015160000151848381518110610e0b57610e0b612bc5565b6020026020010151848381518110610e2557610e25612bc5565b602002602001015160200151604051602401610e42929190612ed9565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612bc5565b60200260200101819052505b610ea2826001612f1d565b91505b80610eaf81612f30565b915050610cd3565b50610ec18561167d565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612f49565b9050600080610f1383611a88565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e9101612686565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190612fd3565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c20565b915091506000828060200190518101906110349190612c72565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c6123ee565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261167d565b9450505050965096945050505050565b8051610b6057602081015163ca7a4e7560e01b906112aa9061303c565b6001600160e01b031916036112f157600081602001518060200190518101906112d39190613074565b9150508060405163ca7a4e7560e01b81526004016104ec919061318a565b8060200151604051634ae063a960e11b81526004016104ec9190612ae7565b60008060008086868681811061132857611328612bc5565b919091013560f81c915050600081900361134c5750600092508291508390506115b5565b60006113588287612f1d565b611363906001612f1d565b905060008260421480156113a95750888861137f896001612f1d565b81811061138e5761138e612bc5565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113e7575088886113bd600185613202565b8181106113cc576113cc612bc5565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561145f57611457600060408b8b6114008c6002612f1d565b9061140c600189613202565b9261141993929190613215565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611cb19050565b509050611491565b888861146c896001612f1d565b61147892859290613215565b60405161148692919061323f565b604051809103902090505b60008060006114a18c8c87611310565b925092509250600082856040516020016114c5929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f000000000000000000000000ec58c26b8e0a4bc0fe1ad21d216e4ecad9e037a81690630178b8bf90602401602060405180830381865afa15801561155e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115829190612c72565b90506001600160a01b038116156115a657995097508996506115b595505050505050565b50929850919650909450505050505b93509350939050565b60008060006115cd8585611d82565b90925090508161163f57600185516115e59190613202565b84146116335760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61164985826115be565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff8111156116a2576116a26123ee565b60405190808252806020026020018201604052801561170057816020015b6116ed604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116c05790505b50905060008367ffffffffffffffff81111561171e5761171e6123ee565b60405190808252806020026020018201604052801561176457816020015b60408051808201909152600081526060602082015281526020019060019003908161173c5790505b5090508367ffffffffffffffff811115611780576117806123ee565b6040519080825280602002602001820160405280156117c657816020015b60408051808201909152600081526060602082015281526020019060019003908161179e5790505b50945060006117d487611e39565b905060005b858110156119c7576000886020015182815181106117f9576117f9612bc5565b6020026020010151905060008960e00151838151811061181b5761181b612bc5565b6020026020010151905080156118675760405180604001604052806000151581526020018381525089848151811061185557611855612bc5565b602002602001018190525050506119b5565b600061187d8b60000151848d60a0015188611ed0565b809450819250505060008060008061189a8f60a001518887611f58565b9350935093509350831561191057828060200190518101906118bc91906132cf565b8b8d815181106118ce576118ce612bc5565b6020026020010181905250818a89815181106118ec576118ec612bc5565b602090810291909101015261190260018d612f1d565b9b50505050505050506119b5565b80801561191e575088602001515b1561193a57828060200190518101906119379190612f49565b92505b60405180604001604052808215158152602001848152508e898151811061196357611963612bc5565b60200260200101819052508e60200151888151811061198457611984612bc5565b60200260200101518a898151811061199e5761199e612bc5565b602002602001015160200181905250505050505050505b806119bf81612f30565b9150506117d9565b50836000036119da575050505050919050565b83835230876040015163a780bab660e01b856040516024016119fc91906133ca565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a5d95949392919061342c565b60408051601f1981840301815290829052630556f18360e41b82526104ec95949392916004016134e9565b805160609060009081908490611a9f816002612f1d565b67ffffffffffffffff811115611ab757611ab76123ee565b6040519080825280601f01601f191660200182016040528015611ae1576020820181803683370190505b50945060009350808403611b2657600060f81b85600081518110611b0757611b07612bc5565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b3e57611b3e612bc5565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611c00578360f81b868260010181518110611ba457611ba4612bc5565b60200101906001600160f81b031916908160001a90535084611bcd846001840160ff8816612110565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c50565b600184019350828181518110611c1857611c18612bc5565b602001015160f81c60f81b868260010181518110611c3857611c38612bc5565b60200101906001600160f81b031916908160001a9053505b8015611c5f5760001901611b2c565b5083611c7083600060ff8716612110565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611b0757611b07612bc5565b8251600090600190831115611cc557600080fd5b611d16565b6000603a8210602f83111615611ce25750602f190190565b60478210604083111615611cf857506036190190565b60678210606083111615611d0e57506056190190565b5060ff919050565b60208501845b84811015611d7857611d338183015160001a611cca565b611d456001830184015160001a611cca565b60ff811460ff83141715611d5e57600094505050611d78565b60049190911b1760089490941b9390931792600201611d1c565b5050935093915050565b60008083518310611dd55760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611de957611de9612bc5565b016020015160f81c90508015611e1557611e0e85611e08866001612f1d565b83612110565b9250611e1a565b600092505b611e248185612f1d565b611e2f906001612f1d565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611e6c90639061b92360e01b612134565b905083608001518015611e7d575080155b15611eb4576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f4c57826020015115611f305760018686604051602401611efc929190612ed9565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f4284611f3d8761303c565b612134565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611f8b57611f8487876121b9565b9050611f9b565b611f98878761c3506121cd565b90505b3d8115611fbf576000611faf600083612260565b9095509350600191506109219050565b60048110612106576000611fd560006004612260565b90506000611fed6004611fe88186613202565b612260565b9050630556f18360e41b6120008361303c565b6001600160e01b031916036120ce5760008060008060008580602001905181019061202b919061351d565b945094509450945094508e6001600160a01b0316856001600160a01b0316036120c4576040518060600160405280866001600160a01b031681526020018581526020018481525060405160200161208291906135cd565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b5050505050612103565b81816040516020016120e19291906135e0565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b825160009061211f8385612f1d565b111561212a57600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121a6575060408051601f3d908101601f191682019092526121a39181019061360f565b60015b6121b257506000610356565b9050610356565b60006121c683835a6121cd565b9392505050565b60006001600160a01b0384163b61224c5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff81111561227b5761227b6123ee565b6040519080825280601f01601f1916602001820160405280156122a5576020820181803683370190505b5090508183602083013e92915050565b8280548282559060005260206000209081019282156122fb579160200282015b828111156122fb57825182906122eb908261367b565b50916020019190600101906122d5565b5061230792915061230b565b5090565b8082111561230757600061231f8282612328565b5060010161230b565b50805461233490612b8b565b6000825580601f10612344575050565b601f016020900490600052602060002090810190610b6091905b80821115612307576000815560010161235e565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561239a57600080fd5b81356121c681612372565b60008083601f8401126123b757600080fd5b50813567ffffffffffffffff8111156123cf57600080fd5b6020830191508360208285010111156123e757600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612427576124276123ee565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612456576124566123ee565b604052919050565b600067ffffffffffffffff821115612478576124786123ee565b50601f01601f191660200190565b60006124996124948461245e565b61242d565b90508281528383830111156124ad57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124d557600080fd5b6121c683833560208501612486565b600067ffffffffffffffff8211156124fe576124fe6123ee565b5060051b60200190565b600082601f83011261251957600080fd5b81356020612529612494836124e4565b82815260059290921b8401810191818101908684111561254857600080fd5b8286015b8481101561259d57803567ffffffffffffffff81111561256c5760008081fd5b8701603f8101891361257e5760008081fd5b61258f898683013560408401612486565b84525091830191830161254c565b509695505050505050565b600080600080606085870312156125be57600080fd5b843567ffffffffffffffff808211156125d657600080fd5b6125e2888389016123a5565b909650945060208701359150808211156125fb57600080fd5b612607888389016124c4565b9350604087013591508082111561261d57600080fd5b5061262a87828801612508565b91505092959194509250565b60005b83811015612651578181015183820152602001612639565b50506000910152565b60008151808452612672816020860160208601612636565b601f01601f19169290920160200192915050565b604081526000612699604083018561265a565b90506001600160a01b03831660208301529392505050565b600082601f8301126126c257600080fd5b813560206126d2612494836124e4565b82815260059290921b840181019181810190868411156126f157600080fd5b8286015b8481101561259d57803567ffffffffffffffff8111156127155760008081fd5b6127238986838b01016124c4565b8452509183019183016126f5565b60008060006040848603121561274657600080fd5b833567ffffffffffffffff8082111561275e57600080fd5b61276a878388016123a5565b9095509350602086013591508082111561278357600080fd5b50612790868287016126b1565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561280457888603605f1901855281518051151587528301518387018890526127f18888018261265a565b96505093820193908201906001016127c3565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561283957600080fd5b843567ffffffffffffffff8082111561285157600080fd5b61285d888389016123a5565b9096509450602087013591508082111561287657600080fd5b50612883878288016123a5565b95989497509550505050565b6080815260006128a2608083018761265a565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156128e157600080fd5b843567ffffffffffffffff808211156128f957600080fd5b612905888389016123a5565b9096509450602087013591508082111561291e57600080fd5b612607888389016126b1565b60008060008060008060a0878903121561294357600080fd5b863567ffffffffffffffff8082111561295b57600080fd5b6129678a838b016123a5565b9098509650602089013591508082111561298057600080fd5b61298c8a838b016124c4565b955060408901359150808211156129a257600080fd5b6129ae8a838b01612508565b9450606089013591506129c082612372565b909250608088013590808211156129d657600080fd5b506129e389828a016124c4565b9150509295509295509295565b600060208284031215612a0257600080fd5b813567ffffffffffffffff811115612a1957600080fd5b612a2584828501612508565b949350505050565b600080600060408486031215612a4257600080fd5b833567ffffffffffffffff80821115612a5a57600080fd5b612a66878388016123a5565b90955093506020860135915080821115612a7f57600080fd5b50612790868287016124c4565b60008060208385031215612a9f57600080fd5b823567ffffffffffffffff811115612ab657600080fd5b612ac2858286016123a5565b90969095509350505050565b600060208284031215612ae057600080fd5b5035919050565b6020815260006121c6602083018461265a565b600080600060408486031215612b0f57600080fd5b833567ffffffffffffffff80821115612b2757600080fd5b612b33878388016123a5565b90955093506020860135915080821115612b4c57600080fd5b5061279086828701612508565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612b8057600080fd5b81356121c681612b59565b600181811c90821680612b9f57607f821691505b602082108103612bbf57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612bec57600080fd5b8151612bfa6124948261245e565b818152846020838601011115612c0f57600080fd5b612a25826020830160208701612636565b60008060408385031215612c3357600080fd5b825167ffffffffffffffff811115612c4a57600080fd5b612c5685828601612bdb565b9250506020830151612c6781612b59565b809150509250929050565b600060208284031215612c8457600080fd5b81516121c681612b59565b8015158114610b6057600080fd5b60008060408385031215612cb057600080fd5b823567ffffffffffffffff80821115612cc857600080fd5b818501915085601f830112612cdc57600080fd5b81356020612cec612494836124e4565b82815260059290921b84018101918181019089841115612d0b57600080fd5b948201945b83861015612d32578535612d2381612c8f565b82529482019490820190612d10565b96505086013592505080821115612d4857600080fd5b50611e2f858286016126b1565b600080600080600060a08688031215612d6d57600080fd5b612d778635612c8f565b85359450612d886020870135612b59565b6020860135935067ffffffffffffffff8060408801351115612da957600080fd5b612db98860408901358901612508565b93508060608801351115612dcc57600080fd5b612ddc88606089013589016124c4565b92508060808801351115612def57600080fd5b6080870135870188601f820112612e0557600080fd5b612e1261249482356124e4565b81358082526020808301929160051b8401018b1015612e3057600080fd5b602083015b6020843560051b850101811015612ec7578481351115612e5457600080fd5b803584016040818e03601f19011215612e6c57600080fd5b612e74612404565b612e816020830135612372565b602082013581528660408301351115612e9957600080fd5b612eac8e602060408501358501016124c4565b60208201528085525050602083019250602081019050612e35565b50809450505050509295509295909350565b604081526000612eec604083018561265a565b8281036020840152612efe818561265a565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f07565b600060018201612f4257612f42612f07565b5060010190565b600060208284031215612f5b57600080fd5b815167ffffffffffffffff811115612f7257600080fd5b612a2584828501612bdb565b600081518084526020808501808196508360051b8101915082860160005b85811015612fc6578284038952612fb484835161265a565b98850198935090840190600101612f9c565b5091979650505050505050565b60a081526000612fe660a083018861265a565b8281036020840152612ff8818861265a565b9050828103604084015261300c8187612f7e565b90506001600160e01b0319851660608401528281036080840152613030818561265a565b98975050505050505050565b6000815160208301516001600160e01b03198082169350600483101561306c5780818460040360031b1b83161693505b505050919050565b600080604080848603121561308857600080fd5b835161309381612372565b8093505060208085015167ffffffffffffffff808211156130b357600080fd5b818701915087601f8301126130c757600080fd5b81516130d5612494826124e4565b81815260059190911b8301840190848101908a8311156130f457600080fd5b8585015b83811015613178578051858111156131105760008081fd5b8601808d03601f19018913156131265760008081fd5b61312e612404565b8882015161ffff811681146131435760008081fd5b8152818a0151878111156131575760008081fd5b6131658f8b83860101612bdb565b828b0152508452509186019186016130f8565b50809750505050505050509250929050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156131f457888303603f190185528151805161ffff1684528701518784018790526131e18785018261265a565b95880195935050908601906001016131b1565b509098975050505050505050565b8181038181111561035657610356612f07565b6000808585111561322557600080fd5b8386111561323257600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261326057600080fd5b81516020613270612494836124e4565b82815260059290921b8401810191818101908684111561328f57600080fd5b8286015b8481101561259d57805167ffffffffffffffff8111156132b35760008081fd5b6132c18986838b0101612bdb565b845250918301918301613293565b6000602082840312156132e157600080fd5b815167ffffffffffffffff808211156132f957600080fd5b908301906060828603121561330d57600080fd5b604051606081018181108382111715613328576133286123ee565b604052825161333681612b59565b815260208301518281111561334a57600080fd5b6133568782860161324f565b60208301525060408301518281111561336e57600080fd5b61337a87828601612bdb565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526133b16060850182612f7e565b905060408301518482036040860152612efe828261265a565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561341f57603f1988860301845261340d858351613389565b945092850192908501906001016133f1565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261345860a0850188612f7e565b848103606086015261346a818861265a565b905084810360808601528086518083528483019150848160051b84010185890160005b838110156134d657858303601f19018552815180516001600160e01b03191684528801518884018890526134c38885018261265a565b958901959350509087019060010161348d565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820152600061350b60a0830187612f7e565b828103604084015261300c818761265a565b600080600080600060a0868803121561353557600080fd5b855161354081612b59565b602087015190955067ffffffffffffffff8082111561355e57600080fd5b61356a89838a0161324f565b9550604088015191508082111561358057600080fd5b61358c89838a01612bdb565b94506060880151915061359e82612372565b6080880151919350808211156135b357600080fd5b506135c088828901612bdb565b9150509295509295909350565b6020815260006121c66020830184613389565b600083516135f2818460208801612636565b835190830190613606818360208801612636565b01949350505050565b60006020828403121561362157600080fd5b81516121c681612c8f565b601f82111561367657600081815260208120601f850160051c810160208610156136535750805b601f850160051c820191505b818110156136725782815560010161365f565b5050505b505050565b815167ffffffffffffffff811115613695576136956123ee565b6136a9816136a38454612b8b565b8461362c565b602080601f8311600181146136de57600084156136c65750858301515b600019600386901b1c1916600185901b178555613672565b600085815260208120601f198616915b8281101561370d578886015182559484019460019091019084016136ee565b508582101561372b5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea26469706673582212203bf9dc7d80332d4814d1f83bdf2f5614384ce60bd28a1b51b219341fb0b036cc64736f6c63430008110033
RNS.sol
pragma solidity >=0.8.4; interface RNS { // Logged when the owner of a node assigns a new owner to a subnode. event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); // Logged when the owner of a node transfers ownership to a new account. event Transfer(bytes32 indexed node, address owner); // Logged when the resolver for a node changes. event NewResolver(bytes32 indexed node, address resolver); // Logged when the TTL of a node changes event NewTTL(bytes32 indexed node, uint64 ttl); // Logged when an operator is added or removed. event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); function setRecord( bytes32 node, address owner, address resolver, uint64 ttl ) external; function setSubnodeRecord( bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl ) external; function setSubnodeOwner( bytes32 node, bytes32 label, address owner ) external returns (bytes32); function setResolver(bytes32 node, address resolver) external; function setOwner(bytes32 node, address owner) external; function setTTL(bytes32 node, uint64 ttl) external; function setApprovalForAll(address operator, bool approved) external; function owner(bytes32 node) external view returns (address); function resolver(bytes32 node) external view returns (address); function ttl(bytes32 node) external view returns (uint64); function recordExists(bytes32 node) external view returns (bool); function isApprovedForAll( address owner, address operator ) external view returns (bool); }
HexUtils.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; library HexUtils { /** * @dev Attempts to parse bytes32 from a hex string * @param str The string to parse * @param idx The offset to start parsing at * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string. */ function hexStringToBytes32( bytes memory str, uint256 idx, uint256 lastIdx ) internal pure returns (bytes32 r, bool valid) { valid = true; assembly { // check that the index to read to is not past the end of the string if gt(lastIdx, mload(str)) { revert(0, 0) } function getHex(c) -> ascii { // chars 48-57: 0-9 if and(gt(c, 47), lt(c, 58)) { ascii := sub(c, 48) leave } // chars 65-70: A-F if and(gt(c, 64), lt(c, 71)) { ascii := add(sub(c, 65), 10) leave } // chars 97-102: a-f if and(gt(c, 96), lt(c, 103)) { ascii := add(sub(c, 97), 10) leave } // invalid char ascii := 0xff } let ptr := add(str, 32) for { let i := idx } lt(i, lastIdx) { i := add(i, 2) } { let byte1 := getHex(byte(0, mload(add(ptr, i)))) let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1))))) // if either byte is invalid, set invalid and break loop if or(eq(byte1, 0xff), eq(byte2, 0xff)) { valid := false break } let combined := or(shl(4, byte1), byte2) r := or(shl(8, r), combined) } } } /** * @dev Attempts to parse an address from a hex string * @param str The string to parse * @param idx The offset to start parsing at * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string. */ function hexToAddress( bytes memory str, uint256 idx, uint256 lastIdx ) internal pure returns (address, bool) { if (lastIdx - idx < 40) return (address(0x0), false); (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx); return (address(uint160(uint256(r))), valid); } }
NameEncoder.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {BytesUtils} from "../wrapper/BytesUtils.sol"; library NameEncoder { using BytesUtils for bytes; function dnsEncodeName( string memory name ) internal pure returns (bytes memory dnsName, bytes32 node) { uint8 labelLength = 0; bytes memory bytesName = bytes(name); uint256 length = bytesName.length; dnsName = new bytes(length + 2); node = 0; if (length == 0) { dnsName[0] = 0; return (dnsName, node); } // use unchecked to save gas since we check for an underflow // and we check for the length before the loop unchecked { for (uint256 i = length - 1; i >= 0; i--) { if (bytesName[i] == ".") { dnsName[i + 1] = bytes1(labelLength); node = keccak256( abi.encodePacked( node, bytesName.keccak(i + 1, labelLength) ) ); labelLength = 0; } else { labelLength += 1; dnsName[i + 1] = bytesName[i]; } if (i == 0) { break; } } } node = keccak256( abi.encodePacked(node, bytesName.keccak(0, labelLength)) ); dnsName[0] = bytes1(labelLength); return (dnsName, node); } }
Resolver.sol
//SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import "./profiles/IABIResolver.sol"; import "./profiles/IAddressResolver.sol"; import "./profiles/IAddrResolver.sol"; import "./profiles/IContentHashResolver.sol"; import "./profiles/IDNSRecordResolver.sol"; import "./profiles/IDNSZoneResolver.sol"; import "./profiles/IInterfaceResolver.sol"; import "./profiles/INameResolver.sol"; import "./profiles/IPubkeyResolver.sol"; import "./profiles/ITextResolver.sol"; import "./profiles/IExtendedResolver.sol"; /** * A generic resolver interface which includes all the functions including the ones deprecated */ interface Resolver is IERC165, IABIResolver, IAddressResolver, IAddrResolver, IContentHashResolver, IDNSRecordResolver, IDNSZoneResolver, IInterfaceResolver, INameResolver, IPubkeyResolver, ITextResolver, IExtendedResolver { /* Deprecated events */ event ContentChanged(bytes32 indexed node, bytes32 hash); function setApprovalForAll(address, bool) external; function approve(bytes32 node, address delegate, bool approved) external; function isApprovedForAll(address account, address operator) external; function isApprovedFor( address owner, bytes32 node, address delegate ) external; function setABI( bytes32 node, uint256 contentType, bytes calldata data ) external; function setAddr(bytes32 node, address addr) external; function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external; function setContenthash(bytes32 node, bytes calldata hash) external; function setDnsrr(bytes32 node, bytes calldata data) external; function setName(bytes32 node, string calldata _name) external; function setPubkey(bytes32 node, bytes32 x, bytes32 y) external; function setText( bytes32 node, string calldata key, string calldata value ) external; function setInterface( bytes32 node, bytes4 interfaceID, address implementer ) external; function multicall( bytes[] calldata data ) external returns (bytes[] memory results); function multicallWithNodeCheck( bytes32 nodehash, bytes[] calldata data ) external returns (bytes[] memory results); /* Deprecated functions */ function content(bytes32 node) external view returns (bytes32); function multihash(bytes32 node) external view returns (bytes memory); function setContent(bytes32 node, bytes32 hash) external; function setMultihash(bytes32 node, bytes calldata hash) external; }
BytesUtils.sol
//SPDX-License-Identifier: MIT pragma solidity ~0.8.17; library BytesUtils { /* * @dev Returns the keccak-256 hash of a byte range. * @param self The byte string to hash. * @param offset The position to start hashing at. * @param len The number of bytes to hash. * @return The hash of the byte range. */ function keccak( bytes memory self, uint256 offset, uint256 len ) internal pure returns (bytes32 ret) { require(offset + len <= self.length); assembly { ret := keccak256(add(add(self, 32), offset), len) } } /** * @dev Returns the RNS namehash of a DNS-encoded name. * @param self The DNS-encoded name to hash. * @param offset The offset at which to start hashing. * @return The namehash of the name. */ function namehash( bytes memory self, uint256 offset ) internal pure returns (bytes32) { (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset); if (labelhash == bytes32(0)) { require(offset == self.length - 1, "namehash: Junk at end of name"); return bytes32(0); } return keccak256(abi.encodePacked(namehash(self, newOffset), labelhash)); } /** * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label. * @param self The byte string to read a label from. * @param idx The index to read a label at. * @return labelhash The hash of the label at the specified index, or 0 if it is the last label. * @return newIdx The index of the start of the next label. */ function readLabel( bytes memory self, uint256 idx ) internal pure returns (bytes32 labelhash, uint256 newIdx) { require(idx < self.length, "readLabel: Index out of bounds"); uint256 len = uint256(uint8(self[idx])); if (len > 0) { labelhash = keccak(self, idx + 1, len); } else { labelhash = bytes32(0); } newIdx = idx + len + 1; } }
LowLevelCallUtils.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; library LowLevelCallUtils { using Address for address; /** * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with * `returnDataSize` and `readReturnData`. * @param target The address to staticcall. * @param data The data to pass to the call. * @return success True if the call succeeded, or false if it reverts. */ function functionStaticCall( address target, bytes memory data ) internal view returns (bool success) { return functionStaticCall(target, data, gasleft()); } /** * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with * `returnDataSize` and `readReturnData`. * @param target The address to staticcall. * @param data The data to pass to the call. * @param gasLimit The gas limit to use for the call. * @return success True if the call succeeded, or false if it reverts. */ function functionStaticCall( address target, bytes memory data, uint256 gasLimit ) internal view returns (bool success) { require( target.isContract(), "LowLevelCallUtils: static call to non-contract" ); assembly { success := staticcall( gasLimit, target, add(data, 32), mload(data), 0, 0 ) } } /** * @dev Returns the size of the return data of the most recent external call. */ function returnDataSize() internal pure returns (uint256 len) { assembly { len := returndatasize() } } /** * @dev Reads return data from the most recent external call. * @param offset Offset into the return data. * @param length Number of bytes to return. */ function readReturnData( uint256 offset, uint256 length ) internal pure returns (bytes memory data) { data = new bytes(length); assembly { returndatacopy(add(data, 32), offset, length) } } /** * @dev Reverts with the return data from the most recent external call. */ function propagateRevert() internal pure { assembly { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } }
UniversalResolver.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.8.17 <0.9.0; import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {LowLevelCallUtils} from "./LowLevelCallUtils.sol"; import {RNS} from "../registry/RNS.sol"; import {IExtendedResolver} from "../resolvers/profiles/IExtendedResolver.sol"; import {Resolver, INameResolver, IAddrResolver} from "../resolvers/Resolver.sol"; import {NameEncoder} from "./NameEncoder.sol"; import {BytesUtils} from "../wrapper/BytesUtils.sol"; import {HexUtils} from "./HexUtils.sol"; error OffchainLookup( address sender, string[] urls, bytes callData, bytes4 callbackFunction, bytes extraData ); error ResolverNotFound(); error ResolverWildcardNotSupported(); error ResolverNotContract(); error ResolverError(bytes returnData); error HttpError(HttpErrorItem[] errors); struct HttpErrorItem { uint16 status; string message; } struct MulticallData { bytes name; bytes[] data; string[] gateways; bytes4 callbackFunction; bool isWildcard; address resolver; bytes metaData; bool[] failures; } struct MulticallChecks { bool isCallback; bool hasExtendedResolver; } struct OffchainLookupCallData { address sender; string[] urls; bytes callData; } struct OffchainLookupExtraData { bytes4 callbackFunction; bytes data; } struct Result { bool success; bytes returnData; } interface BatchGateway { function query( OffchainLookupCallData[] memory data ) external returns (bool[] memory failures, bytes[] memory responses); } /** * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain, * making it possible to make a single smart contract call to resolve an RNS name. */ contract UniversalResolver is ERC165, Ownable { using Address for address; using NameEncoder for string; using BytesUtils for bytes; using HexUtils for bytes; string[] public batchGatewayURLs; RNS public immutable registry; constructor(address _registry, string[] memory _urls) { registry = RNS(_registry); batchGatewayURLs = _urls; } function setGatewayURLs(string[] memory _urls) public onlyOwner { batchGatewayURLs = _urls; } /** * @dev Performs RNS name resolution for the supplied name and resolution data. * @param name The name to resolve, in normalised and DNS-encoded form. * @param data The resolution data, as specified in RNSIP-10. * @return The result of resolving the name. */ function resolve( bytes calldata name, bytes memory data ) external view returns (bytes memory, address) { return _resolveSingle( name, data, batchGatewayURLs, this.resolveSingleCallback.selector, "" ); } function resolve( bytes calldata name, bytes[] memory data ) external view returns (Result[] memory, address) { return resolve(name, data, batchGatewayURLs); } function resolve( bytes calldata name, bytes memory data, string[] memory gateways ) external view returns (bytes memory, address) { return _resolveSingle( name, data, gateways, this.resolveSingleCallback.selector, "" ); } function resolve( bytes calldata name, bytes[] memory data, string[] memory gateways ) public view returns (Result[] memory, address) { return _resolve(name, data, gateways, this.resolveCallback.selector, ""); } function _resolveSingle( bytes calldata name, bytes memory data, string[] memory gateways, bytes4 callbackFunction, bytes memory metaData ) public view returns (bytes memory, address) { bytes[] memory dataArr = new bytes[](1); dataArr[0] = data; (Result[] memory results, address resolver) = _resolve( name, dataArr, gateways, callbackFunction, metaData ); Result memory result = results[0]; _checkResolveSingle(result); return (result.returnData, resolver); } function _resolve( bytes calldata name, bytes[] memory data, string[] memory gateways, bytes4 callbackFunction, bytes memory metaData ) internal view returns (Result[] memory results, address resolverAddress) { (Resolver resolver, , uint256 finalOffset) = findResolver(name); resolverAddress = address(resolver); if (resolverAddress == address(0)) { revert ResolverNotFound(); } if (!resolverAddress.isContract()) { revert ResolverNotContract(); } bool isWildcard = finalOffset != 0; results = _multicall( MulticallData( name, data, gateways, callbackFunction, isWildcard, resolverAddress, metaData, new bool[](data.length) ) ); } function reverse( bytes calldata reverseName ) external view returns (string memory, address, address, address) { return reverse(reverseName, batchGatewayURLs); } /** * @dev Performs RNS name reverse resolution for the supplied reverse name. * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address. */ function reverse( bytes calldata reverseName, string[] memory gateways ) public view returns (string memory, address, address, address) { bytes memory encodedCall = abi.encodeCall( INameResolver.name, reverseName.namehash(0) ); ( bytes memory reverseResolvedData, address reverseResolverAddress ) = _resolveSingle( reverseName, encodedCall, gateways, this.reverseCallback.selector, "" ); return getForwardDataFromReverse( reverseResolvedData, reverseResolverAddress, gateways ); } function getForwardDataFromReverse( bytes memory resolvedReverseData, address reverseResolverAddress, string[] memory gateways ) internal view returns (string memory, address, address, address) { string memory resolvedName = abi.decode(resolvedReverseData, (string)); (bytes memory encodedName, bytes32 namehash) = resolvedName .dnsEncodeName(); bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash); bytes memory metaData = abi.encode( resolvedName, reverseResolverAddress ); (bytes memory resolvedData, address resolverAddress) = this ._resolveSingle( encodedName, encodedCall, gateways, this.reverseCallback.selector, metaData ); address resolvedAddress = abi.decode(resolvedData, (address)); return ( resolvedName, resolvedAddress, reverseResolverAddress, resolverAddress ); } function resolveSingleCallback( bytes calldata response, bytes calldata extraData ) external view returns (bytes memory, address) { (Result[] memory results, address resolver, , ) = _resolveCallback( response, extraData, this.resolveSingleCallback.selector ); Result memory result = results[0]; _checkResolveSingle(result); return (result.returnData, resolver); } function resolveCallback( bytes calldata response, bytes calldata extraData ) external view returns (Result[] memory, address) { (Result[] memory results, address resolver, , ) = _resolveCallback( response, extraData, this.resolveCallback.selector ); return (results, resolver); } function reverseCallback( bytes calldata response, bytes calldata extraData ) external view returns (string memory, address, address, address) { ( Result[] memory results, address resolverAddress, string[] memory gateways, bytes memory metaData ) = _resolveCallback( response, extraData, this.reverseCallback.selector ); Result memory result = results[0]; if (!result.success) { revert ResolverError(result.returnData); } if (metaData.length > 0) { (string memory resolvedName, address reverseResolverAddress) = abi .decode(metaData, (string, address)); address resolvedAddress = abi.decode(result.returnData, (address)); return ( resolvedName, resolvedAddress, reverseResolverAddress, resolverAddress ); } return getForwardDataFromReverse( result.returnData, resolverAddress, gateways ); } function supportsInterface( bytes4 interfaceId ) public view virtual override returns (bool) { return interfaceId == type(IExtendedResolver).interfaceId || super.supportsInterface(interfaceId); } function _resolveCallback( bytes calldata response, bytes calldata extraData, bytes4 callbackFunction ) internal view returns (Result[] memory, address, string[] memory, bytes memory) { MulticallData memory multicallData; multicallData.callbackFunction = callbackFunction; (bool[] memory failures, bytes[] memory responses) = abi.decode( response, (bool[], bytes[]) ); OffchainLookupExtraData[] memory extraDatas; ( multicallData.isWildcard, multicallData.resolver, multicallData.gateways, multicallData.metaData, extraDatas ) = abi.decode( extraData, (bool, address, string[], bytes, OffchainLookupExtraData[]) ); require(responses.length <= extraDatas.length); multicallData.data = new bytes[](extraDatas.length); multicallData.failures = new bool[](extraDatas.length); uint256 offchainCount = 0; for (uint256 i = 0; i < extraDatas.length; i++) { if (extraDatas[i].callbackFunction == bytes4(0)) { // This call did not require an offchain lookup; use the previous input data. multicallData.data[i] = extraDatas[i].data; } else { if (failures[offchainCount]) { multicallData.failures[i] = true; multicallData.data[i] = responses[offchainCount]; } else { multicallData.data[i] = abi.encodeWithSelector( extraDatas[i].callbackFunction, responses[offchainCount], extraDatas[i].data ); } offchainCount = offchainCount + 1; } } return ( _multicall(multicallData), multicallData.resolver, multicallData.gateways, multicallData.metaData ); } /** * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps * the error with the data necessary to continue the request where it left off. * @param target The address to call. * @param data The data to call `target` with. * @return offchain Whether the call reverted with an `OffchainLookup` error. * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct. * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct. * @return result Whether the call succeeded. */ function callWithOffchainLookupPropagation( address target, bytes memory data, bool isSafe ) internal view returns ( bool offchain, bytes memory returnData, OffchainLookupExtraData memory extraData, bool result ) { if (isSafe) { result = LowLevelCallUtils.functionStaticCall(target, data); } else { result = LowLevelCallUtils.functionStaticCall(target, data, 50000); } uint256 size = LowLevelCallUtils.returnDataSize(); if (result) { return ( false, LowLevelCallUtils.readReturnData(0, size), extraData, true ); } // Failure if (size >= 4) { bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4); // Offchain lookup. Decode the revert message and create our own that nests it. bytes memory revertData = LowLevelCallUtils.readReturnData( 4, size - 4 ); if (bytes4(errorId) == OffchainLookup.selector) { ( address wrappedSender, string[] memory wrappedUrls, bytes memory wrappedCallData, bytes4 wrappedCallbackFunction, bytes memory wrappedExtraData ) = abi.decode( revertData, (address, string[], bytes, bytes4, bytes) ); if (wrappedSender == target) { returnData = abi.encode( OffchainLookupCallData( wrappedSender, wrappedUrls, wrappedCallData ) ); extraData = OffchainLookupExtraData( wrappedCallbackFunction, wrappedExtraData ); return (true, returnData, extraData, false); } } else { returnData = bytes.concat(errorId, revertData); return (false, returnData, extraData, false); } } } /** * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively * removing labels until it finds a result. * @param name The name to resolve, in DNS-encoded and normalised form. * @return resolver The Resolver responsible for this name. * @return namehash The namehash of the full name. * @return finalOffset The offset of the first label with a resolver. */ function findResolver( bytes calldata name ) public view returns (Resolver, bytes32, uint256) { ( address resolver, bytes32 namehash, uint256 finalOffset ) = findResolver(name, 0); return (Resolver(resolver), namehash, finalOffset); } function findResolver( bytes calldata name, uint256 offset ) internal view returns (address, bytes32, uint256) { uint256 labelLength = uint256(uint8(name[offset])); if (labelLength == 0) { return (address(0), bytes32(0), offset); } uint256 nextLabel = offset + labelLength + 1; bytes32 labelHash; if ( labelLength == 66 && // 0x5b == '[' name[offset + 1] == 0x5b && // 0x5d == ']' name[nextLabel - 1] == 0x5d ) { // Encrypted label (labelHash, ) = bytes(name[offset + 2:nextLabel - 1]) .hexStringToBytes32(0, 64); } else { labelHash = keccak256(name[offset + 1:nextLabel]); } ( address parentresolver, bytes32 parentnode, uint256 parentoffset ) = findResolver(name, nextLabel); bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash)); address resolver = registry.resolver(node); if (resolver != address(0)) { return (resolver, node, offset); } return (parentresolver, node, parentoffset); } function _checkInterface( address resolver, bytes4 interfaceId ) internal view returns (bool) { try Resolver(resolver).supportsInterface{gas: 50000}(interfaceId) returns (bool supported) { return supported; } catch { return false; } } function _checkSafetyAndItem( bytes memory name, bytes memory item, address resolver, MulticallChecks memory multicallChecks ) internal view returns (bool, bytes memory) { if (!multicallChecks.isCallback) { if (multicallChecks.hasExtendedResolver) { return ( true, abi.encodeCall(IExtendedResolver.resolve, (name, item)) ); } return (_checkInterface(resolver, bytes4(item)), item); } return (true, item); } function _checkMulticall( MulticallData memory multicallData ) internal view returns (MulticallChecks memory) { bool isCallback = multicallData.name.length == 0; bool hasExtendedResolver = _checkInterface( multicallData.resolver, type(IExtendedResolver).interfaceId ); if (multicallData.isWildcard && !hasExtendedResolver) { revert ResolverWildcardNotSupported(); } return MulticallChecks(isCallback, hasExtendedResolver); } function _checkResolveSingle(Result memory result) internal pure { if (!result.success) { if (bytes4(result.returnData) == HttpError.selector) { (, HttpErrorItem[] memory errors) = abi.decode( result.returnData, (bytes4, HttpErrorItem[]) ); revert HttpError(errors); } revert ResolverError(result.returnData); } } function _multicall( MulticallData memory multicallData ) internal view returns (Result[] memory results) { uint256 length = multicallData.data.length; uint256 offchainCount = 0; OffchainLookupCallData[] memory callDatas = new OffchainLookupCallData[](length); OffchainLookupExtraData[] memory extraDatas = new OffchainLookupExtraData[](length); results = new Result[](length); MulticallChecks memory multicallChecks = _checkMulticall(multicallData); for (uint256 i = 0; i < length; i++) { bytes memory item = multicallData.data[i]; bool failure = multicallData.failures[i]; if (failure) { results[i] = Result(false, item); continue; } bool isSafe = false; (isSafe, item) = _checkSafetyAndItem( multicallData.name, item, multicallData.resolver, multicallChecks ); ( bool offchain, bytes memory returnData, OffchainLookupExtraData memory extraData, bool success ) = callWithOffchainLookupPropagation( multicallData.resolver, item, isSafe ); if (offchain) { callDatas[offchainCount] = abi.decode( returnData, (OffchainLookupCallData) ); extraDatas[i] = extraData; offchainCount += 1; continue; } if (success && multicallChecks.hasExtendedResolver) { // if this is a successful resolve() call, unwrap the result returnData = abi.decode(returnData, (bytes)); } results[i] = Result(success, returnData); extraDatas[i].data = multicallData.data[i]; } if (offchainCount == 0) { return results; } // Trim callDatas if offchain data exists assembly { mstore(callDatas, offchainCount) } revert OffchainLookup( address(this), multicallData.gateways, abi.encodeWithSelector(BatchGateway.query.selector, callDatas), multicallData.callbackFunction, abi.encode( multicallData.isWildcard, multicallData.resolver, multicallData.gateways, multicallData.metaData, extraDatas ) ); } }
Address.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
Context.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
Ownable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
IABIResolver.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IABIResolver { event ABIChanged(bytes32 indexed node, uint256 indexed contentType); /** * Returns the ABI associated with an RNS node. * Defined in EIP205. * @param node The RNS node to query * @param contentTypes A bitwise OR of the ABI formats accepted by the caller. * @return contentType The content type of the return value * @return data The ABI data */ function ABI( bytes32 node, uint256 contentTypes ) external view returns (uint256, bytes memory); }
IAddrResolver.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; /** * Interface for the legacy (ETH-only) addr function. */ interface IAddrResolver { event AddrChanged(bytes32 indexed node, address a); /** * Returns the address associated with an RNS node. * @param node The RNS node to query. * @return The associated address. */ function addr(bytes32 node) external view returns (address payable); }
INameResolver.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface INameResolver { event NameChanged(bytes32 indexed node, string name); /** * Returns the name associated with an RNS node, for reverse records. * Defined in EIP181. * @param node The RNS node to query. * @return The associated name. */ function name(bytes32 node) external view returns (string memory); }
ITextResolver.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface ITextResolver { event TextChanged( bytes32 indexed node, string indexed indexedKey, string key, string value ); /** * Returns the text data associated with an RNS node and key. * @param node The RNS node to query. * @param key The text data key to query. * @return The associated text data. */ function text( bytes32 node, string calldata key ) external view returns (string memory); }
IPubkeyResolver.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IPubkeyResolver { event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y); /** * Returns the SECP256k1 public key associated with an RNS node. * Defined in EIP 619. * @param node The RNS node to query * @return x The X coordinate of the curve point for the public key. * @return y The Y coordinate of the curve point for the public key. */ function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y); }
IAddressResolver.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; /** * Interface for the new (multicoin) addr function. */ interface IAddressResolver { event AddressChanged( bytes32 indexed node, uint256 coinType, bytes newAddress ); function addr( bytes32 node, uint256 coinType ) external view returns (bytes memory); }
IDNSZoneResolver.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IDNSZoneResolver { // DNSZonehashChanged is emitted whenever a given node's zone hash is updated. event DNSZonehashChanged( bytes32 indexed node, bytes lastzonehash, bytes zonehash ); /** * zonehash obtains the hash for the zone. * @param node The RNS node to query. * @return The associated contenthash. */ function zonehash(bytes32 node) external view returns (bytes memory); }
IExtendedResolver.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; interface IExtendedResolver { function resolve( bytes memory name, bytes memory data ) external view returns (bytes memory); }
IDNSRecordResolver.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IDNSRecordResolver { // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated. event DNSRecordChanged( bytes32 indexed node, bytes name, uint16 resource, bytes record ); // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted. event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource); /** * Obtain a DNS record. * @param node the namehash of the node for which to fetch the record * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types * @return the DNS record in wire format if present, otherwise empty */ function dnsRecord( bytes32 node, bytes32 name, uint16 resource ) external view returns (bytes memory); }
IInterfaceResolver.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IInterfaceResolver { event InterfaceChanged( bytes32 indexed node, bytes4 indexed interfaceID, address implementer ); /** * Returns the address of a contract that implements the specified interface for this name. * If an implementer has not been set for this interfaceID and name, the resolver will query * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that * contract implements EIP165 and returns `true` for the specified interfaceID, its address * will be returned. * @param node The RNS node to query. * @param interfaceID The EIP 165 interface ID to check for. * @return The address that implements this interface, or 0 if the interface is unsupported. */ function interfaceImplementer( bytes32 node, bytes4 interfaceID ) external view returns (address); }
IContentHashResolver.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IContentHashResolver { event ContenthashChanged(bytes32 indexed node, bytes hash); /** * Returns the contenthash associated with an RNS node. * @param node The RNS node to query. * @return The associated contenthash. */ function contenthash(bytes32 node) external view returns (bytes memory); }
ERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
IERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
Gas Token: