Address Contract Verified
Address
0xAA63e72C77de751852f29F7a3d0670Ab23EBE496
Balance
0 ETH
Nonce
22
Code Size
17201 bytes
Creator
0x92eED028...c7F2 at tx 0xc20b0b45...e8f60f
Indexed Transactions
0
Contract Bytecode
17201 bytes
0x608060405234801561000f575f80fd5b5060043610610091575f3560e01c8063a2e03da411610064578063a2e03da4146100e5578063ca080d0a14610103578063dd9b12c614610121578063ec81aadb1461013d578063f2fde38b1461017057610091565b80630a75434114610095578063622ae7aa1461009f578063715018a6146100bd5780638da5cb5b146100c7575b5f80fd5b61009d61018c565b005b6100a76103aa565b6040516100b49190610fd8565b60405180910390f35b6100c56105cf565b005b6100cf6105e2565b6040516100dc9190611007565b60405180910390f35b6100ed610609565b6040516100fa9190611040565b60405180910390f35b61010b61062e565b6040516101189190611007565b60405180910390f35b61013b600480360381019061013691906110ec565b610653565b005b6101576004803603810190610152919061117c565b610aa2565b60405161016794939291906111ef565b60405180910390f35b61018a60048036038101906101859190611240565b610c27565b005b610194610cab565b5f73ffffffffffffffffffffffffffffffffffffffff1660025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610223576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161021a906112b5565b60405180910390fd5b5f60018054905067ffffffffffffffff811115610243576102426112d3565b5b6040519080825280602002602001820160405280156102715781602001602082028036833780820191505090505b5090505f5b60018054905081101561031f576001818154811061029757610296611300565b5b905f5260205f2090600402015f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168282815181106102d8576102d7611300565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508080600101915050610276565b5060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166311024b4a826040518263ffffffff1660e01b815260040161037a91906113d5565b5f604051808303815f87803b158015610391575f80fd5b505af11580156103a3573d5f803e3d5ffd5b5050505050565b60606001805480602002602001604051908101604052809291908181526020015f905b828210156105c6578382905f5260205f2090600402016040518060800160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820180546104a790611422565b80601f01602080910402602001604051908101604052809291908181526020018280546104d390611422565b801561051e5780601f106104f55761010080835404028352916020019161051e565b820191905f5260205f20905b81548152906001019060200180831161050157829003601f168201915b5050505050815260200160038201805461053790611422565b80601f016020809104026020016040519081016040528092919081815260200182805461056390611422565b80156105ae5780601f10610585576101008083540402835291602001916105ae565b820191905f5260205f20905b81548152906001019060200180831161059157829003601f168201915b505050505081525050815260200190600101906103cd565b50505050905090565b6105d7610cab565b6105e05f610d32565b565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61065b610cab565b5f60028484905061066c919061147f565b146106ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a39061151f565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361071a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161071190611587565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff1660035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036107a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107a0906115ef565b60405180910390fd5b5f5b83839050811015610a9c575f8484838181106107ca576107c9611300565b5b90506020028101906107dc9190611619565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505090505f858560018561083091906116a8565b8181106108405761083f611300565b5b90506020028101906108529190611619565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505090505f82828660035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040516108c890610dfa565b6108d594939291906116db565b604051809103905ff0801580156108ee573d5f803e3d5ffd5b509050600160405180608001604052808373ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff16815260200185815260200184815250908060018154018082558091505060019003905f5260205f2090600402015f909190919091505f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040820151816002019081610a0591906118c9565b506060820151816003019081610a1b91906118c9565b5050508073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f801b50b59a9c797b08c62fe4c8bee1aff31ff3246d488e359cedfc8e75ffd05f8585604051610a7d929190611998565b60405180910390a3505050600281610a9591906116a8565b90506107ab565b50505050565b60018181548110610ab1575f80fd5b905f5260205f2090600402015f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806002018054610b1a90611422565b80601f0160208091040260200160405190810160405280929190818152602001828054610b4690611422565b8015610b915780601f10610b6857610100808354040283529160200191610b91565b820191905f5260205f20905b815481529060010190602001808311610b7457829003601f168201915b505050505090806003018054610ba690611422565b80601f0160208091040260200160405190810160405280929190818152602001828054610bd290611422565b8015610c1d5780601f10610bf457610100808354040283529160200191610c1d565b820191905f5260205f20905b815481529060010190602001808311610c0057829003601f168201915b5050505050905084565b610c2f610cab565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c9f575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610c969190611007565b60405180910390fd5b610ca881610d32565b50565b610cb3610df3565b73ffffffffffffffffffffffffffffffffffffffff16610cd16105e2565b73ffffffffffffffffffffffffffffffffffffffff1614610d3057610cf4610df3565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610d279190611007565b60405180910390fd5b565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f33905090565b61292e806119ce83390190565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610e5982610e30565b9050919050565b610e6981610e4f565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f610eb182610e6f565b610ebb8185610e79565b9350610ecb818560208601610e89565b610ed481610e97565b840191505092915050565b5f608083015f830151610ef45f860182610e60565b506020830151610f076020860182610e60565b5060408301518482036040860152610f1f8282610ea7565b91505060608301518482036060860152610f398282610ea7565b9150508091505092915050565b5f610f518383610edf565b905092915050565b5f602082019050919050565b5f610f6f82610e07565b610f798185610e11565b935083602082028501610f8b85610e21565b805f5b85811015610fc65784840389528151610fa78582610f46565b9450610fb283610f59565b925060208a01995050600181019050610f8e565b50829750879550505050505092915050565b5f6020820190508181035f830152610ff08184610f65565b905092915050565b61100181610e4f565b82525050565b5f60208201905061101a5f830184610ff8565b92915050565b5f61102a82610e30565b9050919050565b61103a81611020565b82525050565b5f6020820190506110535f830184611031565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261108257611081611061565b5b8235905067ffffffffffffffff81111561109f5761109e611065565b5b6020830191508360208202830111156110bb576110ba611069565b5b9250929050565b6110cb81610e4f565b81146110d5575f80fd5b50565b5f813590506110e6816110c2565b92915050565b5f805f6040848603121561110357611102611059565b5b5f84013567ffffffffffffffff8111156111205761111f61105d565b5b61112c8682870161106d565b9350935050602061113f868287016110d8565b9150509250925092565b5f819050919050565b61115b81611149565b8114611165575f80fd5b50565b5f8135905061117681611152565b92915050565b5f6020828403121561119157611190611059565b5b5f61119e84828501611168565b91505092915050565b5f82825260208201905092915050565b5f6111c182610e6f565b6111cb81856111a7565b93506111db818560208601610e89565b6111e481610e97565b840191505092915050565b5f6080820190506112025f830187610ff8565b61120f6020830186610ff8565b818103604083015261122181856111b7565b9050818103606083015261123581846111b7565b905095945050505050565b5f6020828403121561125557611254611059565b5b5f611262848285016110d8565b91505092915050565b7f436869656656616c696461746f722061646472657373206e6f742073657400005f82015250565b5f61129f601e836111a7565b91506112aa8261126b565b602082019050919050565b5f6020820190508181035f8301526112cc81611293565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f6113618383610e60565b60208301905092915050565b5f602082019050919050565b5f6113838261132d565b61138d8185611337565b935061139883611347565b805f5b838110156113c85781516113af8882611356565b97506113ba8361136d565b92505060018101905061139b565b5085935050505092915050565b5f6020820190508181035f8301526113ed8184611379565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061143957607f821691505b60208210810361144c5761144b6113f5565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61148982611149565b915061149483611149565b9250826114a4576114a3611452565b5b828206905092915050565b7f496e707574206172726179206d757374206861766520616e206576656e206c655f8201527f6e67746800000000000000000000000000000000000000000000000000000000602082015250565b5f6115096024836111a7565b9150611514826114af565b604082019050919050565b5f6020820190508181035f830152611536816114fd565b9050919050565b7f496e76616c696420696e697469616c4f776e65722061646472657373000000005f82015250565b5f611571601c836111a7565b915061157c8261153d565b602082019050919050565b5f6020820190508181035f83015261159e81611565565b9050919050565b7f496e76616c696420436861696e526f75746572206164647265737300000000005f82015250565b5f6115d9601b836111a7565b91506115e4826115a5565b602082019050919050565b5f6020820190508181035f830152611606816115cd565b9050919050565b5f80fd5b5f80fd5b5f80fd5b5f80833560016020038436030381126116355761163461160d565b5b80840192508235915067ffffffffffffffff82111561165757611656611611565b5b60208301925060018202360383131561167357611672611615565b5b509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6116b282611149565b91506116bd83611149565b92508282019050808211156116d5576116d461167b565b5b92915050565b5f6080820190508181035f8301526116f381876111b7565b9050818103602083015261170781866111b7565b90506117166040830185610ff8565b6117236060830184610ff8565b95945050505050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026117887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261174d565b611792868361174d565b95508019841693508086168417925050509392505050565b5f819050919050565b5f6117cd6117c86117c384611149565b6117aa565b611149565b9050919050565b5f819050919050565b6117e6836117b3565b6117fa6117f2826117d4565b848454611759565b825550505050565b5f90565b61180e611802565b6118198184846117dd565b505050565b5b8181101561183c576118315f82611806565b60018101905061181f565b5050565b601f821115611881576118528161172c565b61185b8461173e565b8101602085101561186a578190505b61187e6118768561173e565b83018261181e565b50505b505050565b5f82821c905092915050565b5f6118a15f1984600802611886565b1980831691505092915050565b5f6118b98383611892565b9150826002028217905092915050565b6118d282610e6f565b67ffffffffffffffff8111156118eb576118ea6112d3565b5b6118f58254611422565b611900828285611840565b5f60209050601f831160018114611931575f841561191f578287015190505b61192985826118ae565b865550611990565b601f19841661193f8661172c565b5f5b8281101561196657848901518255600182019150602085019450602081019050611941565b86831015611983578489015161197f601f891682611892565b8355505b6001600288020188555050505b505050505050565b5f6040820190508181035f8301526119b081856111b7565b905081810360208301526119c481846111b7565b9050939250505056fe60806040525f600655348015610013575f80fd5b5060405161292e38038061292e83398181016040528101906100359190610657565b81848481600390816100479190610900565b5080600490816100579190610900565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100ca575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100c191906109de565b60405180910390fd5b6100d98161014f60201b60201c565b505f600560146101000a81548160ff0219169083151502179055506101068260065461021260201b60201c565b8060095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050610ab4565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610282575f6040517fec442f0500000000000000000000000000000000000000000000000000000000815260040161027991906109de565b60405180910390fd5b6102935f838361029760201b60201c565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036102e7578060025f8282546102db9190610a24565b925050819055506103b5565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610370578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161036793929190610a66565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036103fc578060025f8282540392505081905550610446565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516104a39190610a9b565b60405180910390a3505050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61050f826104c9565b810181811067ffffffffffffffff8211171561052e5761052d6104d9565b5b80604052505050565b5f6105406104b0565b905061054c8282610506565b919050565b5f67ffffffffffffffff82111561056b5761056a6104d9565b5b610574826104c9565b9050602081019050919050565b8281835e5f83830152505050565b5f6105a161059c84610551565b610537565b9050828152602081018484840111156105bd576105bc6104c5565b5b6105c8848285610581565b509392505050565b5f82601f8301126105e4576105e36104c1565b5b81516105f484826020860161058f565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610626826105fd565b9050919050565b6106368161061c565b8114610640575f80fd5b50565b5f815190506106518161062d565b92915050565b5f805f806080858703121561066f5761066e6104b9565b5b5f85015167ffffffffffffffff81111561068c5761068b6104bd565b5b610698878288016105d0565b945050602085015167ffffffffffffffff8111156106b9576106b86104bd565b5b6106c5878288016105d0565b93505060406106d687828801610643565b92505060606106e787828801610643565b91505092959194509250565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061074157607f821691505b602082108103610754576107536106fd565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026107b67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261077b565b6107c0868361077b565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6108046107ff6107fa846107d8565b6107e1565b6107d8565b9050919050565b5f819050919050565b61081d836107ea565b6108316108298261080b565b848454610787565b825550505050565b5f90565b610845610839565b610850818484610814565b505050565b5b81811015610873576108685f8261083d565b600181019050610856565b5050565b601f8211156108b8576108898161075a565b6108928461076c565b810160208510156108a1578190505b6108b56108ad8561076c565b830182610855565b50505b505050565b5f82821c905092915050565b5f6108d85f19846008026108bd565b1980831691505092915050565b5f6108f083836108c9565b9150826002028217905092915050565b610909826106f3565b67ffffffffffffffff811115610922576109216104d9565b5b61092c825461072a565b610937828285610877565b5f60209050601f831160018114610968575f8415610956578287015190505b61096085826108e5565b8655506109c7565b601f1984166109768661075a565b5f5b8281101561099d57848901518255600182019150602085019450602081019050610978565b868310156109ba57848901516109b6601f8916826108c9565b8355505b6001600288020188555050505b505050505050565b6109d88161061c565b82525050565b5f6020820190506109f15f8301846109cf565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610a2e826107d8565b9150610a39836107d8565b9250828201905080821115610a5157610a506109f7565b5b92915050565b610a60816107d8565b82525050565b5f606082019050610a795f8301866109cf565b610a866020830185610a57565b610a936040830184610a57565b949350505050565b5f602082019050610aae5f830184610a57565b92915050565b611e6d80610ac15f395ff3fe608060405234801561000f575f80fd5b50600436106101a7575f3560e01c8063715018a6116100f7578063a9a106e711610095578063dd62ed3e1161006f578063dd62ed3e14610481578063ec0cdf62146104b1578063f2fde38b146104e1578063f44637ba146104fd576101a7565b8063a9a106e714610403578063aa2fe91b14610433578063ca080d0a14610463576101a7565b80638da5cb5b116100d15780638da5cb5b1461037b57806395d89b4114610399578063983b2d56146103b7578063a9059cbb146103d3576101a7565b8063715018a61461034b57806379cc6790146103555780638456cb5914610371576101a7565b8063313ce5671161016457806340c10f191161013e57806340c10f19146102c557806342966c68146102e15780635c975abb146102fd57806370a082311461031b576101a7565b8063313ce5671461027f578063378dc3dc1461029d5780633f4ba83a146102bb576101a7565b806302846858146101ab57806306fdde03146101c7578063095ea7b3146101e557806318160ddd1461021557806323b872dd146102335780633092afd514610263575b5f80fd5b6101c560048036038101906101c091906117d9565b610519565b005b6101cf6105bb565b6040516101dc9190611874565b60405180910390f35b6101ff60048036038101906101fa91906118c7565b61064b565b60405161020c919061191f565b60405180910390f35b61021d61066d565b60405161022a9190611947565b60405180910390f35b61024d60048036038101906102489190611960565b610676565b60405161025a919061191f565b60405180910390f35b61027d600480360381019061027891906117d9565b610693565b005b610287610735565b60405161029491906119cb565b60405180910390f35b6102a561073d565b6040516102b29190611947565b60405180910390f35b6102c3610743565b005b6102df60048036038101906102da91906118c7565b610755565b005b6102fb60048036038101906102f691906119e4565b6107f4565b005b610305610891565b604051610312919061191f565b60405180910390f35b610335600480360381019061033091906117d9565b6108a7565b6040516103429190611947565b60405180910390f35b6103536108ec565b005b61036f600480360381019061036a91906118c7565b6108ff565b005b61037961099e565b005b6103836109b0565b6040516103909190611a1e565b60405180910390f35b6103a16109d8565b6040516103ae9190611874565b60405180910390f35b6103d160048036038101906103cc91906117d9565b610a68565b005b6103ed60048036038101906103e891906118c7565b610b0b565b6040516103fa919061191f565b60405180910390f35b61041d600480360381019061041891906119e4565b610b26565b60405161042a9190611874565b60405180910390f35b61044d600480360381019061044891906117d9565b610bd1565b60405161045a919061191f565b60405180910390f35b61046b610bee565b6040516104789190611a92565b60405180910390f35b61049b60048036038101906104969190611aab565b610c13565b6040516104a89190611947565b60405180910390f35b6104cb60048036038101906104c691906117d9565b610c95565b6040516104d8919061191f565b60405180910390f35b6104fb60048036038101906104f691906117d9565b610cb2565b005b610517600480360381019061051291906117d9565b610d36565b005b610521610dd9565b5f60085f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f90eabbc0c667db2a5029ed6bc0f5fe9f356d11684a4ca9fcfaec0e53f12b9c8e60405160405180910390a250565b6060600380546105ca90611b16565b80601f01602080910402602001604051908101604052809291908181526020018280546105f690611b16565b80156106415780601f1061061857610100808354040283529160200191610641565b820191905f5260205f20905b81548152906001019060200180831161062457829003601f168201915b5050505050905090565b5f80610655610e60565b9050610662818585610e67565b600191505092915050565b5f600254905090565b5f61067f610e79565b61068a848484610eba565b90509392505050565b61069b610dd9565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669260405160405180910390a250565b5f6012905090565b60065481565b61074b610dd9565b610753610ee8565b565b60075f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff166107de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d590611b90565b60405180910390fd5b6107e6610e79565b6107f08282610f4a565b5050565b60085f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1661087d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087490611bf8565b60405180910390fd5b610885610e79565b61088e81610fc9565b50565b5f600560149054906101000a900460ff16905090565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6108f4610dd9565b6108fd5f610fdd565b565b60085f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f90611bf8565b60405180910390fd5b610990610e79565b61099a82826110a0565b5050565b6109a6610dd9565b6109ae6110c0565b565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600480546109e790611b16565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1390611b16565b8015610a5e5780601f10610a3557610100808354040283529160200191610a5e565b820191905f5260205f20905b815481529060010190602001808311610a4157829003601f168201915b5050505050905090565b610a70610dd9565b600160075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f660405160405180910390a250565b5f610b14610e79565b610b1e8383611123565b905092915050565b60605f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663804ea334846040518263ffffffff1660e01b8152600401610b839190611947565b5f60405180830381865afa158015610b9d573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610bc59190611d48565b50905080915050919050565b6007602052805f5260405f205f915054906101000a900460ff1681565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b6008602052805f5260405f205f915054906101000a900460ff1681565b610cba610dd9565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d2a575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610d219190611a1e565b60405180910390fd5b610d3381610fdd565b50565b610d3e610dd9565b600160085f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f86e57fd2b90329052917118de7c3f521f400d439b9650deaa906a25b08b9456060405160405180910390a250565b610de1610e60565b73ffffffffffffffffffffffffffffffffffffffff16610dff6109b0565b73ffffffffffffffffffffffffffffffffffffffff1614610e5e57610e22610e60565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610e559190611a1e565b60405180910390fd5b565b5f33905090565b610e748383836001611145565b505050565b610e81610891565b15610eb8576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f80610ec4610e60565b9050610ed1858285611314565b610edc8585856113a6565b60019150509392505050565b610ef0611496565b5f600560146101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610f33610e60565b604051610f409190611a1e565b60405180910390a1565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610fba575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610fb19190611a1e565b60405180910390fd5b610fc55f83836114d6565b5050565b610fda610fd4610e60565b826116ef565b50565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6110b2826110ac610e60565b83611314565b6110bc82826116ef565b5050565b6110c8610e79565b6001600560146101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861110c610e60565b6040516111199190611a1e565b60405180910390a1565b5f8061112d610e60565b905061113a8185856113a6565b600191505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036111b5575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016111ac9190611a1e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611225575f6040517f94280d6200000000000000000000000000000000000000000000000000000000815260040161121c9190611a1e565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550801561130e578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516113059190611947565b60405180910390a35b50505050565b5f61131f8484610c13565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146113a05781811015611391578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161138893929190611da2565b60405180910390fd5b61139f84848484035f611145565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611416575f6040517f96c6fd1e00000000000000000000000000000000000000000000000000000000815260040161140d9190611a1e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611486575f6040517fec442f0500000000000000000000000000000000000000000000000000000000815260040161147d9190611a1e565b60405180910390fd5b6114918383836114d6565b505050565b61149e610891565b6114d4576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611526578060025f82825461151a9190611e04565b925050819055506115f4565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050818110156115af578381836040517fe450d38c0000000000000000000000000000000000000000000000000000000081526004016115a693929190611da2565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361163b578060025f8282540392505081905550611685565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516116e29190611947565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361175f575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016117569190611a1e565b60405180910390fd5b61176a825f836114d6565b5050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6117a88261177f565b9050919050565b6117b88161179e565b81146117c2575f80fd5b50565b5f813590506117d3816117af565b92915050565b5f602082840312156117ee576117ed611777565b5b5f6117fb848285016117c5565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61184682611804565b611850818561180e565b935061186081856020860161181e565b6118698161182c565b840191505092915050565b5f6020820190508181035f83015261188c818461183c565b905092915050565b5f819050919050565b6118a681611894565b81146118b0575f80fd5b50565b5f813590506118c18161189d565b92915050565b5f80604083850312156118dd576118dc611777565b5b5f6118ea858286016117c5565b92505060206118fb858286016118b3565b9150509250929050565b5f8115159050919050565b61191981611905565b82525050565b5f6020820190506119325f830184611910565b92915050565b61194181611894565b82525050565b5f60208201905061195a5f830184611938565b92915050565b5f805f6060848603121561197757611976611777565b5b5f611984868287016117c5565b9350506020611995868287016117c5565b92505060406119a6868287016118b3565b9150509250925092565b5f60ff82169050919050565b6119c5816119b0565b82525050565b5f6020820190506119de5f8301846119bc565b92915050565b5f602082840312156119f9576119f8611777565b5b5f611a06848285016118b3565b91505092915050565b611a188161179e565b82525050565b5f602082019050611a315f830184611a0f565b92915050565b5f819050919050565b5f611a5a611a55611a508461177f565b611a37565b61177f565b9050919050565b5f611a6b82611a40565b9050919050565b5f611a7c82611a61565b9050919050565b611a8c81611a72565b82525050565b5f602082019050611aa55f830184611a83565b92915050565b5f8060408385031215611ac157611ac0611777565b5b5f611ace858286016117c5565b9250506020611adf858286016117c5565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611b2d57607f821691505b602082108103611b4057611b3f611ae9565b5b50919050565b7f4e6f7420616e20617574686f72697a6564206d696e74657200000000000000005f82015250565b5f611b7a60188361180e565b9150611b8582611b46565b602082019050919050565b5f6020820190508181035f830152611ba781611b6e565b9050919050565b7f4e6f7420616e20617574686f72697a6564206275726e657200000000000000005f82015250565b5f611be260188361180e565b9150611bed82611bae565b602082019050919050565b5f6020820190508181035f830152611c0f81611bd6565b9050919050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611c548261182c565b810181811067ffffffffffffffff82111715611c7357611c72611c1e565b5b80604052505050565b5f611c8561176e565b9050611c918282611c4b565b919050565b5f67ffffffffffffffff821115611cb057611caf611c1e565b5b611cb98261182c565b9050602081019050919050565b5f611cd8611cd384611c96565b611c7c565b905082815260208101848484011115611cf457611cf3611c1a565b5b611cff84828561181e565b509392505050565b5f82601f830112611d1b57611d1a611c16565b5b8151611d2b848260208601611cc6565b91505092915050565b5f81519050611d428161189d565b92915050565b5f8060408385031215611d5e57611d5d611777565b5b5f83015167ffffffffffffffff811115611d7b57611d7a61177b565b5b611d8785828601611d07565b9250506020611d9885828601611d34565b9150509250929050565b5f606082019050611db55f830186611a0f565b611dc26020830185611938565b611dcf6040830184611938565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611e0e82611894565b9150611e1983611894565b9250828201905080821115611e3157611e30611dd7565b5b9291505056fea264697066735822122062a36c3ddcaf28f353e7ebe2f447d17b0a31089946e97c0a01600a6bfb20c74564736f6c634300081a0033a264697066735822122029bd586f9b68ad6a93da9f7696e1bc5edc9f774918f5a5ab58d1cba35fb9e69664736f6c634300081a0033
Verified Source Code Full Match
Compiler: v0.8.26+commit.8a97fa7a
EVM: cancun
Optimization: No
BridgeToken.sol 103 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./sources/OZ/ERC20.sol";
import "./sources/OZ/Ownable.sol";
import "./sources/OZ/ERC20Burnable.sol";
import "./sources/OZ/Pausable.sol";
interface IChainRouter {
function getChainInfo(uint256 networkId) external view returns (string memory, uint256);
}
contract BridgeToken is ERC20, ERC20Burnable, Ownable, Pausable {
uint256 public initialSupply = 0 * 10**18; // No supply at deployment
// Authorized minters and burners
mapping(address => bool) public authorizedMinters;
mapping(address => bool) public authorizedBurners;
// Reference to the ChainRouter contract
IChainRouter public chainRouter;
event MinterAdded(address indexed minter);
event MinterRemoved(address indexed minter);
event BurnerAdded(address indexed burner);
event BurnerRemoved(address indexed burner);
// The constructor takes the initial owner address and calls the Ownable constructor
constructor (
string memory _name,
string memory _symbol,
address initialOwner,
address chainRouterAddress
)
ERC20 (_name, _symbol)
Ownable (initialOwner)
{
_mint(initialOwner, initialSupply);
chainRouter = IChainRouter(chainRouterAddress); // Initialize ChainRouter contract address
}
// Modifiers
modifier onlyAuthorizedMinter() {
require(authorizedMinters[msg.sender], "Not an authorized minter");
_;
}
modifier onlyAuthorizedBurner() {
require(authorizedBurners[msg.sender], "Not an authorized burner");
_;
}
function addMinter(address minter) external onlyOwner {
authorizedMinters[minter] = true;
emit MinterAdded(minter);
}
function removeMinter(address minter) external onlyOwner {
authorizedMinters[minter] = false;
emit MinterRemoved(minter);
}
function addBurner(address burner) external onlyOwner {
authorizedBurners[burner] = true;
emit BurnerAdded(burner);
}
function removeBurner(address burner) external onlyOwner {
authorizedBurners[burner] = false;
emit BurnerRemoved(burner);
}
function mint(address to, uint256 amount) external onlyAuthorizedMinter whenNotPaused {
_mint(to, amount);
}
function burn(uint256 amount) public override onlyAuthorizedBurner whenNotPaused {
super.burn(amount);
}
function burnFrom(address account, uint256 amount) public override onlyAuthorizedBurner whenNotPaused {
super.burnFrom(account, amount);
}
// Function to get the name of a registered blockchain from its ID (using ChainRouter)
function getBlockchainById(uint256 networkId) external view returns (string memory) {
// Fetch blockchain info from ChainRouter
(string memory chainName, ) = chainRouter.getChainInfo(networkId);
return chainName;
}
function pause() external onlyOwner {_pause();}
function unpause() external onlyOwner {_unpause();}
function transfer(address recipient, uint256 amount) public override whenNotPaused returns (bool) {
return super.transfer(recipient, amount);
}
function transferFrom(address sender, address recipient, uint256 amount) public override whenNotPaused returns (bool) {
return super.transferFrom(sender, recipient, amount);
}
}
EmoliumDeployerV2.sol 65 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./sources/OZ/Ownable.sol";
import "./BridgeToken.sol";
import "./chiefValidator.sol";
contract EmoliumTokenFactory is Ownable {
struct TokenInfo {
address tokenAddress;
address initialOwner;
string name;
string symbol;
}
TokenInfo[] public deployedTokens; // Deployed Emolium Liquid Tokens
event TokenDeployed(address indexed initialOwner, address indexed tokenAddress, string name, string symbol);
address payable public chiefValidator; // Emolium ChiefValidator address
address public chainRouter; // Emolium ChainRouter address
constructor(address initialOwner, address payable _chiefValidatorAddress, address _chainRouterAddress)
Ownable(initialOwner)
{
transferOwnership(initialOwner);
chiefValidator = _chiefValidatorAddress;
chainRouter = _chainRouterAddress;
}
// Deploy Liquid token
function deployLiquidToken(string[] calldata namesAndSymbols, address initialOwner) external onlyOwner {
require(namesAndSymbols.length % 2 == 0, "Input array must have an even length");
require(initialOwner != address(0), "Invalid initialOwner address");
require(chainRouter != address(0), "Invalid ChainRouter address");
for (uint256 i = 0; i < namesAndSymbols.length; i += 2) {
string memory name = namesAndSymbols[i];
string memory symbol = namesAndSymbols[i + 1];
BridgeToken newToken = new BridgeToken(name, symbol, initialOwner, chainRouter);
deployedTokens.push(TokenInfo(address(newToken), initialOwner, name, symbol));
emit TokenDeployed(initialOwner, address(newToken), name, symbol);
}
}
// Register Liquid Tokens in ChiefValidator
function registerTokens() external onlyOwner {
require(chiefValidator != address(0), "ChiefValidator address not set");
address[] memory tokenAddresses = new address[](deployedTokens.length);
for (uint256 i = 0; i < deployedTokens.length; i++) {
tokenAddresses[i] = deployedTokens[i].tokenAddress;
}
ChiefValidator(chiefValidator).registerBridgeTokens(tokenAddresses);
}
// Function to get the list of deployed tokens
function getDeployedTokens() external view returns (TokenInfo[] memory) {
return deployedTokens;
}
}
chiefValidator.sol 262 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./sources/OZ/Ownable.sol";
import "./sources/OZ/ReentrancyGuard.sol";
import "./sources/OZ/IERC20.sol";
import "./sources/OZ/Address.sol";
import "./sources/IWETH.sol";
import "./sources/IMintableERC20.sol";
import "./sources/IBridgedToken.sol";
import "./validatorFactory.sol";
import "./validator.sol";
interface IBurnableERC20 {
function burn(uint256 amount) external;
}
contract ChiefValidator is Ownable, ReentrancyGuard {
address public EMLTokenAddress;
ValidatorFactory public validatorFactory;
uint256 public emlRewardAmount;
address public bridgeDeposit;
address public wethAddress;
address public devAddress;
IWETH public weth;
// Retreive Bridge Tokens
mapping(address => bool) public bridgeTokens;
// Store Proofs
mapping(bytes32 => bool) public proofs; // bool => true (legit) or false (not submitted or fraud)
// Mapping of authorized Contracts
mapping(address => bool) public authorizedContracts;
// Events
event TokenDeployed(address indexed initialOwner, address indexed tokenAddress, string name, string symbol);
event ProofVerified(bytes32 indexed proofHash, bool valid);
event EMLMinted(address indexed validator, uint256 amount);
event BridgeTokenRegistered(address indexed tokenAddress);
event BridgedETH(address to, uint256 amount);
event BridgeFee(address to, uint256 amount);
event TokenBridgedIn(address indexed tokenAddress, address to, uint256 amount);
event BridgedTokenTransfered(address indexed tokenAddress, address to, uint256 amount);
event DeployerAuthorized(address indexed contractAddress, bool isAuthorized);
// Modifier
modifier onlyAuthorized() {
require(authorizedContracts[msg.sender], "Caller is not authorized");
_;
}
constructor(
address _EMLTokenAddress,
address _wethAddress,
address _devAddress,
address _initialOwner,
address _validatorFactory
) Ownable(_initialOwner)
{
EMLTokenAddress = _EMLTokenAddress;
validatorFactory = ValidatorFactory(_validatorFactory);
wethAddress = _wethAddress;
devAddress = _devAddress;
transferOwnership(_initialOwner);
}
// Autorize contracts for validator creation
function setAuthorization(address _contract, bool _isAuthorized) external onlyOwner {
authorizedContracts[_contract] = _isAuthorized;
emit DeployerAuthorized(_contract, _isAuthorized);
}
// Register Bridge Tokens
function registerBridgeTokens(address[] calldata tokens) external onlyAuthorized {
for (uint256 i = 0; i < tokens.length; i++) {
bridgeTokens[tokens[i]] = true;
emit BridgeTokenRegistered(tokens[i]);
}
}
// Update Bridge Tokens
function updateBridgeTokens(address tokenAddress, bool isRegistered) external onlyOwner {
bridgeTokens[tokenAddress] = isRegistered;
}
function isBridgeTokenRegistered(address token) external view returns (bool) {
return bridgeTokens[token];
}
// Verify Proof & Mint EML Rewards to validators
function verifyProof(string[] calldata proofData, bytes32 proofHash) external nonReentrant onlyOwner {
require(proofData.length == 6, "Invalid proof data length");
require(!proofs[proofHash], "Proof already submitted");
address[] memory validators = validatorFactory.getDeployedValidators();
uint256 activeValidatorCount = 0;
address[] memory activeValidators = new address[](validators.length);
for (uint256 i = 0; i < validators.length; i++) {
if (Validator(validators[i]).isActive()) {
activeValidators[activeValidatorCount] = validators[i];
activeValidatorCount++;
}
}
require(activeValidatorCount > 0, "No active validators found");
bool proofValid = false;
for (uint256 i = 0; i < activeValidatorCount; i++) {
bytes32 keccakResult = Validator(activeValidators[i]).calculateKeccak256(proofData);
if (keccakResult == proofHash) {
proofValid = true;
break;
}
}
if (proofValid) {
mintEMLRewards();
handleBridgedToken(proofData);
proofs[proofHash] = true;
emit ProofVerified(proofHash, true);
} else {
emit ProofVerified(proofHash, false);
}
}
// Mint EML Rewards
function mintEMLRewards() internal {
address[] memory validators = validatorFactory.getDeployedValidators();
uint256 totalActiveValidators = 0;
// Number of active Validators
for (uint256 i = 0; i < validators.length; i++) {
if (Validator(validators[i]).isActive()) {
totalActiveValidators++;
}
}
require(totalActiveValidators > 0, "No active validators found");
uint256 rewardPerValidator = emlRewardAmount / totalActiveValidators;
// EML Mint to Active Validators only & equally
for (uint256 i = 0; i < validators.length; i++) {
if (Validator(validators[i]).isActive()) {
address validatorOwner = Validator(validators[i]).getValidatorOwner();
// Call EML Mint function
IMintableERC20(EMLTokenAddress).mint(validatorOwner, rewardPerValidator);
emit EMLMinted(validatorOwner, rewardPerValidator);
}
}
}
// Handle Bridge Operations
function handleBridgedToken(string[] calldata proofData) internal {
address tokenAddress = parseAddress(proofData[0]);
uint256 amount = parseUint(proofData[1]);
address destination = parseAddress(proofData[2]);
uint256 timestamp = parseUint(proofData[3]);
string memory emoliumSaltData = proofData[4];
uint256 providedFee = parseUint(proofData[5]);
require(timestamp >= 0, "Invalid timestamp");
require(bytes(emoliumSaltData).length > 0, "Invalid salt data");
require(providedFee >= 0, "Invalid fee");
// Fee calculation and validation
uint256 calculatedFee = (amount * providedFee) / 10000;
uint256 netAmount = amount - calculatedFee;
// Handle ETH & WETH
if (tokenAddress == wethAddress) {
IWETH(wethAddress).withdraw(amount);
payable(devAddress).transfer(calculatedFee);
payable(destination).transfer(netAmount);
emit BridgedETH(destination, netAmount);
if (calculatedFee > 0) emit BridgeFee(devAddress, calculatedFee);
}
// Handle Emolium Bridge Registered Token
else if (bridgeTokens[tokenAddress]) {
IBridgedToken(tokenAddress).mint(destination, netAmount);
IBridgedToken(tokenAddress).mint(devAddress, calculatedFee);
emit TokenBridgedIn(tokenAddress, destination, netAmount);
if (calculatedFee > 0) emit BridgeFee(devAddress, calculatedFee);
}
// Handle all other ERC20 tokens
else {
IERC20(tokenAddress).transfer(destination, netAmount);
IERC20(tokenAddress).transfer(devAddress, calculatedFee);
emit BridgedTokenTransfered(tokenAddress, destination, netAmount);
if (calculatedFee > 0) emit BridgeFee(devAddress, calculatedFee);
}
}
// Convert string to uint
function parseUint(string memory _value) internal pure returns (uint256) {
bytes memory b = bytes(_value);
uint256 number = 0;
for (uint256 i = 0; i < b.length; i++) {
number = number * 10 + (uint256(uint8(b[i])) - 48);
}
return number;
}
// Convert string to address
function parseAddress(string memory _value) internal pure returns (address) {
bytes memory b = bytes(_value);
require(b.length == 42, "Invalid address length"); // Inclut '0x' au début
uint160 number;
for (uint256 i = 2; i < b.length; i++) { // Skip '0x'
number *= 16;
uint8 c = uint8(b[i]);
if (c >= 48 && c <= 57) {
number += c - 48;
} else if (c >= 97 && c <= 102) {
number += c - 87;
} else if (c >= 65 && c <= 70) {
number += c - 55;
}
}
return address(number);
}
// Setters for addresses
function setBridgeDeposit(address _bridgeDeposit) external onlyOwner {
bridgeDeposit = _bridgeDeposit;
}
function setWethAddress(address _wethAddress) external onlyOwner {
wethAddress = _wethAddress;
}
// Set EML Reward Amount
function setEMLRewardAmount(uint256 _amount) external onlyOwner {
emlRewardAmount = _amount;
}
// Get Proof Status
function getProofStatus(bytes32 proofHash) external view returns (bool) {
return proofs[proofHash];
}
// Emergency & Rescue Functions
function rescueETH() external onlyOwner {
require(address(this).balance > 0, "Insufficient ETH balance");
payable(devAddress).transfer(address(this).balance);
}
function rescueERC20(address token, uint256 amount) external onlyOwner {
IERC20 erc20 = IERC20(token);
require(erc20.balanceOf(address(this)) >= amount, "Insufficient token balance");
erc20.transfer(devAddress, amount);
}
function rescueWETH(uint256 amount) external onlyOwner {
require(weth.balanceOf(address(this)) >= amount, "Insufficient WETH balance");
weth.transfer(devAddress, amount);
}
receive() external payable {}
}
IBridgedToken.sol 20 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IBridgedToken {
function mint(address to, uint256 amount) external;
function burn(address from, uint256 amount) external;
function burnFrom(address from, uint256 amount) external;
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function tokenAddress() external view returns (address);
function mintable() external view returns (bool);
function burnable() external view returns (bool);
}
IMintableERC20.sol 19 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IMintableERC20 {
function mint(address to, uint256 amount) external;
function burn(address from, uint256 amount) external;
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function tokenAddress() external view returns (address);
function mintable() external view returns (bool);
function burnable() external view returns (bool);
}
IWETH.sol 14 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IWETH {
function deposit() external payable;
function withdraw(uint256 wad) external;
function balanceOf(address guy) external view returns (uint256);
function transfer(address dst, uint256 wad) external returns (bool);
function approve(address usr, uint256 wad) external returns (bool);
function transferFrom(address src, address dst, uint256 wad) external returns (bool);
function allowance(address src, address dst) external view returns (uint256);
event Deposit(address indexed dst, uint256 wad);
event Withdrawal(address indexed src, uint256 wad);
}
Address.sol 78 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
import "./Errors.sol";
library Address {
error AddressEmptyCode(address target);
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert Errors.InsufficientBalance(address(this).balance, amount);
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert Errors.FailedCall();
}
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
function _revert(bytes memory returndata) 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
assembly ("memory-safe") {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert Errors.FailedCall();
}
}
}
Context.sol 18 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
ERC20.sol 147 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import "./IERC20.sol";
import "./IERC20Metadata.sol";
import "./Context.sol";
import "./draft-IERC6093.sol";
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual returns (string memory) {
return _name;
}
function symbol() public view virtual returns (string memory) {
return _symbol;
}
function decimals() public view virtual returns (uint8) {
return 18;
}
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
_totalSupply -= value;
}
} else {
unchecked {
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}
ERC20Burnable.sol 19 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol)
pragma solidity ^0.8.20;
import "./ERC20.sol";
import "./Context.sol";
abstract contract ERC20Burnable is Context, ERC20 {
function burn(uint256 value) public virtual {
_burn(_msgSender(), value);
}
function burnFrom(address account, uint256 value) public virtual {
_spendAllowance(account, _msgSender(), value);
_burn(account, value);
}
}
Errors.sol 11 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
library Errors {
error InsufficientBalance(uint256 balance, uint256 needed);
error FailedCall();
error FailedDeployment();
error MissingPrecompile(address);
}
IERC20.sol 22 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
IERC20Metadata.sol 15 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
import "./IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
Ownable.sol 54 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import "./Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
Pausable.sol 56 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
import {Context} from "./Context.sol";
abstract contract Pausable is Context {
bool private _paused;
event Paused(address account);
event Unpaused(address account);
error EnforcedPause();
error ExpectedPause();
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
ReentrancyGuard.sol 39 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
abstract contract ReentrancyGuard {
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
_status = ENTERED;
}
function _nonReentrantAfter() private {
_status = NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
draft-IERC6093.sol 36 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
interface IERC20Errors {
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
error ERC20InvalidSender(address sender);
error ERC20InvalidReceiver(address receiver);
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
error ERC20InvalidApprover(address approver);
error ERC20InvalidSpender(address spender);
}
interface IERC721Errors {
error ERC721InvalidOwner(address owner);
error ERC721NonexistentToken(uint256 tokenId);
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
error ERC721InvalidSender(address sender);
error ERC721InvalidReceiver(address receiver);
error ERC721InsufficientApproval(address operator, uint256 tokenId);
error ERC721InvalidApprover(address approver);
error ERC721InvalidOperator(address operator);
}
interface IERC1155Errors {
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
error ERC1155InvalidSender(address sender);
error ERC1155InvalidReceiver(address receiver);
error ERC1155MissingApprovalForAll(address operator, address owner);
error ERC1155InvalidApprover(address approver);
error ERC1155InvalidOperator(address operator);
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
validator.sol 101 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./sources/OZ/IERC20.sol";
import "./sources/OZ/Ownable.sol";
contract Validator is Ownable {
address public EMLTokenAddress;
address public validatorFactory;
uint256 public validatorPrice;
address public admin;
bool public active = false;
// Validator Current Owner
mapping(address => address) public validatorOwners;
// Mapping to associate the contract address with the validator address
mapping(address => address) public validatorContracts;
// Events
event EMLBalanceChecked(uint256 balance);
event ValidatorCount(uint256 activeCount, uint256 maxCount);
event ValidatorClosed(address indexed owner, uint256 amount);
event ValidatorOpened();
event ValidatorClosedEvent();
constructor(address _EMLTokenAddress, address _initialOwner, address _validatorFactory) Ownable(_initialOwner) {
EMLTokenAddress = _EMLTokenAddress;
admin = _initialOwner;
validatorFactory = _validatorFactory; // Set the validatorFactory by default
validatorContracts[address(this)] = address(this);
validatorOwners[address(this)] = _initialOwner;
}
// Keccak hash function for an array of strings
function calculateKeccak256(string[] calldata inputs) external view returns (bytes32) {
require(active, "Validator is not active"); // Check if the validator is active
// Concatenate all strings in the array
bytes memory concatenatedString;
for (uint256 i = 0; i < inputs.length; i++) {
concatenatedString = abi.encodePacked(concatenatedString, inputs[i]);
}
// Calculate the Keccak256 hash of the concatenated string
bytes32 hash = keccak256(concatenatedString);
return hash;
}
// Set a new validator factory
function setValidatorFactory(address _validatorFactory) external onlyOwner {
require(_validatorFactory != address(0), "Invalid validator factory address");
validatorFactory = _validatorFactory;
}
// Return the validator contract address
function getValidatorContractAddress() external view returns (address) {
return validatorContracts[address(this)];
}
// Return the current validator owner
function getValidatorOwner() external view returns (address) {
return validatorOwners[address(this)];
}
// Return the amount of EML available in the contract
function getEMLBalance() external view returns (uint256) {
return IERC20(EMLTokenAddress).balanceOf(address(this));
}
// Function to close the validator and send the EML balance to the owner
function closeValidator() external onlyOwner {
uint256 balance = IERC20(EMLTokenAddress).balanceOf(address(this));
require(balance > 0, "No EML tokens to transfer");
IERC20(EMLTokenAddress).transfer(owner(), balance);
active = false;
emit ValidatorClosed(owner(), balance);
emit ValidatorClosedEvent();
}
// Open the validator if it holds at least 20,000 EML
function openValidator() external onlyOwner {
uint256 emlBalance = IERC20(EMLTokenAddress).balanceOf(address(this));
emit EMLBalanceChecked(emlBalance); // Log la balance
require(emlBalance >= 20000 * 10**18, "Validator must hold at least 20,000 EML");
active = true;
emit ValidatorOpened();
}
// Function to check if the validator is active
function isActive() external view returns (bool) {
return active;
}
// Function to get the admin address
function getAdmin() external view returns (address) {
return admin;
}
}
validatorFactory.sol 109 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./sources/OZ/Ownable.sol";
import "./validator.sol";
contract ValidatorFactory is Ownable {
// Mapping to store the addresses of deployed validators
mapping(address => bool) public validators;
// Mapping of authorized Contracts
mapping(address => bool) public authorizedContracts;
// List of deployed validators
address[] public deployedValidators;
// Maximum number of active validators
uint256 public constant MAX_ACTIVE_VALIDATORS = 25;
// Events
event ValidatorCreated(address indexed validatorAddress);
event ContractAuthorized(address indexed contractAddress, bool isAuthorized);
// Modifier
modifier onlyAuthorized() {
require(authorizedContracts[msg.sender], "Caller is not authorized");
_;
}
constructor(address _initialOwner) Ownable(_initialOwner) {
}
// Autorize contracts for validator creation
function setAuthorization(address _contract, bool _isAuthorized) external onlyOwner {
authorizedContracts[_contract] = _isAuthorized;
emit ContractAuthorized(_contract, _isAuthorized);
}
// Function to create a single Validator and assign ownership to the provided owner
function createValidator(address _EMLTokenAddress, address _owner) external onlyAuthorized returns (address) {
// Check the number of active validators
uint256 activeValidatorCount = 0;
for (uint256 i = 0; i < deployedValidators.length; i++) {
if (Validator(deployedValidators[i]).isActive()) {
activeValidatorCount++;
}
}
require(
activeValidatorCount < MAX_ACTIVE_VALIDATORS,
"Maximum number of active validators reached"
);
// Create the validator and pass this factory address in the constructor
Validator newValidator = new Validator(_EMLTokenAddress, _owner, address(this));
// Register the new validator in the factory
address validatorAddress = address(newValidator);
validators[validatorAddress] = true;
deployedValidators.push(validatorAddress);
emit ValidatorCreated(validatorAddress);
return validatorAddress;
}
// Create a batch of Validators
function createInitialValidators(address _EMLTokenAddress, uint256 numberOfValidators) external onlyOwner {
require(numberOfValidators > 0, "Number of validators must be greater than 0");
require(numberOfValidators <= MAX_ACTIVE_VALIDATORS, "Cannot create more than the maximum allowed validators");
// Check active Validators number
uint256 activeValidatorCount = 0;
for (uint256 i = 0; i < deployedValidators.length; i++) {
if (Validator(deployedValidators[i]).isActive()) {
activeValidatorCount++;
}
}
require(
deployedValidators.length + numberOfValidators <= MAX_ACTIVE_VALIDATORS || activeValidatorCount < MAX_ACTIVE_VALIDATORS,
"Cannot exceed the maximum number of validators"
);
for (uint256 i = 0; i < numberOfValidators; i++) {
Validator newValidator = new Validator(_EMLTokenAddress, msg.sender, address(this));
address validatorAddress = address(newValidator);
validators[validatorAddress] = true;
deployedValidators.push(validatorAddress);
emit ValidatorCreated(validatorAddress);
}
}
// Check if a validator is active
function isValidatorActive(address validatorAddress) external view returns (bool) {
require(validators[validatorAddress], "Validator not found");
return Validator(validatorAddress).isActive();
}
// Get the owner of a validator
function getValidatorOwner(address validatorAddress) external view returns (address) {
require(validators[validatorAddress], "Validator not found");
return Validator(validatorAddress).getValidatorOwner();
}
// Get the list of deployed validators
function getDeployedValidators() external view returns (address[] memory) {
return deployedValidators;
}
}
Read Contract
chainRouter 0xca080d0a → address
chiefValidator 0xa2e03da4 → address
deployedTokens 0xec81aadb → address, address, string, string
getDeployedTokens 0x622ae7aa → tuple[]
owner 0x8da5cb5b → address
Write Contract 4 functions
These functions modify contract state and require a wallet transaction to execute.
deployLiquidToken 0xdd9b12c6
string[] namesAndSymbols
address initialOwner
registerTokens 0x0a754341
No parameters
renounceOwnership 0x715018a6
No parameters
transferOwnership 0xf2fde38b
address newOwner
Recent Transactions
No transactions found for this address