Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0xefD94041Fa3c6b1802d48057Cd6a9B0ee4276a89
Balance 0 ETH
Nonce 1
Code Size 16014 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

16014 bytes
0x608060405234801561001057600080fd5b50600436106101985760003560e01c8063a217fddf116100e3578063df38461e1161008c578063fb81dff111610066578063fb81dff1146104a5578063fc2e05c5146104c5578063ff3bf644146104ec57600080fd5b8063df38461e14610452578063eec40a3914610472578063fb1466f11461048557600080fd5b8063cc60c413116100bd578063cc60c4131461040c578063d547741f1461042c578063d7d9b08c1461043f57600080fd5b8063a217fddf146103de578063acab5c1c146103e6578063c84e77cb146103f957600080fd5b80632f2ff15d116101455780636cb69f421161011f5780636cb69f42146102d757806391d1485414610387578063990bb9da146103cb57600080fd5b80632f2ff15d1461027d57806336568abe14610290578063548e75a9146102a357600080fd5b80631bf4026a116101765780631bf4026a14610232578063248a9ca3146102475780632b1ea8c61461026a57600080fd5b806301a0704c1461019d57806301ffc9a7146101c35780630f45cc81146101e6575b600080fd5b6101b06101ab366004613073565b6104ff565b6040519081526020015b60405180910390f35b6101d66101d13660046130b5565b610532565b60405190151581526020016101ba565b61020d7f000000000000000000000000104e363ac6521e55a24ae724855362acec3febe681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ba565b61024561024036600461313c565b6105cb565b005b6101b06102553660046131ad565b60009081526020819052604090206001015490565b6102456102783660046131df565b610744565b61024561028b36600461321e565b610c3d565b61024561029e36600461321e565b610c68565b6102b66102b13660046131df565b610cc6565b6040516fffffffffffffffffffffffffffffffff90911681526020016101ba565b610348604080516060810182526000808252602082018190529181019190915250604080516060810182526001546fffffffffffffffffffffffffffffffff8082168352600254166020830152700100000000000000000000000000000000900463ffffffff169181019190915290565b6040805182516fffffffffffffffffffffffffffffffff9081168252602080850151909116908201529181015163ffffffff16908201526060016101ba565b6101d661039536600461321e565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b6102456103d936600461324a565b610e3d565b6101b0600081565b6102456103f4366004613321565b611072565b6102b66104073660046131df565b6112fe565b61041f61041a3660046131ad565b6113f9565b6040516101ba91906133f4565b61024561043a36600461321e565b6114f6565b61024561044d36600461313c565b61151b565b6104656104603660046131df565b61165f565b6040516101ba91906135f4565b610245610480366004613607565b6118de565b61049861049336600461363d565b611a26565b6040516101ba9190613667565b6104b86104b3366004613607565b611bcd565b6040516101ba91906136ea565b6101b07f45504f43485f4d414e414745525f524f4c45000000000000000000000000000081565b6102456104fa366004613761565b611cae565b600082826040516020016105149291906138b5565b60405160208183030381529060405280519060200120905092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806105c557507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b7f45504f43485f4d414e414745525f524f4c4500000000000000000000000000006105f581611f39565b60055460ff1615610667576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265656e7472616e6379206973206e6f7420616c6c6f7765640000000000000060448201526064015b60405180910390fd5b600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560005b63ffffffff81168311156107145761070286868363ffffffff168181106106be576106be6138c9565b90506020020160208101906106d391906138f8565b85858463ffffffff168181106106eb576106eb6138c9565b90506020028101906106fd9190613913565b611f46565b8061070c816139a7565b915050610695565b5050600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550505050565b60055460ff16156107b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265656e7472616e6379206973206e6f7420616c6c6f77656400000000000000604482015260640161065e565b600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905563ffffffff811615801590610811575060015463ffffffff700100000000000000000000000000000000909104811690821611155b610877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4c453a20496e76616c69642065706f6368204944000000000000000000000000604482015260640161065e565b6000610882826112fe565b90506000816fffffffffffffffffffffffffffffffff1611610900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4c453a204e6f2066756e647320746f20636c61696d0000000000000000000000604482015260640161065e565b63ffffffff82166000908152600360205260409020600260038083015460ff169081111561093057610930613407565b14610997576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4c453a204e6f7420696e2072656c656173696e67207374616765000000000000604482015260640161065e565b6000600460006109a984600201612051565b815260208101919091526040016000206001015473ffffffffffffffffffffffffffffffffffffffff1690506109de84610cc6565b82546fffffffffffffffffffffffffffffffff9182167001000000000000000000000000000000000291161782556040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000104e363ac6521e55a24ae724855362acec3febe6169063a9059cbb90610ab3908490879060040173ffffffffffffffffffffffffffffffffffffffff9290921682526fffffffffffffffffffffffffffffffff16602082015260400190565b6020604051808303816000875af1158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906139cc565b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4c453a205472616e73666572206661696c656400000000000000000000000000604482015260640161065e565b81546fffffffffffffffffffffffffffffffff8082167001000000000000000000000000000000009092041603610bbc57600382810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790555b60028054849190600090610be39084906fffffffffffffffffffffffffffffffff166139ee565b82546fffffffffffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555050600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055505050565b600082815260208190526040902060010154610c5881611f39565b610c628383612081565b50505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610cb7576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cc1828261217d565b505050565b63ffffffff81166000818152600360205260408120909115801590610d0b575060015463ffffffff700100000000000000000000000000000000909104811690841611155b610d71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4c453a20496e76616c69642065706f6368204944000000000000000000000000604482015260640161065e565b600260038083015460ff1690811115610d8c57610d8c613407565b1015610d9b5750600092915050565b600181015467ffffffffffffffff16421115610e37576001810154600090610dcd9067ffffffffffffffff1642613a16565b6001830154909150600090610dfb9067ffffffffffffffff8082169168010000000000000000900416613a29565b67ffffffffffffffff16905080821115610e13578091505b8254610e32906fffffffffffffffffffffffffffffffff168383612238565b935050505b50919050565b7f45504f43485f4d414e414745525f524f4c450000000000000000000000000000610e6781611f39565b60055460ff1615610ed4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265656e7472616e6379206973206e6f7420616c6c6f77656400000000000000604482015260640161065e565b600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558786148015610f0d57508584145b8015610f1857508382145b610f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4c453a20556e657175616c206c656e6774680000000000000000000000000000604482015260640161065e565b60005b8881101561103e576110368a8a83818110610f9e57610f9e6138c9565b9050602002016020810190610fb39190613a49565b898984818110610fc557610fc56138c9565b9050602002016020810190610fda91906131df565b63ffffffff16888885818110610ff257610ff26138c9565b905060200201602081019061100791906131df565b63ffffffff1687878681811061101f5761101f6138c9565b90506020028101906110319190613913565b61230b565b600101610f81565b5050600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555050505050505050565b60055460ff16156110df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265656e7472616e6379206973206e6f7420616c6c6f77656400000000000000604482015260640161065e565b600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055600061111683836104ff565b600081815260046020526040902060018101549192509073ffffffffffffffffffffffffffffffffffffffff1633146111ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f4c453a204e6f2041757468000000000000000000000000000000000000000000604482015260640161065e565b73ffffffffffffffffffffffffffffffffffffffff8516611228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c453a20496e76616c6964207265636569766572206164647265737300000000604482015260640161065e565b6001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff871617905560405161127a9085908590613a7b565b6040805191829003822033835273ffffffffffffffffffffffffffffffffffffffff88166020840152917fd6dfc3916d4a5b81becd15700981576e1687000c5fa61f4b7e142b056e219161910160405180910390a25050600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055505050565b6000808263ffffffff16118015611335575060015463ffffffff700100000000000000000000000000000000909104811690831611155b61139b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4c453a20496e76616c69642065706f6368204944000000000000000000000000604482015260640161065e565b60006113a683610cc6565b63ffffffff841660009081526003602052604090208054919250906113f19070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1683613a8b565b949350505050565b6040805160608082018352815260006020820181905291810191909152600082815260046020908152604091829020825181546080938102820184019094526060810184815290939192849284918401828280156114a257602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116114655790505b50505091835250506001919091015473ffffffffffffffffffffffffffffffffffffffff8116602083015274010000000000000000000000000000000000000000900460ff16151560409091015292915050565b60008281526020819052604090206001015461151181611f39565b610c62838361217d565b7f45504f43485f4d414e414745525f524f4c45000000000000000000000000000061154581611f39565b60055460ff16156115b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265656e7472616e6379206973206e6f7420616c6c6f77656400000000000000604482015260640161065e565b600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560005b63ffffffff81168311156107145761164d86868363ffffffff16818110611609576116096138c9565b905060200201602081019061161e91906138f8565b85858463ffffffff16818110611636576116366138c9565b90506020028101906116489190613913565b612664565b80611657816139a7565b9150506115e0565b604080516101208101825260008082526060602083018190529282018190529181018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915260008263ffffffff161180156116df575060015463ffffffff700100000000000000000000000000000000909104811690831611155b611745576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4c453a20496e76616c69642065706f6368204944000000000000000000000000604482015260640161065e565b63ffffffff821660009081526003602052604081209061176484610cc6565b90506000611771856112fe565b83549091506000906117969084906fffffffffffffffffffffffffffffffff16613a8b565b90506040518061012001604052808560030160009054906101000a900460ff1660038111156117c7576117c7613407565b81526020018560020180546117db90613ab3565b80601f016020809104026020016040519081016040528092919081815260200182805461180790613ab3565b80156118545780601f1061182957610100808354040283529160200191611854565b820191906000526020600020905b81548152906001019060200180831161183757829003601f168201915b505050918352505085546fffffffffffffffffffffffffffffffff808216602084015260019097015467ffffffffffffffff80821660408501526801000000000000000090910416606083015270010000000000000000000000000000000090048616608082015292851660a084015292841660c083015290921660e09092019190915292915050565b7f45504f43485f4d414e414745525f524f4c45000000000000000000000000000061190881611f39565b60055460ff1615611975576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265656e7472616e6379206973206e6f7420616c6c6f77656400000000000000604482015260640161065e565b600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560005b63ffffffff81168311156119f8576119e684848363ffffffff168181106119cc576119cc6138c9565b90506020020160208101906119e191906131df565b6127be565b806119f0816139a7565b9150506119a3565b5050600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555050565b60608163ffffffff168363ffffffff161115611a9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4c453a20496e76616c69642065706f6368204944000000000000000000000000604482015260640161065e565b611aa88383613b00565b611ab3906001613b1c565b63ffffffff1667ffffffffffffffff811115611ad157611ad1613b38565b604051908082528060200260200182016040528015611b6657816020015b604080516101208101825260008082526060602080840182905293830182905282018190526080820181905260a0820181905260c0820181905260e0820181905261010082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611aef5790505b509050825b8263ffffffff168163ffffffff1611611bc657611b878161165f565b82611b928684613b00565b63ffffffff1681518110611ba857611ba86138c9565b60200260200101819052508080611bbe906139a7565b915050611b6b565b5092915050565b60608167ffffffffffffffff811115611be857611be8613b38565b604051908082528060200260200182016040528015611c5157816020015b60408051606080820183528152600060208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611c065790505b50905060005b82811015611bc657611c8961041a858584818110611c7757611c776138c9565b90506020028101906101ab9190613913565b828281518110611c9b57611c9b6138c9565b6020908102919091010152600101611c57565b7f45504f43485f4d414e414745525f524f4c450000000000000000000000000000611cd881611f39565b60055460ff1615611d45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265656e7472616e6379206973206e6f7420616c6c6f77656400000000000000604482015260640161065e565b600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558988148015611d7e57508786145b8015611d8957508584145b8015611d9457508382145b611dfa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4c453a20556e657175616c206c656e6774680000000000000000000000000000604482015260640161065e565b60005b63ffffffff81168b1115611f0357611ef18c8c8363ffffffff16818110611e2657611e266138c9565b9050602002016020810190611e3b91906131df565b8b8b8463ffffffff16818110611e5357611e536138c9565b9050602002016020810190611e689190613a49565b8a8a8563ffffffff16818110611e8057611e806138c9565b9050602002016020810190611e959190613b67565b89898663ffffffff16818110611ead57611ead6138c9565b9050602002016020810190611ec29190613b67565b88888763ffffffff16818110611eda57611eda6138c9565b9050602002810190611eec9190613913565b612982565b80611efb816139a7565b915050611dfd565b5050600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550505050505050505050565b611f438133612fa0565b50565b6000611f5283836104ff565b600081815260046020526040902060018101549192509073ffffffffffffffffffffffffffffffffffffffff8681169116148015611fa5575073ffffffffffffffffffffffffffffffffffffffff851615155b61200b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c453a20446f75626c6520636865636b206572726f7200000000000000000000604482015260640161065e565b60010180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905550505050565b6000816040516020016120649190613b91565b604051602081830303815290604052805190602001209050919050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff166121755760008381526020818152604080832073ffffffffffffffffffffffffffffffffffffffff86168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556121133390565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45060016105c5565b5060006105c5565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16156121755760008381526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8616808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45060016105c5565b600080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff858709858702925082811083820303915050806000036122905783828161228657612286613c3b565b0492505050612304565b80841161229c57600080fd5b600084868809851960019081018716968790049682860381900495909211909303600082900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b600180546000919060109061233990700100000000000000000000000000000000900463ffffffff166139a7565b825463ffffffff8281166101009490940a848102910219909116179092556000908152600360205260409081902090517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526fffffffffffffffffffffffffffffffff891660448201529192509073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000104e363ac6521e55a24ae724855362acec3febe616906323b872dd906064016020604051808303816000875af1158015612414573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243891906139cc565b61249e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4c453a20546f6b656e207472616e73666572206661696c656400000000000000604482015260640161065e565b8467ffffffffffffffff168667ffffffffffffffff161061251b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4c52543a2054696d65206572726f722e00000000000000000000000000000000604482015260640161065e565b80546fffffffffffffffffffffffffffffffff88167fffffffffffffffffffffffffffffffff0000000000000000000000000000000091821617825560018201805467ffffffffffffffff8881166801000000000000000002919093169289169290921791909117905560028101612594848683613cb8565b506003810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560006125ce85856104ff565b60008181526004602081815260408084208054600181018255908552919093206008820401805463ffffffff808a1660079094169094026101000a83810294021916929092179091559051919250907f45c6b311f2946239ca2508a94835ab508e2b8bd683b6bb14c2910322e598f9bc90612652908b908b908b908b908b90613dd2565b60405180910390a25050505050505050565b600061267083836104ff565b600081815260046020526040902060018101549192509074010000000000000000000000000000000000000000900460ff1615612709576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4c453a205265636569766572206164647265737320636f6e6669726d65640000604482015260640161065e565b6001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff871617905560405161275b9085908590613a7b565b60408051918290038220600184015473ffffffffffffffffffffffffffffffffffffffff908116845288166020840152917f9c9039cce6bde59b5f0031300888782ad8e9e65f07ab7660da8398bdc8019938910160405180910390a25050505050565b60008163ffffffff161180156127f4575060015463ffffffff700100000000000000000000000000000000909104811690821611155b61285a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4c453a20496e76616c69642065706f6368204944000000000000000000000000604482015260640161065e565b63ffffffff81166000908152600360205260409020600160038083015460ff169081111561288a5761288a613407565b146128f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4c453a20416c7265616479205374617274656400000000000000000000000000604482015260640161065e565b6003810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660021790558054600180546fffffffffffffffffffffffffffffffff92831692600091612948918591166139ee565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050565b63ffffffff86166000908152600360205260409020600160038083015460ff16908111156129b2576129b2613407565b14612a19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4c453a20416c7265616479205374617274656400000000000000000000000000604482015260640161065e565b80546fffffffffffffffffffffffffffffffff9081169087161115612b6b578054600090612a59906fffffffffffffffffffffffffffffffff1688613a8b565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526fffffffffffffffffffffffffffffffff821660448201529091507f000000000000000000000000104e363ac6521e55a24ae724855362acec3febe673ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af1158015612b06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2a91906139cc565b505080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff8716178155612cb4565b80546fffffffffffffffffffffffffffffffff9081169087161015612cb4578054600090612bac9088906fffffffffffffffffffffffffffffffff16613a8b565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff821660248201529091507f000000000000000000000000104e363ac6521e55a24ae724855362acec3febe673ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af1158015612c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c7791906139cc565b505080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff87161781555b8367ffffffffffffffff168567ffffffffffffffff1610612d31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4c52543a2054696d65206572726f722e00000000000000000000000000000000604482015260640161065e565b60018101805467ffffffffffffffff86811668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909216908816171790556000612d8584846104ff565b90506000612d9583600201612051565b9050808214612f4f576000818152600460205260408120905b8154811015612ef6578a63ffffffff16826000018281548110612dd357612dd36138c9565b6000918252602090912060088204015460079091166004026101000a900463ffffffff1603612eee5781548290612e0c90600190613a16565b81548110612e1c57612e1c6138c9565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff16826000018281548110612e5757612e576138c9565b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555081600001805480612e9d57612e9d613e29565b60008281526020902060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191820401805463ffffffff600460078516026101000a02191690559055612ef6565b600101612dae565b5060008381526004602081815260408320805460018101825590845292206008830401805463ffffffff808f1660079095169093026101000a938402929093021990921617905560028401612f4c868883613cb8565b50505b8863ffffffff167f426fa9f6edaf285d39f9b1e4c856e832716e028aed8af36999b6cf3133ef9ab58989898989604051612f8d959493929190613dd2565b60405180910390a2505050505050505050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16613026576040517fe2517d3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024810183905260440161065e565b5050565b60008083601f84011261303c57600080fd5b50813567ffffffffffffffff81111561305457600080fd5b60208301915083602082850101111561306c57600080fd5b9250929050565b6000806020838503121561308657600080fd5b823567ffffffffffffffff81111561309d57600080fd5b6130a98582860161302a565b90969095509350505050565b6000602082840312156130c757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461230457600080fd5b60008083601f84011261310957600080fd5b50813567ffffffffffffffff81111561312157600080fd5b6020830191508360208260051b850101111561306c57600080fd5b6000806000806040858703121561315257600080fd5b843567ffffffffffffffff81111561316957600080fd5b613175878288016130f7565b909550935050602085013567ffffffffffffffff81111561319557600080fd5b6131a1878288016130f7565b95989497509550505050565b6000602082840312156131bf57600080fd5b5035919050565b803563ffffffff811681146131da57600080fd5b919050565b6000602082840312156131f157600080fd5b612304826131c6565b803573ffffffffffffffffffffffffffffffffffffffff811681146131da57600080fd5b6000806040838503121561323157600080fd5b82359150613241602084016131fa565b90509250929050565b6000806000806000806000806080898b03121561326657600080fd5b883567ffffffffffffffff81111561327d57600080fd5b6132898b828c016130f7565b909950975050602089013567ffffffffffffffff8111156132a957600080fd5b6132b58b828c016130f7565b909750955050604089013567ffffffffffffffff8111156132d557600080fd5b6132e18b828c016130f7565b909550935050606089013567ffffffffffffffff81111561330157600080fd5b61330d8b828c016130f7565b999c989b5096995094979396929594505050565b60008060006040848603121561333657600080fd5b61333f846131fa565b9250602084013567ffffffffffffffff81111561335b57600080fd5b6133678682870161302a565b9497909650939450505050565b80516060808452815190840181905260009160200190829060808601905b808310156133bb5763ffffffff8451168252602082019150602084019350600183019250613392565b5073ffffffffffffffffffffffffffffffffffffffff602086015116602087015260408501511515604087015280935050505092915050565b6020815260006123046020830184613374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6004811061346d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6000815180845260005b818110156134975760208185018101518683018201520161347b565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6134e0828251613436565b6000602082015161012060208501526134fd610120850182613471565b9050604083015161352260408601826fffffffffffffffffffffffffffffffff169052565b50606083015161353e606086018267ffffffffffffffff169052565b50608083015161355a608086018267ffffffffffffffff169052565b5060a083015161357e60a08601826fffffffffffffffffffffffffffffffff169052565b5060c08301516135a260c08601826fffffffffffffffffffffffffffffffff169052565b5060e08301516135c660e08601826fffffffffffffffffffffffffffffffff169052565b506101008301516135ec6101008601826fffffffffffffffffffffffffffffffff169052565b509392505050565b60208152600061230460208301846134d5565b6000806020838503121561361a57600080fd5b823567ffffffffffffffff81111561363157600080fd5b6130a9858286016130f7565b6000806040838503121561365057600080fd5b613659836131c6565b9150613241602084016131c6565b6000602082016020835280845180835260408501915060408160051b86010192506020860160005b828110156136de577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08786030184526136c98583516134d5565b9450602093840193919091019060010161368f565b50929695505050505050565b6000602082016020835280845180835260408501915060408160051b86010192506020860160005b828110156136de577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc087860301845261374c858351613374565b94506020938401939190910190600101613712565b60008060008060008060008060008060a08b8d03121561378057600080fd5b8a3567ffffffffffffffff81111561379757600080fd5b6137a38d828e016130f7565b909b5099505060208b013567ffffffffffffffff8111156137c357600080fd5b6137cf8d828e016130f7565b90995097505060408b013567ffffffffffffffff8111156137ef57600080fd5b6137fb8d828e016130f7565b90975095505060608b013567ffffffffffffffff81111561381b57600080fd5b6138278d828e016130f7565b90955093505060808b013567ffffffffffffffff81111561384757600080fd5b6138538d828e016130f7565b915080935050809150509295989b9194979a5092959850565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006113f160208301848661386c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561390a57600080fd5b612304826131fa565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261394857600080fd5b83018035915067ffffffffffffffff82111561396357600080fd5b60200191503681900382131561306c57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff821663ffffffff81036139c3576139c3613978565b60010192915050565b6000602082840312156139de57600080fd5b8151801515811461230457600080fd5b6fffffffffffffffffffffffffffffffff81811683821601908111156105c5576105c5613978565b818103818111156105c5576105c5613978565b67ffffffffffffffff82811682821603908111156105c5576105c5613978565b600060208284031215613a5b57600080fd5b81356fffffffffffffffffffffffffffffffff8116811461230457600080fd5b8183823760009101908152919050565b6fffffffffffffffffffffffffffffffff82811682821603908111156105c5576105c5613978565b600181811c90821680613ac757607f821691505b602082108103610e37577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b63ffffffff82811682821603908111156105c5576105c5613978565b63ffffffff81811683821601908111156105c5576105c5613978565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215613b7957600080fd5b813567ffffffffffffffff8116811461230457600080fd5b602081526000808354613ba381613ab3565b8060208601526001821660008114613bc25760018114613bfc57613c30565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083166040870152604082151560051b8701019350613c30565b86600052602060002060005b83811015613c2757815488820160400152600190910190602001613c08565b87016040019450505b509195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b601f821115610cc157806000526020600020601f840160051c81016020851015613c915750805b601f840160051c820191505b81811015613cb15760008155600101613c9d565b5050505050565b67ffffffffffffffff831115613cd057613cd0613b38565b613ce483613cde8354613ab3565b83613c6a565b6000601f841160018114613d365760008515613d005750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613cb1565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613d855786850135825560209485019460019092019101613d65565b5086821015613dc0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6fffffffffffffffffffffffffffffffff8616815267ffffffffffffffff8516602082015267ffffffffffffffff84166040820152608060608201526000613e1e60808301848661386c565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220b44ab4d51ac83264ea865cf9cf43651c07a93a3c09902d82a027b4bf8c49e74d64736f6c634300081a0033

Verified Source Code Partial Match

Compiler: v0.8.26+commit.8a97fa7a EVM: paris Optimization: Yes (9999999 runs)
LockerRealTime.sol 1152 lines
pragma solidity ^0.8.20;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev The `account` is missing a role.
     */
    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);

    /**
     * @dev The caller of a function is not the expected one.
     *
     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
     */
    error AccessControlBadConfirmation();

    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     */
    event RoleAdminChanged(
        bytes32 indexed role,
        bytes32 indexed previousAdminRole,
        bytes32 indexed newAdminRole
    );

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(
        bytes32 indexed role,
        address indexed account,
        address indexed sender
    );

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(
        bytes32 indexed role,
        address indexed account,
        address indexed sender
    );

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(
        bytes32 role,
        address account
    ) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `callerConfirmation`.
     */
    function renounceRole(bytes32 role, address callerConfirmation) external;
}

pragma solidity ^0.8.20;

/**
 * @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;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https:
 *
 * 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:
     * 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);
}

pragma solidity ^0.8.20;

/**
 * @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);
 * }
 * ```
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(
        bytes4 interfaceId
    ) public view virtual returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

pragma solidity ^0.8.20;

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```solidity
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```solidity
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
 * to enforce additional security measures for this role.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address account => bool) hasRole;
        bytes32 adminRole;
    }

    mapping(bytes32 role => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with an {AccessControlUnauthorizedAccount} error including the required role.
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(
        bytes4 interfaceId
    ) public view virtual override returns (bool) {
        return
            interfaceId == type(IAccessControl).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(
        bytes32 role,
        address account
    ) public view virtual returns (bool) {
        return _roles[role].hasRole[account];
    }

    /**
     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
     * is missing `role`.
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert AccessControlUnauthorizedAccount(account, role);
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleGranted} event.
     */
    function grantRole(
        bytes32 role,
        address account
    ) public virtual onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleRevoked} event.
     */
    function revokeRole(
        bytes32 role,
        address account
    ) public virtual onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `callerConfirmation`.
     *
     * May emit a {RoleRevoked} event.
     */
    function renounceRole(
        bytes32 role,
        address callerConfirmation
    ) public virtual {
        if (callerConfirmation != _msgSender()) {
            revert AccessControlBadConfirmation();
        }

        _revokeRole(role, callerConfirmation);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleGranted} event.
     */
    function _grantRole(
        bytes32 role,
        address account
    ) internal virtual returns (bool) {
        if (!hasRole(role, account)) {
            _roles[role].hasRole[account] = true;
            emit RoleGranted(role, account, _msgSender());
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(
        bytes32 role,
        address account
    ) internal virtual returns (bool) {
        if (hasRole(role, account)) {
            _roles[role].hasRole[account] = false;
            emit RoleRevoked(role, account, _msgSender());
            return true;
        } else {
            return false;
        }
    }
}

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(
        address owner,
        address spender
    ) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https:
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);
}

interface ILockEpochRealTime {
    event LockEpochCreated(
        uint32 indexed epochId,
        uint128 amount,
        uint64 unlockStartPoint,
        uint64 unlockEndPoint,
        string roleName
    );
    event LockEpochUpdated(
        uint32 indexed epochId,
        uint128 amount,
        uint64 unlockStartPoint,
        uint64 unlockEndPoint,
        string roleName
    );
    event LockEpochReleased(
        uint32 indexed epochId,
        uint128 amount,
        uint64 unlockStartPoint,
        uint64 unlockEndPoint,
        string roleName
    );
    event LockEpochClaimed(
        uint32 indexed epochId,
        uint128 amount,
        uint64 unlockStartPoint,
        uint64 unlockEndPoint,
        string roleName
    );

    event RoleBindReceiverUpdated(
        string indexed roleName,
        address oldReceiver,
        address newReceiver
    );

    event RoleTransferred(
        string indexed roleName,
        address oldReceiver,
        address newReceiver
    );

    /**
     * uint96 timestamp 2**96 = 79228162514264337593543950336 as 79,228,162,514.26434 ether,
     * uint32 epochId
     * uint32 cycles
     * uint128 amount
     * if your token total supply beyond this, don't use it
     */

    function getRoleNameHash(
        string calldata roleName
    ) external pure returns (bytes32 roleHash);

    function getUnlockAmountOf(
        uint32 epochId
    ) external view returns (uint128 unlockAmount);

    function getUnclaimAmountOf(
        uint32 epochId
    ) external view returns (uint128 unclaimAmount);

    function createLockEpochs(
        uint128[] calldata totalLockAmounts,
        uint32[] calldata unlockStartPoints,
        uint32[] calldata unlockEndPoints,
        string[] calldata roleName
    ) external;

    function updateLockEpochs(
        uint32[] calldata epochIds,
        uint128[] calldata newTotalLockAmounts,
        uint64[] calldata newUnlockStartPoints,
        uint64[] calldata newUnlockEndPoints,
        string[] calldata newRoleNames
    ) external;

    function startReleaseLockEpochs(uint32[] calldata epochIds) external;

    function updateRoleBindReceivers(
        address[] calldata roleBindReceivers,
        string[] calldata roleNames
    ) external;

    function confirmRoleBindReceivers(
        address[] calldata roleBindReceivers,
        string[] calldata roleNames
    ) external;

    function transferRole(address to, string calldata roleName) external;

    function claimUnlockedFunds(uint32 epochId) external;

    function getSystemInfo() external view returns (SystemInfo memory sysInfo);

    function getLockEpochInfos(
        uint32 startEpochId,
        uint32 endEpochId
    ) external view returns (LockEpochInfo[] memory leis);

    function getLockEpochInfo(
        uint32 epochId
    ) external view returns (LockEpochInfo memory lei);

    function getRoleInfos(
        string[] calldata roleNames
    ) external view returns (RoleInfo[] memory roleInfos);

    function getRoleInfoByHash(
        bytes32 roleHash
    ) external view returns (RoleInfo memory roleInfo);
}
struct SystemInfo {
    uint128 totalLockedAmount;
    uint128 totalClaimedAmount;
    uint32 totalLockEpoch;
}

struct System {
    uint128 totalLockedAmount;
    uint32 totalLockEpoch;
    uint128 totalClaimedAmount;
    uint32 notUse;
}

struct RoleInfo {
    uint32[] roleBindEpochIds;
    address roleBindReceiver;
    bool confirmBindReceiver;
}

enum LockEpochState {
    notExist,
    notStart,
    releasing,
    finished
}

struct LockEpochInfo {
    LockEpochState les;
    string belongToRoleName;
    uint128 totalLockAmount;
    uint64 unlockStartPoint;
    uint64 unlockEndPoint;
    uint128 claimedAmount;
    uint128 currentUnclaimAmount;
    uint128 currentUnlockAmount;
    uint128 unReleaseAmount;
}

struct LockEpoch {
    uint128 totalLockAmount;
    uint128 claimedAmount;
    uint64 unlockStartPoint;
    uint64 unlockEndPoint;
    uint128 notUse;
    string belongToRoleName;
    LockEpochState les;
}

pragma solidity ^0.8.19;

library Math {
    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = x < y ? x : y;
    }

    function sqrt(uint256 y) internal pure returns (uint256 z) {
        if (y > 3) {
            z = y;
            uint256 x = y / 2 + 1;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
     * denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https:
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            uint256 prod0;
            uint256 prod1;
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            if (prod1 == 0) {
                return prod0 / denominator;
            }

            require(denominator > prod1);

            uint256 remainder;
            assembly {
                remainder := mulmod(x, y, denominator)

                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            uint256 twos = denominator & (~denominator + 1);
            assembly {
                denominator := div(denominator, twos)

                prod0 := div(prod0, twos)

                twos := add(div(sub(0, twos), twos), 1)
            }

            prod0 |= prod1 * twos;

            uint256 inverse = (3 * denominator) ^ 2;

            inverse *= 2 - denominator * inverse;
            inverse *= 2 - denominator * inverse;
            inverse *= 2 - denominator * inverse;
            inverse *= 2 - denominator * inverse;
            inverse *= 2 - denominator * inverse;
            inverse *= 2 - denominator * inverse;

            result = prod0 * inverse;
            return result;
        }
    }
}
// CyberForker @ AOF 2025/01/20
contract LockerRealTime is ILockEpochRealTime, AccessControl {
    IERC20 public immutable lockedToken;
    System sys;
    mapping(uint32 => LockEpoch) epochs;
    mapping(bytes32 => RoleInfo) roleNameHashToRoleInfo;
    bytes32 public constant EPOCH_MANAGER_ROLE = bytes32("EPOCH_MANAGER_ROLE");

    constructor(address lockTokenAddress) {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        lockedToken = IERC20(lockTokenAddress);
    }

    bool private isLocked;
    modifier noReentrancy() {
        require(!isLocked, "Reentrancy is not allowed");
        isLocked = true;
        _;
        isLocked = false;
    }

    /**
     * Preseed Round
     * Seed Round
     * Team
     * Ecosystem
     * Marketing
     * Public Sale
     * Public Sale-KOL
     * Advisors
     * Inital Liquidity
     */

    function getRoleNameHash(
        string calldata roleName
    ) public pure returns (bytes32 roleHash) {
        roleHash = keccak256(abi.encode(roleName));
    }

    function _getRoleNameHash(
        string storage roleName
    ) internal pure returns (bytes32 roleHash) {
        roleHash = keccak256(abi.encode(roleName));
    }

    function getUnlockAmountOf(
        uint32 epochId
    ) public view returns (uint128 unlockAmount) {
        LockEpoch storage _le = epochs[epochId];

        require(
            epochId > 0 && epochId <= sys.totalLockEpoch,
            "LE: Invalid epoch ID"
        );

        if (_le.les < LockEpochState.releasing) return 0;

        if (block.timestamp > _le.unlockStartPoint) {
            uint256 _timePassed = block.timestamp - _le.unlockStartPoint;

            uint256 _totalLockTime = _le.unlockEndPoint - _le.unlockStartPoint;

            if (_timePassed > _totalLockTime) _timePassed = _totalLockTime;

            unlockAmount = uint128(
                Math.mulDiv(_le.totalLockAmount, _timePassed, _totalLockTime)
            );
        }
    }

    function getUnclaimAmountOf(
        uint32 epochId
    ) public view returns (uint128 unclaimAmount) {
        require(
            epochId > 0 && epochId <= sys.totalLockEpoch,
            "LE: Invalid epoch ID"
        );

        uint128 _unlockAmount = getUnlockAmountOf(epochId);
        LockEpoch storage _le = epochs[epochId];

        unclaimAmount = _unlockAmount - _le.claimedAmount;
    }

    function createLockEpochs(
        uint128[] calldata totalLockAmounts,
        uint32[] calldata unlockStartPoints,
        uint32[] calldata unlockEndPoints,
        string[] calldata roleName
    ) external onlyRole(EPOCH_MANAGER_ROLE) noReentrancy {
        require(
            totalLockAmounts.length == unlockStartPoints.length &&
                unlockStartPoints.length == unlockEndPoints.length &&
                unlockEndPoints.length == roleName.length,
            "LE: Unequal length"
        );

        for (uint256 i = 0; i < totalLockAmounts.length; i++) {
            createLockEpoch(
                totalLockAmounts[i],
                unlockStartPoints[i],
                unlockEndPoints[i],
                roleName[i]
            );
        }
    }

    function createLockEpoch(
        uint128 totalLockAmount,
        uint64 unlockStartPoint,
        uint64 unlockEndPoint,
        string calldata roleName
    ) internal {
        uint32 _epochId = ++sys.totalLockEpoch;

        LockEpoch storage _le = epochs[_epochId];

        require(
            lockedToken.transferFrom(
                msg.sender,
                address(this),
                totalLockAmount
            ),
            "LE: Token transfer failed"
        );
        require(unlockStartPoint < unlockEndPoint, "LRT: Time error.");

        _le.totalLockAmount = totalLockAmount;
        _le.unlockStartPoint = unlockStartPoint;
        _le.unlockEndPoint = unlockEndPoint;
        _le.belongToRoleName = roleName;
        _le.les = LockEpochState.notStart;

        bytes32 _belongToRoleHash = getRoleNameHash(roleName);
        roleNameHashToRoleInfo[_belongToRoleHash].roleBindEpochIds.push(
            _epochId
        );

        emit LockEpochCreated(
            _epochId,
            totalLockAmount,
            unlockStartPoint,
            unlockEndPoint,
            roleName
        );
    }

    function updateLockEpochs(
        uint32[] calldata epochIds,
        uint128[] calldata newTotalLockAmounts,
        uint64[] calldata newUnlockStartPoints,
        uint64[] calldata newUnlockEndPoints,
        string[] calldata newRoleNames
    ) external onlyRole(EPOCH_MANAGER_ROLE) noReentrancy {
        require(
            epochIds.length == newTotalLockAmounts.length &&
                newTotalLockAmounts.length == newUnlockStartPoints.length &&
                newUnlockStartPoints.length == newUnlockEndPoints.length &&
                newUnlockEndPoints.length == newRoleNames.length,
            "LE: Unequal length"
        );
        for (uint32 i = 0; i < epochIds.length; i++) {
            updateLockEpoch(
                epochIds[i],
                newTotalLockAmounts[i],
                newUnlockStartPoints[i],
                newUnlockEndPoints[i],
                newRoleNames[i]
            );
        }
    }

    function updateLockEpoch(
        uint32 epochId,
        uint128 newTotalLockAmount,
        uint64 newUnlockStartPoint,
        uint64 newUnlockEndPoint,
        string calldata newRoleName
    ) internal {
        LockEpoch storage _le = epochs[epochId];
        require(_le.les == LockEpochState.notStart, "LE: Already Started");

        if (newTotalLockAmount > _le.totalLockAmount) {
            uint128 amountToTransfer = newTotalLockAmount - _le.totalLockAmount;
            lockedToken.transferFrom(
                msg.sender,
                address(this),
                amountToTransfer
            );
            _le.totalLockAmount = newTotalLockAmount;
        } else if (newTotalLockAmount < _le.totalLockAmount) {
            uint128 amountToRefund = _le.totalLockAmount - newTotalLockAmount;
            lockedToken.transfer(msg.sender, amountToRefund);
            _le.totalLockAmount = newTotalLockAmount;
        }

        require(newUnlockStartPoint < newUnlockEndPoint, "LRT: Time error.");
        _le.unlockStartPoint = newUnlockStartPoint;
        _le.unlockEndPoint = newUnlockEndPoint;

        bytes32 _newBelongToRoleHash = getRoleNameHash(newRoleName);
        bytes32 _currentBelongToRoleHash = _getRoleNameHash(
            _le.belongToRoleName
        );

        if (_newBelongToRoleHash != _currentBelongToRoleHash) {
            RoleInfo storage oldRole = roleNameHashToRoleInfo[
                _currentBelongToRoleHash
            ];

            for (uint i = 0; i < oldRole.roleBindEpochIds.length; i++) {
                if (oldRole.roleBindEpochIds[i] == epochId) {
                    oldRole.roleBindEpochIds[i] = oldRole.roleBindEpochIds[
                        oldRole.roleBindEpochIds.length - 1
                    ];
                    oldRole.roleBindEpochIds.pop();
                    break;
                }
            }

            roleNameHashToRoleInfo[_newBelongToRoleHash].roleBindEpochIds.push(
                epochId
            );
            _le.belongToRoleName = newRoleName;
        }

        emit LockEpochUpdated(
            epochId,
            newTotalLockAmount,
            newUnlockStartPoint,
            newUnlockEndPoint,
            newRoleName
        );
    }

    function startReleaseLockEpochs(
        uint32[] calldata epochIds
    ) external onlyRole(EPOCH_MANAGER_ROLE) noReentrancy {
        for (uint32 i = 0; i < epochIds.length; i++) {
            startReleaseLockEpoch(epochIds[i]);
        }
    }

    function startReleaseLockEpoch(uint32 epochId) internal {
        require(
            epochId > 0 && epochId <= sys.totalLockEpoch,
            "LE: Invalid epoch ID"
        );
        LockEpoch storage _le = epochs[epochId];
        require(_le.les == LockEpochState.notStart, "LE: Already Started");
        _le.les = LockEpochState.releasing;
        sys.totalLockedAmount += _le.totalLockAmount;
    }

    function updateRoleBindReceivers(
        address[] calldata roleBindReceivers,
        string[] calldata roleNames
    ) external onlyRole(EPOCH_MANAGER_ROLE) noReentrancy {
        for (uint32 i = 0; i < roleNames.length; i++) {
            updateRoleBindReceiver(roleBindReceivers[i], roleNames[i]);
        }
    }

    function updateRoleBindReceiver(
        address roleBindReceiver,
        string calldata roleName
    ) internal {
        bytes32 _roleHash = getRoleNameHash(roleName);

        RoleInfo storage _ri = roleNameHashToRoleInfo[_roleHash];

        require(!_ri.confirmBindReceiver, "LE: Receiver address confirmed");

        _ri.roleBindReceiver = roleBindReceiver;

        emit RoleBindReceiverUpdated(
            roleName,
            _ri.roleBindReceiver,
            roleBindReceiver
        );
    }

    function confirmRoleBindReceivers(
        address[] calldata roleBindReceivers,
        string[] calldata roleNames
    ) external onlyRole(EPOCH_MANAGER_ROLE) noReentrancy {
        for (uint32 i = 0; i < roleNames.length; i++) {
            confirmRoleBindReceiver(roleBindReceivers[i], roleNames[i]);
        }
    }

    function confirmRoleBindReceiver(
        address roleBindReceiver,
        string calldata roleName
    ) internal {
        bytes32 _roleHash = getRoleNameHash(roleName);
        RoleInfo storage _ri = roleNameHashToRoleInfo[_roleHash];

        require(
            roleBindReceiver == _ri.roleBindReceiver &&
                roleBindReceiver != address(0),
            "LE: Double check error"
        );
        _ri.confirmBindReceiver = true;
    }

    function transferRole(
        address to,
        string calldata roleName
    ) external noReentrancy {
        bytes32 _roleHash = getRoleNameHash(roleName);
        RoleInfo storage _ri = roleNameHashToRoleInfo[_roleHash];
        require(_ri.roleBindReceiver == msg.sender, "LE: No Auth");
        require(to != address(0), "LE: Invalid receiver address");
        _ri.roleBindReceiver = to;
        emit RoleTransferred(roleName, msg.sender, to);
    }

    function claimUnlockedFunds(uint32 epochId) external noReentrancy {
        require(
            epochId > 0 && epochId <= sys.totalLockEpoch,
            "LE: Invalid epoch ID"
        );

        uint128 _toClaimAmount = getUnclaimAmountOf(epochId);

        require(_toClaimAmount > 0, "LE: No funds to claim");

        LockEpoch storage _le = epochs[epochId];
        require(
            _le.les == LockEpochState.releasing,
            "LE: Not in releasing stage"
        );

        address _receiver = roleNameHashToRoleInfo[
            _getRoleNameHash(_le.belongToRoleName)
        ].roleBindReceiver;

        _le.claimedAmount = getUnlockAmountOf(epochId);

        require(
            lockedToken.transfer(_receiver, _toClaimAmount),
            "LE: Transfer failed"
        );

        if (_le.claimedAmount == _le.totalLockAmount) {
            _le.les = LockEpochState.finished;
        }
        sys.totalClaimedAmount += _toClaimAmount;
    }

    function getSystemInfo() external view returns (SystemInfo memory sysInfo) {
        sysInfo = SystemInfo({
            totalLockedAmount: sys.totalLockedAmount,
            totalClaimedAmount: sys.totalClaimedAmount,
            totalLockEpoch: sys.totalLockEpoch
        });
    }

    function getLockEpochInfos(
        uint32 startEpochId,
        uint32 endEpochId
    ) external view returns (LockEpochInfo[] memory leis) {
        require(startEpochId <= endEpochId, "LE: Invalid epoch ID");
        leis = new LockEpochInfo[](endEpochId - startEpochId + 1);
        for (uint32 i = startEpochId; i <= endEpochId; i++) {
            leis[i - startEpochId] = getLockEpochInfo(i);
        }
    }

    function getLockEpochInfo(
        uint32 epochId
    ) public view returns (LockEpochInfo memory lei) {
        require(
            epochId > 0 && epochId <= sys.totalLockEpoch,
            "LE: Invalid epoch ID"
        );

        LockEpoch storage _le = epochs[epochId];

        uint128 _unlockAmount = getUnlockAmountOf(epochId);

        uint128 _unclaimAmount = getUnclaimAmountOf(epochId);

        uint128 _unReleaseAmount = _le.totalLockAmount - _unlockAmount;

        lei = LockEpochInfo({
            les: _le.les,
            belongToRoleName: _le.belongToRoleName,
            totalLockAmount: _le.totalLockAmount,
            unlockStartPoint: _le.unlockStartPoint,
            unlockEndPoint: _le.unlockEndPoint,
            claimedAmount: _le.claimedAmount,
            currentUnclaimAmount: _unclaimAmount,
            currentUnlockAmount: _unlockAmount,
            unReleaseAmount: _unReleaseAmount
        });
    }

    function getRoleInfos(
        string[] calldata roleNames
    ) external view returns (RoleInfo[] memory roleInfos) {
        roleInfos = new RoleInfo[](roleNames.length);
        for (uint256 i = 0; i < roleNames.length; i++) {
            roleInfos[i] = getRoleInfoByHash(getRoleNameHash(roleNames[i]));
        }
    }

    function getRoleInfoByHash(
        bytes32 roleHash
    ) public view returns (RoleInfo memory roleInfo) {
        roleInfo = roleNameHashToRoleInfo[roleHash];
    }
}
// 0xefD94041Fa3c6b1802d48057Cd6a9B0ee4276a89

Read Contract

DEFAULT_ADMIN_ROLE 0xa217fddf → bytes32
EPOCH_MANAGER_ROLE 0xfc2e05c5 → bytes32
getLockEpochInfo 0xdf38461e → tuple
getLockEpochInfos 0xfb1466f1 → tuple[]
getRoleAdmin 0x248a9ca3 → bytes32
getRoleInfoByHash 0xcc60c413 → tuple
getRoleInfos 0xfb81dff1 → tuple[]
getRoleNameHash 0x01a0704c → bytes32
getSystemInfo 0x6cb69f42 → tuple
getUnclaimAmountOf 0xc84e77cb → uint128
getUnlockAmountOf 0x548e75a9 → uint128
hasRole 0x91d14854 → bool
lockedToken 0x0f45cc81 → address
supportsInterface 0x01ffc9a7 → bool

Write Contract 10 functions

These functions modify contract state and require a wallet transaction to execute.

claimUnlockedFunds 0x2b1ea8c6
uint32 epochId
confirmRoleBindReceivers 0x1bf4026a
address[] roleBindReceivers
string[] roleNames
createLockEpochs 0x990bb9da
uint128[] totalLockAmounts
uint32[] unlockStartPoints
uint32[] unlockEndPoints
string[] roleName
grantRole 0x2f2ff15d
bytes32 role
address account
renounceRole 0x36568abe
bytes32 role
address callerConfirmation
revokeRole 0xd547741f
bytes32 role
address account
startReleaseLockEpochs 0xeec40a39
uint32[] epochIds
transferRole 0xacab5c1c
address to
string roleName
updateLockEpochs 0xff3bf644
uint32[] epochIds
uint128[] newTotalLockAmounts
uint64[] newUnlockStartPoints
uint64[] newUnlockEndPoints
string[] newRoleNames
updateRoleBindReceivers 0xd7d9b08c
address[] roleBindReceivers
string[] roleNames

Recent Transactions

No transactions found for this address