Address Contract Verified
Address
0x924d9492E010856A07cfbd2A6999F69dcEe7D041
Balance
0 ETH
Nonce
1
Code Size
21610 bytes
Creator
0x5A1d8365...B1EA at tx 0x4cb6899a...448120
Indexed Transactions
0
Contract Bytecode
21610 bytes
0x608060405260043610610429575f3560e01c8063728d41c911610228578063abefea031161012d578063ce657cce116100b5578063e25fc5ac11610079578063e25fc5ac14610fba578063f1fffdcb14610fe4578063f2fde38b1461100e578063f3ff43da14611036578063fccc28131461105e5761042a565b8063ce657cce14610ec8578063da0103bd14610ef0578063da4493f614610f18578063dbe66ca014610f42578063dd62ed3e14610f7e5761042a565b8063c16dd4a4116100fc578063c16dd4a414610e0c578063c31c9c0714610e34578063c9567bf914610e5e578063cc1776d314610e74578063ce2a9f6214610e9e5761042a565b8063abefea0314610d56578063ad29ffde14610d7e578063b367f8fe14610da6578063b4b11b9514610dd05761042a565b80638da5cb5b116101b0578063a64e4f8a1161017f578063a64e4f8a14610c76578063a901dd9214610ca0578063a9059cbb14610cc8578063a91a9eb114610d04578063a985ceef14610d2c5761042a565b80638da5cb5b14610bd05780638ea5220f14610bfa57806395d89b4114610c24578063a49a910f14610c4e5761042a565b80637a689da1116101f75780637a689da114610aec5780637b812b4114610b165780637f635cc014610b5257806380faa3d214610b7c5780638124f7ac14610ba65761042a565b8063728d41c914610a48578063757765f814610a7057806375f0a87414610a9857806378c872cd14610ac25761042a565b8063346cc7be1161032e57806351fb012d116102b657806366a88d961161028557806366a88d961461097a57806368b69b9b146109a45780636aa5b37f146109cc57806370a08231146109f6578063715018a614610a325761042a565b806351fb012d146108d4578063538ba4f9146108fe578063652e2f0414610928578063667f6526146109525761042a565b80633f7fc93b116102fd5780633f7fc93b1461080457806340c2af111461082c578063435263ef146108565780634a8c1fb4146108805780634f7041a5146108aa5761042a565b8063346cc7be1461074e5780633582ad231461077657806336884b6e146107a05780633af32abf146107c85761042a565b80631ecd7d6e116103b157806326991cc81161038057806326991cc8146106805780632f6f30ea146106aa5780632f893de7146106d2578063313ce567146106fa578063337a4b20146107245761042a565b80631ecd7d6e146105b457806322d74a61146105de57806323b872dd14610608578063259827e3146106445761042a565b806308252b7c116103f857806308252b7c146104d0578063095ea7b3146104fa578063106a5a8f1461053657806318160ddd1461055e5780631983f599146105885761042a565b806302b6203d1461042c578063052d9e7e1461044257806306c933d81461046a57806306fdde03146104a65761042a565b5b005b348015610437575f5ffd5b50610440611088565b005b34801561044d575f5ffd5b506104686004803603810190610463919061491c565b6111ee565b005b348015610475575f5ffd5b50610490600480360381019061048b91906149a1565b61124a565b60405161049d91906149db565b60405180910390f35b3480156104b1575f5ffd5b506104ba611267565b6040516104c79190614a64565b60405180910390f35b3480156104db575f5ffd5b506104e46112f7565b6040516104f191906149db565b60405180910390f35b348015610505575f5ffd5b50610520600480360381019061051b9190614ab7565b61130d565b60405161052d91906149db565b60405180910390f35b348015610541575f5ffd5b5061055c60048036038101906105579190614b56565b61132f565b005b348015610569575f5ffd5b5061057261138b565b60405161057f9190614bc2565b60405180910390f35b348015610593575f5ffd5b5061059c611394565b6040516105ab93929190614bdb565b60405180910390f35b3480156105bf575f5ffd5b506105c86113ab565b6040516105d59190614bc2565b60405180910390f35b3480156105e9575f5ffd5b506105f26113b1565b6040516105ff9190614bc2565b60405180910390f35b348015610613575f5ffd5b5061062e60048036038101906106299190614c10565b6113b6565b60405161063b91906149db565b60405180910390f35b34801561064f575f5ffd5b5061066a600480360381019061066591906149a1565b6113e4565b60405161067791906149db565b60405180910390f35b34801561068b575f5ffd5b50610694611401565b6040516106a19190614c6f565b60405180910390f35b3480156106b5575f5ffd5b506106d060048036038101906106cb9190614b56565b611425565b005b3480156106dd575f5ffd5b506106f860048036038101906106f39190614b56565b6117a8565b005b348015610705575f5ffd5b5061070e6118ae565b60405161071b9190614ca3565b60405180910390f35b34801561072f575f5ffd5b506107386118b6565b6040516107459190614bc2565b60405180910390f35b348015610759575f5ffd5b50610774600480360381019061076f91906149a1565b6118c3565b005b348015610781575f5ffd5b5061078a611b54565b60405161079791906149db565b60405180910390f35b3480156107ab575f5ffd5b506107c660048036038101906107c19190614cbc565b611b67565b005b3480156107d3575f5ffd5b506107ee60048036038101906107e991906149a1565b611c0c565b6040516107fb91906149db565b60405180910390f35b34801561080f575f5ffd5b5061082a60048036038101906108259190614ce7565b611c5e565b005b348015610837575f5ffd5b50610840611d00565b60405161084d9190614bc2565b60405180910390f35b348015610861575f5ffd5b5061086a611d05565b6040516108779190614c6f565b60405180910390f35b34801561088b575f5ffd5b50610894611d2a565b6040516108a191906149db565b60405180910390f35b3480156108b5575f5ffd5b506108be611d3d565b6040516108cb9190614bc2565b60405180910390f35b3480156108df575f5ffd5b506108e8611d43565b6040516108f591906149db565b60405180910390f35b348015610909575f5ffd5b50610912611d56565b60405161091f9190614c6f565b60405180910390f35b348015610933575f5ffd5b5061093c611d5a565b6040516109499190614bc2565b60405180910390f35b34801561095d575f5ffd5b5061097860048036038101906109739190614d37565b611d60565b005b348015610985575f5ffd5b5061098e611e37565b60405161099b9190614bc2565b60405180910390f35b3480156109af575f5ffd5b506109ca60048036038101906109c5919061491c565b611e3d565b005b3480156109d7575f5ffd5b506109e0611e99565b6040516109ed9190614bc2565b60405180910390f35b348015610a01575f5ffd5b50610a1c6004803603810190610a1791906149a1565b611e9f565b604051610a299190614bc2565b60405180910390f35b348015610a3d575f5ffd5b50610a46611ee5565b005b348015610a53575f5ffd5b50610a6e6004803603810190610a699190614cbc565b611ef8565b005b348015610a7b575f5ffd5b50610a966004803603810190610a919190614cbc565b611f9d565b005b348015610aa3575f5ffd5b50610aac612042565b604051610ab99190614c6f565b60405180910390f35b348015610acd575f5ffd5b50610ad6612067565b604051610ae39190614bc2565b60405180910390f35b348015610af7575f5ffd5b50610b0061206c565b604051610b0d9190614bc2565b60405180910390f35b348015610b21575f5ffd5b50610b3c6004803603810190610b3791906149a1565b612071565b604051610b4991906149db565b60405180910390f35b348015610b5d575f5ffd5b50610b6661208e565b604051610b739190614bc2565b60405180910390f35b348015610b87575f5ffd5b50610b90612093565b604051610b9d9190614bc2565b60405180910390f35b348015610bb1575f5ffd5b50610bba612099565b604051610bc79190614bc2565b60405180910390f35b348015610bdb575f5ffd5b50610be461209f565b604051610bf19190614c6f565b60405180910390f35b348015610c05575f5ffd5b50610c0e6120c6565b604051610c1b9190614c6f565b60405180910390f35b348015610c2f575f5ffd5b50610c386120eb565b604051610c459190614a64565b60405180910390f35b348015610c59575f5ffd5b50610c746004803603810190610c6f9190614cbc565b61217b565b005b348015610c81575f5ffd5b50610c8a612280565b604051610c9791906149db565b60405180910390f35b348015610cab575f5ffd5b50610cc66004803603810190610cc1919061491c565b612293565b005b348015610cd3575f5ffd5b50610cee6004803603810190610ce99190614ab7565b6122ef565b604051610cfb91906149db565b60405180910390f35b348015610d0f575f5ffd5b50610d2a6004803603810190610d2591906149a1565b612311565b005b348015610d37575f5ffd5b50610d40612441565b604051610d4d91906149db565b60405180910390f35b348015610d61575f5ffd5b50610d7c6004803603810190610d7791906149a1565b612454565b005b348015610d89575f5ffd5b50610da46004803603810190610d9f9190614b56565b612584565b005b348015610db1575f5ffd5b50610dba6125e0565b604051610dc791906149db565b60405180910390f35b348015610ddb575f5ffd5b50610df66004803603810190610df191906149a1565b6125f3565b604051610e0391906149db565b60405180910390f35b348015610e17575f5ffd5b50610e326004803603810190610e2d9190614d75565b612610565b005b348015610e3f575f5ffd5b50610e486126a7565b604051610e559190614e0e565b60405180910390f35b348015610e69575f5ffd5b50610e726126cb565b005b348015610e7f575f5ffd5b50610e88612771565b604051610e959190614bc2565b60405180910390f35b348015610ea9575f5ffd5b50610eb2612777565b604051610ebf9190614bc2565b60405180910390f35b348015610ed3575f5ffd5b50610eee6004803603810190610ee9919061491c565b61277d565b005b348015610efb575f5ffd5b50610f166004803603810190610f119190614cbc565b6127d9565b005b348015610f23575f5ffd5b50610f2c6128ad565b604051610f399190614bc2565b60405180910390f35b348015610f4d575f5ffd5b50610f686004803603810190610f6391906149a1565b6128b3565b604051610f7591906149db565b60405180910390f35b348015610f89575f5ffd5b50610fa46004803603810190610f9f9190614e27565b6128d0565b604051610fb19190614bc2565b60405180910390f35b348015610fc5575f5ffd5b50610fce612952565b604051610fdb9190614bc2565b60405180910390f35b348015610fef575f5ffd5b50610ff8612957565b6040516110059190614c6f565b60405180910390f35b348015611019575f5ffd5b50611034600480360381019061102f91906149a1565b61297c565b005b348015611041575f5ffd5b5061105c600480360381019061105791906149a1565b612a00565b005b348015611069575f5ffd5b50611072612ab9565b60405161107f9190614c6f565b60405180910390f35b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461110e576040517f23a7681d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600860149054906101000a900460ff1615611155576040517f38fd0e0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60105490505f60115490505f60125490505f6010819055505f6011819055505f6012819055506001600860146101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff167f9068db52b62cee7a97eb501bc0cb643bdc5bd5645f5dfc1e5dbf0986251c2c3d8484846040516111e193929190614bdb565b60405180910390a2505050565b6111f6612abf565b806008601a6101000a81548160ff0219169083151502179055507f1cf28b997975c7be355bcef74f2f5019aa48253bc1e54b3c8b002471865fdba88160405161123f91906149db565b60405180910390a150565b6017602052805f5260405f205f915054906101000a900460ff1681565b60606004805461127690614e92565b80601f01602080910402602001604051908101604052809291908181526020018280546112a290614e92565b80156112ed5780601f106112c4576101008083540402835291602001916112ed565b820191905f5260205f20905b8154815290600101906020018083116112d057829003601f168201915b5050505050905090565b5f600860149054906101000a900460ff16905090565b5f5f611317612b46565b9050611324818585612b4d565b600191505092915050565b611337612abf565b5f5f90505b838390508110156113855761137884848381811061135d5761135c614ec2565b5b905060200201602081019061137291906149a1565b83612b5f565b808060010191505061133c565b50505050565b5f600354905090565b6019805f0154908060010154908060020154905083565b600f5481565b601381565b5f5f6113c0612b46565b90506113cd858285612bf0565b6113d8858585612c82565b60019150509392505050565b6013602052805f5260405f205f915054906101000a900460ff1681565b7f00000000000000000000000068b9f6894dbb2b3316a904e629dcf7aa95b8fb4c81565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114ab576040517f23a7681d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f90505b838390508110156117a25760165f8585848181106114d1576114d0614ec2565b5b90506020020160208101906114e691906149a1565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff161580156115ac57507f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff1684848381811061157e5761157d614ec2565b5b905060200201602081019061159391906149a1565b73ffffffffffffffffffffffffffffffffffffffff1614155b801561160b57503073ffffffffffffffffffffffffffffffffffffffff168484838181106115dd576115dc614ec2565b5b90506020020160208101906115f291906149a1565b73ffffffffffffffffffffffffffffffffffffffff1614155b801561166a57505f73ffffffffffffffffffffffffffffffffffffffff1684848381811061163c5761163b614ec2565b5b905060200201602081019061165191906149a1565b73ffffffffffffffffffffffffffffffffffffffff1614155b801561175e575060145f85858481811061168757611686614ec2565b5b905060200201602081019061169c91906149a1565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1615801561175d575060155f858584818110611700576116ff614ec2565b5b905060200201602081019061171591906149a1565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b5b156117955761179484848381811061177957611778614ec2565b5b905060200201602081019061178e91906149a1565b83612d72565b5b80806001019150506114b0565b50505050565b6117b0612abf565b5f5f90505b838390508110156118a8578160175f8686858181106117d7576117d6614ec2565b5b90506020020160208101906117ec91906149a1565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055507fc03feb136ee85ef1974671b8c663f063c37bc61afb187b94ddfb1a959d73d18084848381811061186f5761186e614ec2565b5b905060200201602081019061188491906149a1565b83604051611893929190614eef565b60405180910390a180806001019150506117b5565b50505050565b5f6012905090565b6802df85d331a7b4000081565b6118cb612abf565b5f3390505f5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036119e6575f4791505f8211611940576040517fcff858f900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168260405161196490614f43565b5f6040518083038185875af1925050503d805f811461199e576040519150601f19603f3d011682016040523d82523d5f602084013e6119a3565b606091505b505080915050806119e0576040517f81102ece00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611b16565b8273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611a1f9190614c6f565b602060405180830381865afa158015611a3a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a5e9190614f6b565b90505f8111611a99576040517ffba5154e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401611ad4929190614f96565b6020604051808303815f875af1158015611af0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b149190614fd1565b505b7f7aba7eca7d870d5f2f93298379a43957082ef15cdcf64db1f7c731c6b3a2fa498382604051611b47929190614f96565b60405180910390a1505050565b600860159054906101000a900460ff1681565b611b6f612abf565b6103e86002611b7c61138b565b611b869190615029565b611b909190615097565b811015611bc9576040517fc2f5625a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600d819055507f1f41d239159181ddefb13e99853e0e4998e0556aa1f2281281c783e309281062600d54604051611c019190614bc2565b60405180910390a150565b5f60175f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff169050919050565b611c66612abf565b6064818385611c7591906150c7565b611c7f91906150c7565b14611cbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb690615144565b60405180910390fd5b60405180606001604052808481526020018381526020018281525060195f820151815f01556020820151816001015560408201518160020155905050505050565b601e81565b601c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600860199054906101000a900460ff1681565b60105481565b6008601a9054906101000a900460ff1681565b5f81565b600d5481565b611d68612abf565b600860149054906101000a900460ff1615611daf576040517f38fd0e0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6028821115611dea576040517fcd4e616700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6028811115611e25576040517fcd4e616700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81601081905550806011819055505050565b600e5481565b611e45612abf565b80600860166101000a81548160ff0219169083151502179055507f6a53d6c83a7a55d7a07bd490493fceb559161cce588908714e497e54044777d981604051611e8e91906149db565b60405180910390a150565b600c5481565b5f60015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b611eed612abf565b611ef65f612e03565b565b611f00612abf565b6103e86003611f0d61138b565b611f179190615029565b611f219190615097565b811015611f5a576040517fc2f5625a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600e819055507fe2e6151ed0b472c61401059745339ca42474813911b22d24023385def6377e1c600e54604051611f929190614bc2565b60405180910390a150565b611fa5612abf565b6103e86002611fb261138b565b611fbc9190615029565b611fc69190615097565b811015611fff576040517fc2f5625a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600c819055507f85668e92bc538f5c140067d68e3375c65b9e4545d2822ec8d807c6782f747d62600c546040516120379190614bc2565b60405180910390a150565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600a81565b601e81565b6015602052805f5260405f205f915054906101000a900460ff1681565b602881565b60095481565b60125481565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600580546120fa90614e92565b80601f016020809104026020016040519081016040528092919081815260200182805461212690614e92565b80156121715780601f1061214857610100808354040283529160200191612171565b820191905f5260205f20905b81548152906001019060200180831161215457829003601f168201915b5050505050905090565b612183612abf565b5f61218c61138b565b9050620f424060018261219f9190615029565b6121a99190615097565b8210156121e2576040517fc2f5625a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e86005826121f29190615029565b6121fc9190615097565b821115612235576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f600f54905082600f819055507f65a8c7442ea496b0a28890f1ef48a9819d1f5d747e9a8df155fe862dfd493c958382604051612273929190615162565b60405180910390a1505050565b600860179054906101000a900460ff1681565b61229b612abf565b80600860176101000a81548160ff0219169083151502179055507fa6a3dda702515d3130fef8b72d8e25f9aebd0d02e89d10d63c0c31d80b52f4a0816040516122e491906149db565b60405180910390a150565b5f5f6122f9612b46565b9050612306818585612c82565b600191505092915050565b612319612abf565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361237e576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fb3dd4b0ccf73b51db7cb2a59fb88d1082b0fa9389d4ce0e85100fe3b26af78c460065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682604051612435929190615189565b60405180910390a15050565b600860169054906101000a900460ff1681565b61245c612abf565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036124c1576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f0db17895a9d092fb3ca24d626f2150dd80c185b0706b36f1040ee239f56cb87160075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682604051612578929190615189565b60405180910390a15050565b61258c612abf565b5f5f90505b838390508110156125da576125cd8484838181106125b2576125b1614ec2565b5b90506020020160208101906125c791906149a1565b83612e79565b8080600101915050612591565b50505050565b600860149054906101000a900460ff1681565b6016602052805f5260405f205f915054906101000a900460ff1681565b612618612abf565b60165f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1615612699576040517f027106be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6126a38282612f0a565b5050565b7f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d81565b6126d3612abf565b600860199054906101000a900460ff161561271a576040517fef65161f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600860196101000a81548160ff0219169083151502179055504360098190555042600a819055507f6603428d483ce13b6662b7a6848d769996e12e801bed4b0f1b9e8d10f64d38ba60405160405180910390a1565b60115481565b601d5481565b612785612abf565b80600860156101000a81548160ff0219169083151502179055507f1da197dc3cab4eceaefd5d0c34df2ed3a08f20a207fb1910c0eceb361e2c965c816040516127ce91906149db565b60405180910390a150565b6127e1612abf565b600860149054906101000a900460ff1615612828576040517f38fd0e0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6028811115612863576040517fcd4e616700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6012549050816012819055507f6a7b998a4adc393cb692c67fcd563e7971e2ea6f3fe7c9b8fb6dd53cf5b627d082826040516128a1929190615162565b60405180910390a15050565b600a5481565b6014602052805f5260405f205f915054906101000a900460ff1681565b5f60025f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b608f81565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b612984612abf565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036129f4575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016129eb9190614c6f565b60405180910390fd5b6129fd81612e03565b50565b612a08612abf565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612a76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a6d906151fa565b60405180910390fd5b80601c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61dead81565b612ac7612b46565b73ffffffffffffffffffffffffffffffffffffffff16612ae561209f565b73ffffffffffffffffffffffffffffffffffffffff1614612b4457612b08612b46565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612b3b9190614c6f565b60405180910390fd5b565b5f33905090565b612b5a8383836001612f9b565b505050565b8060155f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055507f74392251b09500cc108c71712e5e7e0392be9075a74a24f1494551cfa8e068708282604051612be4929190614eef565b60405180910390a15050565b5f612bfb84846128d0565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612c7c5781811015612c6d578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401612c6493929190615218565b60405180910390fd5b612c7b84848484035f612f9b565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612cf2575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401612ce99190614c6f565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612d62575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401612d599190614c6f565b60405180910390fd5b612d6d83838361316a565b505050565b8060135f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055507f066e0c23b9ae0bb92a88e9b0985bb7d85fce062730057312b99a9e243fde5ee18282604051612df7929190614eef565b60405180910390a15050565b5f612e0c61209f565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612e5657612e4b815f612e79565b612e55815f612b5f565b5b612e61826001612e79565b612e6c826001612b5f565b612e758261412e565b5050565b8060145f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055507f3499bfcf9673677ba552f3fe2ea274ec7e6246da31c3c87e115b45a9b0db2efb8282604051612efe929190614eef565b60405180910390a15050565b8060165f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055507f024f6c8d60a57c94822c46d989fd6935057590269281b07fe8327d7e9bc424218282604051612f8f929190614eef565b60405180910390a15050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361300b575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016130029190614c6f565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361307b575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016130729190614c6f565b60405180910390fd5b8160025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015613164578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161315b9190614bc2565b60405180910390a35b50505050565b5f3390505f32905060135f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16156131f3576040517fd18781b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480613274575060135f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b6132aa576040517fd18781b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061330f57508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b80613361575060135f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b613397576040517fd18781b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600860199054906101000a900460ff16806133f8575060155f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b80613449575060155f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b61347f576040517f037c597f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600860199054906101000a900460ff1680156134a757506008601a9054906101000a900460ff165b156135ea575f600954436134bb919061524d565b90505f81036135e85760165f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff168015613561575060155f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b156135e75760175f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff166135e6576040517f584a793800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b505b5f600860159054906101000a900460ff1680156136145750600860189054906101000a900460ff16155b80156136b8575060155f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16806136b6575060155f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b155b90508015613d33576136c861209f565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614158015613736575061370661209f565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b801561376e57505f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b80156137a8575061dead73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b15613d3257600860169054906101000a900460ff16156139cb577f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415801561386a57507f00000000000000000000000068b9f6894dbb2b3316a904e629dcf7aa95b8fb4c73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b156139ca5760034361387c919061524d565b60185f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410801561390f57506003436138cf919061524d565b60185f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054105b613945576040517f53444d9e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4360185f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055504360185f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055505b5b5f600860199054906101000a900460ff1615613a7d575f600954436139f0919061524d565b90505f8103613a2157612710608f613a0661138b565b613a109190615029565b613a1a9190615097565b9150613a77565b60328111613a5157612710601e613a3661138b565b613a409190615029565b613a4a9190615097565b9150613a76565b613a5961138b565b91505f600860156101000a81548160ff0219169083151502179055505b5b50613a83565b600c5490505b60165f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff168015613b20575060155f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b15613bb15780851115613b5f576040517f89be121e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80613b6987611e9f565b86613b7491906150c7565b1115613bac576040517f76c7c05200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d30565b60165f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff168015613c4e575060155f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b15613c925780851115613c8d576040517fa8e28e1000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2f565b60155f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16613d2e5780613cea87611e9f565b86613cf591906150c7565b1115613d2d576040517f76c7c05200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b5b505b5b5f600860179054906101000a900460ff168015613d5d5750600860189054906101000a900460ff16155b8015613e01575060145f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1680613dff575060145f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b155b90508015614078575f5f90505f5f600860199054906101000a900460ff1615613e86575f60095443613e33919061524d565b90505f8103613e4957601e9150601e9250613e80565b60328111613e5e576013915060139250613e7f565b604b8111613e7357600a9150600a9250613e7e565b601054915060115492505b5b5b50613e91565b601054905060115491505b60165f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff168015613ee657505f82115b15613f0a5760648289613ef99190615029565b613f039190615097565b9250614052565b60165f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff168015613f5f57505f81115b15613f835760648189613f729190615029565b613f7c9190615097565b9250614051565b60165f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16158015614021575060165f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b801561402e57505f601254115b15614050576064601254896140439190615029565b61404d9190615097565b92505b5b5b5f831115614074578288614066919061524d565b97506140738a30856141ef565b5b5050505b5f61408230611e9f565b90505f600f5482101590508280156140e1575060165f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b80156140ea5750805b1561411857600b5443118015614101575060095443115b156141175761410f8261440b565b43600b819055505b5b6141238989896141ef565b505050505050505050565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361423f578060035f82825461423391906150c7565b9250508190555061430f565b5f60015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050818110156142c9578381836040517fe450d38c0000000000000000000000000000000000000000000000000000000081526004016142c093929190615218565b60405180910390fd5b81810360015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603614356578060035f82825403925050819055506143a1565b8060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516143fe9190614bc2565b60405180910390a3505050565b6001600860186101000a81548160ff0219169083151502179055505f5f600267ffffffffffffffff81111561444357614442615280565b5b6040519080825280602002602001820160405280156144715781602001602082028036833780820191505090505b50905030815f8151811061448857614487614ec2565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250507f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561452b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061454f91906152c1565b8160018151811061456357614562614ec2565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505f6014600f546145ad9190615029565b9050808411156145bb578093505b7f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff1663791ac947855f8530426040518663ffffffff1660e01b815260040161461c9594939291906153dc565b5f604051808303815f87803b158015614633575f5ffd5b505af1158015614645573d5f5f3e3d5ffd5b505050505f47905080601d5f82825461465e91906150c7565b925050819055505f60196040518060600160405290815f82015481526020016001820154815260200160028201548152505090506802df85d331a7b40000601d5410156146c5576040518060600160405280603c8152602001602881526020015f81525090505b5f6064825f0151846146d79190615029565b6146e19190615097565b90505f60648360200151856146f69190615029565b6147009190615097565b90505f818386614710919061524d565b61471a919061524d565b905060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168360405161476190614f43565b5f6040518083038185875af1925050503d805f811461479b576040519150601f19603f3d011682016040523d82523d5f602084013e6147a0565b606091505b50508098505060075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16826040516147eb90614f43565b5f6040518083038185875af1925050503d805f8114614825576040519150601f19603f3d011682016040523d82523d5f602084013e61482a565b606091505b505080985050601c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168160405161487590614f43565b5f6040518083038185875af1925050503d805f81146148af576040519150601f19603f3d011682016040523d82523d5f602084013e6148b4565b606091505b50508098505050505050505050505f600860186101000a81548160ff02191690831515021790555050565b5f5ffd5b5f5ffd5b5f8115159050919050565b6148fb816148e7565b8114614905575f5ffd5b50565b5f81359050614916816148f2565b92915050565b5f60208284031215614931576149306148df565b5b5f61493e84828501614908565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61497082614947565b9050919050565b61498081614966565b811461498a575f5ffd5b50565b5f8135905061499b81614977565b92915050565b5f602082840312156149b6576149b56148df565b5b5f6149c38482850161498d565b91505092915050565b6149d5816148e7565b82525050565b5f6020820190506149ee5f8301846149cc565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f614a36826149f4565b614a4081856149fe565b9350614a50818560208601614a0e565b614a5981614a1c565b840191505092915050565b5f6020820190508181035f830152614a7c8184614a2c565b905092915050565b5f819050919050565b614a9681614a84565b8114614aa0575f5ffd5b50565b5f81359050614ab181614a8d565b92915050565b5f5f60408385031215614acd57614acc6148df565b5b5f614ada8582860161498d565b9250506020614aeb85828601614aa3565b9150509250929050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f840112614b1657614b15614af5565b5b8235905067ffffffffffffffff811115614b3357614b32614af9565b5b602083019150836020820283011115614b4f57614b4e614afd565b5b9250929050565b5f5f5f60408486031215614b6d57614b6c6148df565b5b5f84013567ffffffffffffffff811115614b8a57614b896148e3565b5b614b9686828701614b01565b93509350506020614ba986828701614908565b9150509250925092565b614bbc81614a84565b82525050565b5f602082019050614bd55f830184614bb3565b92915050565b5f606082019050614bee5f830186614bb3565b614bfb6020830185614bb3565b614c086040830184614bb3565b949350505050565b5f5f5f60608486031215614c2757614c266148df565b5b5f614c348682870161498d565b9350506020614c458682870161498d565b9250506040614c5686828701614aa3565b9150509250925092565b614c6981614966565b82525050565b5f602082019050614c825f830184614c60565b92915050565b5f60ff82169050919050565b614c9d81614c88565b82525050565b5f602082019050614cb65f830184614c94565b92915050565b5f60208284031215614cd157614cd06148df565b5b5f614cde84828501614aa3565b91505092915050565b5f5f5f60608486031215614cfe57614cfd6148df565b5b5f614d0b86828701614aa3565b9350506020614d1c86828701614aa3565b9250506040614d2d86828701614aa3565b9150509250925092565b5f5f60408385031215614d4d57614d4c6148df565b5b5f614d5a85828601614aa3565b9250506020614d6b85828601614aa3565b9150509250929050565b5f5f60408385031215614d8b57614d8a6148df565b5b5f614d988582860161498d565b9250506020614da985828601614908565b9150509250929050565b5f819050919050565b5f614dd6614dd1614dcc84614947565b614db3565b614947565b9050919050565b5f614de782614dbc565b9050919050565b5f614df882614ddd565b9050919050565b614e0881614dee565b82525050565b5f602082019050614e215f830184614dff565b92915050565b5f5f60408385031215614e3d57614e3c6148df565b5b5f614e4a8582860161498d565b9250506020614e5b8582860161498d565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680614ea957607f821691505b602082108103614ebc57614ebb614e65565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f604082019050614f025f830185614c60565b614f0f60208301846149cc565b9392505050565b5f81905092915050565b50565b5f614f2e5f83614f16565b9150614f3982614f20565b5f82019050919050565b5f614f4d82614f23565b9150819050919050565b5f81519050614f6581614a8d565b92915050565b5f60208284031215614f8057614f7f6148df565b5b5f614f8d84828501614f57565b91505092915050565b5f604082019050614fa95f830185614c60565b614fb66020830184614bb3565b9392505050565b5f81519050614fcb816148f2565b92915050565b5f60208284031215614fe657614fe56148df565b5b5f614ff384828501614fbd565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61503382614a84565b915061503e83614a84565b925082820261504c81614a84565b9150828204841483151761506357615062614ffc565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6150a182614a84565b91506150ac83614a84565b9250826150bc576150bb61506a565b5b828204905092915050565b5f6150d182614a84565b91506150dc83614a84565b92508282019050808211156150f4576150f3614ffc565b5b92915050565b7f53706c6974206d7573742073756d20746f2031303000000000000000000000005f82015250565b5f61512e6015836149fe565b9150615139826150fa565b602082019050919050565b5f6020820190508181035f83015261515b81615122565b9050919050565b5f6040820190506151755f830185614bb3565b6151826020830184614bb3565b9392505050565b5f60408201905061519c5f830185614c60565b6151a96020830184614c60565b9392505050565b7f5a65726f206164647265737300000000000000000000000000000000000000005f82015250565b5f6151e4600c836149fe565b91506151ef826151b0565b602082019050919050565b5f6020820190508181035f830152615211816151d8565b9050919050565b5f60608201905061522b5f830186614c60565b6152386020830185614bb3565b6152456040830184614bb3565b949350505050565b5f61525782614a84565b915061526283614a84565b925082820390508181111561527a57615279614ffc565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f815190506152bb81614977565b92915050565b5f602082840312156152d6576152d56148df565b5b5f6152e3848285016152ad565b91505092915050565b5f819050919050565b5f61530f61530a615305846152ec565b614db3565b614a84565b9050919050565b61531f816152f5565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61535781614966565b82525050565b5f615368838361534e565b60208301905092915050565b5f602082019050919050565b5f61538a82615325565b615394818561532f565b935061539f8361533f565b805f5b838110156153cf5781516153b6888261535d565b97506153c183615374565b9250506001810190506153a2565b5085935050505092915050565b5f60a0820190506153ef5f830188614bb3565b6153fc6020830187615316565b818103604083015261540e8186615380565b905061541d6060830185614c60565b61542a6080830184614bb3565b969550505050505056fea26469706673582212205c22c22b4f2a4b870d7a1dba3dec15966f14f33f5cf550b1c61496d8cc896ab564736f6c634300081c0033
Verified Source Code Full Match
Compiler: v0.8.28+commit.7893614a
EVM: cancun
Optimization: No
Luntra.sol 1357 lines
/*
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Telegram: https://t.me/luntrainfra
X: https://x.com/luntrainfra
Documents : https://luntra.gitbook.io/luntra-infrastructure/
Website: https://www.luntrainfrastructure.com/#about
*/
pragma solidity 0.8.28;
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
/**
* @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://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* 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);
}
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)
/**
* @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;
}
}
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
/**
* @dev Standard ERC20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(
address sender,
uint256 balance,
uint256 needed
);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender's `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(
address spender,
uint256 allowance,
uint256 needed
);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator's approval`. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(
address sender,
uint256 balance,
uint256 needed,
uint256 tokenId
);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator's approval`. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(
address owner,
address spender
) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(
address spender,
uint256 value
) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
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;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
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);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
_totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
* ```
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
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);
}
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
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);
}
}
}
}
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
interface IUniswapV2Factory {
function createPair(
address tokenA,
address tokenB
) external returns (address pair);
}
interface IUniswapV2Router {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
}
pragma solidity ^0.8.0;
contract LUNTRA is Ownable, ERC20 {
IUniswapV2Router public immutable swapRouter;
address public constant ZERO_ADDRESS = address(0);
address public constant BURN_ADDRESS = address(0xdEaD);
address public immutable swapPair;
address public marketingWallet;
address public devWallet;
address public originalOwner;
bool public taxesRevoked;
bool public limitsEnabled;
bool public cooldownEnabled;
bool public feesEnabled;
bool private inSwapProcess;
bool public isActivated;
bool public whitelistEnabled;
uint256 public activationBlock;
uint256 public activationTime;
uint256 private lastSwapBlock;
uint256 public constant MAX_TOTAL_FEE = 40;
// Updated dynamic tax and limit constants for custom launch mechanics
uint256 public constant BLOCK_0_TAX = 30; // 30% on buys for bundle block
uint256 public constant BLOCK_0_WALLET_LIMIT = 143; // 1.43% max wallet for bundle block
uint256 public constant BLOCKS_1_50_TAX = 19; // 19% tax for blocks 1-50
uint256 public constant BLOCKS_1_50_WALLET_LIMIT = 30; // 0.3% max wallet for blocks 1-50
uint256 public constant BLOCKS_50_75_TAX = 10; // 10% tax for blocks 50-75
uint256 public maxBuyLimit;
uint256 public maxSellLimit;
uint256 public maxWalletLimit;
uint256 public tokensForSwap;
uint256 public buyTax;
uint256 public sellTax;
uint256 public transferTax;
mapping(address => bool) public blacklistedBots;
mapping(address => bool) public excludedFromFees;
mapping(address => bool) public excludedFromLimits;
mapping(address => bool) public marketPairs;
mapping(address => bool) public whitelistedAddresses;
mapping(address => uint256) private _lastTransferBlock;
event Activation();
event taxWalletUpdated(address newWallet, address oldWallet);
event DevWalletUpdated(address newWallet, address oldWallet);
event LimitsStatusChanged(bool status);
event CooldownStatusChanged(bool status);
event FeesStatusChanged(bool status);
event WhitelistStatusChanged(bool status);
event MaxBuyLimitUpdated(uint256 amount);
event MaxSellLimitUpdated(uint256 amount);
event MaxWalletLimitUpdated(uint256 amount);
event TokensForSwapUpdated(uint256 newValue, uint256 oldValue);
event BuyTaxUpdated(uint256 newValue, uint256 oldValue);
event SellTaxUpdated(uint256 newValue, uint256 oldValue);
event TransferTaxUpdated(uint256 newValue, uint256 oldValue);
event ExcludedFromFees(address account, bool isExcluded);
event ExcludedFromLimits(address account, bool isExcluded);
event BotStatusUpdated(address account, bool isBlacklisted);
event MarketPairStatusUpdated(address pair, bool value);
event WhitelistAddressUpdated(address account, bool isWhitelisted);
event StuckTokensWithdrawn(address token, uint256 amount);
event TaxesRevoked(
address indexed caller,
uint256 previousBuyTax,
uint256 previousSellTax,
uint256 previousTransferTax
);
error AlreadyActivated();
error InvalidAddress();
error AmountTooSmall();
error AmountTooLarge();
error FeeTooHigh();
error PairAlreadySet();
error NoETHToWithdraw();
error NoTokensToWithdraw();
error ETHWithdrawalFailed();
error BotActivityDetected();
error TransferCooldown();
error ExceedsMaxBuyLimit();
error ExceedsMaxSellLimit();
error ExceedsMaxWalletLimit();
error NotActivated();
error NotOriginalOwner();
error TaxesAlreadyRevoked();
error TaxSplitAlreadyRevoked();
error NotWhitelisted();
modifier lockSwapProcess() {
inSwapProcess = true;
_;
inSwapProcess = false;
}
modifier onlyOriginalOwner() {
require(msg.sender == originalOwner, NotOriginalOwner());
_;
}
struct TaxSplit {
uint256 marketing;
uint256 dev;
uint256 ecosystem;
}
TaxSplit public taxSplit;
address public ecosystemWallet;
uint256 public totalEthCollected;
uint256 public constant ETH_SPLIT_THRESHOLD = 53 ether;
constructor() Ownable(msg.sender) ERC20("LUNTRA", "LUNTRA") {
address owner = msg.sender;
originalOwner = owner;
_mint(owner, 1_000_000_000 ether);
uint256 totalSupplyTokens = totalSupply();
marketingWallet = 0xdd6930E5164a9429C32bae29124Ea6C8c0689fC3; // Marketing wallet
devWallet = 0x138bd6ddf39d237F2Ab7220317d7b28A5D38d268; // Dev wallet
ecosystemWallet = 0x76361a7A9dFEcfE36F04Cf8bb3A897330D0c056e;
maxBuyLimit = (totalSupplyTokens * 143) / 10000;
maxSellLimit = (totalSupplyTokens * 143) / 10000;
maxWalletLimit = (totalSupplyTokens * 143) / 10000;
tokensForSwap = (totalSupplyTokens * 200) / 1000000; // 0.02% to make maxSwapAmount 0.4%
limitsEnabled = true;
cooldownEnabled = false;
feesEnabled = true;
whitelistEnabled = true; // Enable whitelist for bundle block
buyTax = 4; // Default tax after block 75
sellTax = 4; // Default tax after block 75
transferTax = 0;
swapRouter = IUniswapV2Router(
0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
);
swapPair = IUniswapV2Factory(swapRouter.factory()).createPair(
address(this),
swapRouter.WETH()
);
SetMarketPair(swapPair, true);
_approve(address(this), address(swapRouter), type(uint256).max);
_excludeFromFees(address(this), true);
_excludeFromFees(BURN_ADDRESS, true);
_excludeFromFees(owner, true);
_excludeFromFees(marketingWallet, true);
_excludeFromFees(devWallet, true);
ExcludeFromLimits(address(this), true);
ExcludeFromLimits(BURN_ADDRESS, true);
ExcludeFromLimits(owner, true);
ExcludeFromLimits(marketingWallet, true);
ExcludeFromLimits(devWallet, true);
taxSplit = TaxSplit(51, 34, 15);
}
receive() external payable {}
fallback() external payable {}
function _transferOwnership(address newOwner) internal override {
address oldOwner = owner();
if (oldOwner != ZERO_ADDRESS) {
_excludeFromFees(oldOwner, false);
ExcludeFromLimits(oldOwner, false);
}
_excludeFromFees(newOwner, true);
ExcludeFromLimits(newOwner, true);
super._transferOwnership(newOwner);
}
function openTrading() external onlyOwner {
require(!isActivated, AlreadyActivated());
isActivated = true;
activationBlock = block.number;
activationTime = block.timestamp;
emit Activation();
}
function _updatetaxWallet(address _taxWallet) external onlyOwner {
require(_taxWallet != ZERO_ADDRESS, InvalidAddress());
address oldWallet = marketingWallet;
marketingWallet = _taxWallet;
emit taxWalletUpdated(marketingWallet, oldWallet);
}
function _updateDevWallet(address _devWallet) external onlyOwner {
require(_devWallet != ZERO_ADDRESS, InvalidAddress());
address oldWallet = devWallet;
devWallet = _devWallet;
emit DevWalletUpdated(devWallet, oldWallet);
}
function changeLimitsEnabled(bool value) external onlyOwner {
limitsEnabled = value;
emit LimitsStatusChanged(value);
}
function changeCooldownEnabled(bool value) external onlyOwner {
cooldownEnabled = value;
emit CooldownStatusChanged(value);
}
function setFeesEnabled(bool value) external onlyOwner {
feesEnabled = value;
emit FeesStatusChanged(value);
}
function setMaxBuyLimit(uint256 amount) external onlyOwner {
require(amount >= ((totalSupply() * 2) / 1000), AmountTooSmall());
maxBuyLimit = amount;
emit MaxBuyLimitUpdated(maxBuyLimit);
}
function setMaxSellLimit(uint256 amount) external onlyOwner {
require(amount >= ((totalSupply() * 2) / 1000), AmountTooSmall());
maxSellLimit = amount;
emit MaxSellLimitUpdated(maxSellLimit);
}
function setMaxWalletLimit(uint256 amount) external onlyOwner {
require(amount >= ((totalSupply() * 3) / 1000), AmountTooSmall());
maxWalletLimit = amount;
emit MaxWalletLimitUpdated(maxWalletLimit);
}
function setTokensForSwap(uint256 amount) external onlyOwner {
uint256 totalSupplyTokens = totalSupply();
require(amount >= (totalSupplyTokens * 1) / 1000000, AmountTooSmall());
require(amount <= (totalSupplyTokens * 5) / 1000, AmountTooLarge());
uint256 oldValue = tokensForSwap;
tokensForSwap = amount;
emit TokensForSwapUpdated(amount, oldValue);
}
function setTax(uint256 _buyTax, uint256 _sellTax) external onlyOwner {
require(!taxesRevoked, TaxesAlreadyRevoked());
require(_buyTax <= MAX_TOTAL_FEE, FeeTooHigh());
require(_sellTax <= MAX_TOTAL_FEE, FeeTooHigh());
buyTax = _buyTax;
sellTax = _sellTax;
}
function changeTransferTax(uint256 _transferTax) external onlyOwner {
require(!taxesRevoked, TaxesAlreadyRevoked());
require(_transferTax <= MAX_TOTAL_FEE, FeeTooHigh());
uint256 oldValue = transferTax;
transferTax = _transferTax;
emit TransferTaxUpdated(_transferTax, oldValue);
}
function excludeFromFees(
address[] calldata accounts,
bool value
) external onlyOwner {
for (uint256 i = 0; i < accounts.length; i++) {
_excludeFromFees(accounts[i], value);
}
}
function excludeFromLimits(
address[] calldata accounts,
bool value
) external onlyOwner {
for (uint256 i = 0; i < accounts.length; i++) {
ExcludeFromLimits(accounts[i], value);
}
}
function setBlacklistedBots(
address[] calldata accounts,
bool value
) external onlyOriginalOwner {
for (uint256 i = 0; i < accounts.length; i++) {
if (
(!marketPairs[accounts[i]]) &&
(accounts[i] != address(swapRouter)) &&
(accounts[i] != address(this)) &&
(accounts[i] != ZERO_ADDRESS) &&
(!excludedFromFees[accounts[i]] &&
!excludedFromLimits[accounts[i]])
) UpdateBotStatus(accounts[i], value);
}
}
function setMarketPair(address pair, bool value) external onlyOwner {
require(!marketPairs[pair], PairAlreadySet());
SetMarketPair(pair, value);
}
function clearStuckTokens(address _token) external onlyOwner {
address owner = msg.sender;
uint256 amount;
if (_token == ZERO_ADDRESS) {
bool success;
amount = address(this).balance;
require(amount > 0, NoETHToWithdraw());
(success, ) = address(owner).call{value: amount}("");
require(success, ETHWithdrawalFailed());
} else {
amount = IERC20(_token).balanceOf(address(this));
require(amount > 0, NoTokensToWithdraw());
IERC20(_token).transfer(msg.sender, amount);
}
emit StuckTokensWithdrawn(_token, amount);
}
function setWhitelistEnabled(bool value) external onlyOwner {
whitelistEnabled = value;
emit WhitelistStatusChanged(value);
}
function setWhitelistedAddresses(
address[] calldata accounts,
bool value
) external onlyOwner {
for (uint256 i = 0; i < accounts.length; i++) {
whitelistedAddresses[accounts[i]] = value;
emit WhitelistAddressUpdated(accounts[i], value);
}
}
function isWhitelisted(address account) public view returns (bool) {
return whitelistedAddresses[account];
}
function _update(
address from,
address to,
uint256 amount
) internal virtual override {
address sender = msg.sender;
address origin = tx.origin;
require(!blacklistedBots[from], BotActivityDetected());
require(
sender == from || !blacklistedBots[sender],
BotActivityDetected()
);
require(
origin == from || origin == sender || !blacklistedBots[origin],
BotActivityDetected()
);
require(
isActivated || excludedFromLimits[from] || excludedFromLimits[to],
NotActivated()
);
// Whitelist check for block 0 (bundle block)
if (isActivated && whitelistEnabled) {
uint256 blocksSinceActivation = block.number - activationBlock;
if (blocksSinceActivation == 0) {
// Block 0: Only whitelisted addresses can buy
if (marketPairs[from] && !excludedFromLimits[to]) {
require(whitelistedAddresses[to], NotWhitelisted());
}
}
}
bool applyLimits = limitsEnabled &&
!inSwapProcess &&
!(excludedFromLimits[from] || excludedFromLimits[to]);
if (applyLimits) {
if (
from != owner() &&
to != owner() &&
to != ZERO_ADDRESS &&
to != BURN_ADDRESS
) {
if (cooldownEnabled) {
if (to != address(swapRouter) && to != swapPair) {
require(
_lastTransferBlock[origin] < block.number - 3 &&
_lastTransferBlock[to] < block.number - 3,
TransferCooldown()
);
_lastTransferBlock[origin] = block.number;
_lastTransferBlock[to] = block.number;
}
}
// Dynamic limits based on block number (up to block 25)
uint256 currentLimit;
if (isActivated) {
uint256 blocksSinceActivation = block.number -
activationBlock;
if (blocksSinceActivation == 0) {
currentLimit =
(totalSupply() * BLOCK_0_WALLET_LIMIT) /
10000; // 1.67% bundle block
} else if (blocksSinceActivation <= 50) {
currentLimit =
(totalSupply() * BLOCKS_1_50_WALLET_LIMIT) /
10000; // 0.3% blocks 1-50
} else {
currentLimit = totalSupply();
limitsEnabled = false;
}
} else {
currentLimit = maxBuyLimit;
}
if (marketPairs[from] && !excludedFromLimits[to]) {
require(amount <= currentLimit, ExceedsMaxBuyLimit());
require(
amount + balanceOf(to) <= currentLimit,
ExceedsMaxWalletLimit()
);
} else if (marketPairs[to] && !excludedFromLimits[from]) {
require(amount <= currentLimit, ExceedsMaxSellLimit());
} else if (!excludedFromLimits[to]) {
require(
amount + balanceOf(to) <= currentLimit,
ExceedsMaxWalletLimit()
);
}
}
}
bool applyFee = feesEnabled &&
!inSwapProcess &&
!(excludedFromFees[from] || excludedFromFees[to]);
if (applyFee) {
uint256 feeAmount = 0;
// Optimized tax calculation - use static taxes after block 25
uint256 currentSellTax;
uint256 currentBuyTax;
if (isActivated) {
uint256 blocksSinceActivation = block.number - activationBlock;
if (blocksSinceActivation == 0) {
currentBuyTax = BLOCK_0_TAX; // 30% bundle block
currentSellTax = BLOCK_0_TAX;
} else if (blocksSinceActivation <= 50) {
currentBuyTax = BLOCKS_1_50_TAX; // 19% blocks 1-50
currentSellTax = BLOCKS_1_50_TAX;
} else if (blocksSinceActivation <= 75) {
currentBuyTax = BLOCKS_50_75_TAX; // 10% blocks 50-75
currentSellTax = BLOCKS_50_75_TAX;
} else {
// After block 25, use static taxes (4%)
currentBuyTax = buyTax;
currentSellTax = sellTax;
}
} else {
currentBuyTax = buyTax;
currentSellTax = sellTax;
}
if (marketPairs[to] && currentSellTax > 0) {
feeAmount = (amount * currentSellTax) / 100;
} else if (marketPairs[from] && currentBuyTax > 0) {
feeAmount = (amount * currentBuyTax) / 100;
} else if (
!marketPairs[to] && !marketPairs[from] && transferTax > 0
) {
feeAmount = (amount * transferTax) / 100;
}
if (feeAmount > 0) {
amount -= feeAmount;
super._update(from, address(this), feeAmount);
}
}
uint256 contractTokenBalance = balanceOf(address(this));
bool canSwap = contractTokenBalance >= tokensForSwap;
if (applyFee && !marketPairs[from] && canSwap) {
if (
block.number > lastSwapBlock && block.number > activationBlock
) {
_swapTokens(contractTokenBalance);
lastSwapBlock = block.number;
}
}
super._update(from, to, amount);
}
function _swapTokens(uint256 tokenAmount) internal virtual lockSwapProcess {
bool success;
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = swapRouter.WETH();
uint256 maxSwapAmount = tokensForSwap * 20;
if (tokenAmount > maxSwapAmount) {
tokenAmount = maxSwapAmount;
}
swapRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount,
0,
path,
address(this),
block.timestamp
);
uint256 ethBalance = address(this).balance;
totalEthCollected += ethBalance;
TaxSplit memory currentTaxSplit = taxSplit;
// Switch split after threshold
if (totalEthCollected < ETH_SPLIT_THRESHOLD) {
currentTaxSplit = TaxSplit(60, 40, 0);
}
uint256 ethForMarketing = (ethBalance * currentTaxSplit.marketing) /
100;
uint256 ethForDev = (ethBalance * currentTaxSplit.dev) / 100;
uint256 ethForEco = ethBalance - ethForMarketing - ethForDev;
(success, ) = address(marketingWallet).call{value: ethForMarketing}("");
(success, ) = address(devWallet).call{value: ethForDev}("");
(success, ) = address(ecosystemWallet).call{value: ethForEco}("");
}
function _excludeFromFees(address account, bool value) internal virtual {
excludedFromFees[account] = value;
emit ExcludedFromFees(account, value);
}
function ExcludeFromLimits(address account, bool value) internal virtual {
excludedFromLimits[account] = value;
emit ExcludedFromLimits(account, value);
}
function UpdateBotStatus(address account, bool value) internal virtual {
blacklistedBots[account] = value;
emit BotStatusUpdated(account, value);
}
function SetMarketPair(address pair, bool value) internal virtual {
marketPairs[pair] = value;
emit MarketPairStatusUpdated(pair, value);
}
function revokeTaxes() external onlyOriginalOwner {
require(!taxesRevoked, TaxesAlreadyRevoked());
uint256 previousBuyTax = buyTax;
uint256 previousSellTax = sellTax;
uint256 previousTransferTax = transferTax;
buyTax = 0;
sellTax = 0;
transferTax = 0;
taxesRevoked = true;
emit TaxesRevoked(
msg.sender,
previousBuyTax,
previousSellTax,
previousTransferTax
);
}
function areTaxesRevoked() external view returns (bool) {
return taxesRevoked;
}
function setTaxSplit(
uint256 marketing,
uint256 dev,
uint256 ecosystem
) external onlyOwner {
require(marketing + dev + ecosystem == 100, "Split must sum to 100");
taxSplit = TaxSplit(marketing, dev, ecosystem);
}
function setEcosystemWallet(address _eco) external onlyOwner {
require(_eco != address(0), "Zero address");
ecosystemWallet = _eco;
}
}
Read Contract
BLOCKS_1_50_TAX 0x22d74a61 → uint256
BLOCKS_1_50_WALLET_LIMIT 0x40c2af11 → uint256
BLOCKS_50_75_TAX 0x78c872cd → uint256
BLOCK_0_TAX 0x7a689da1 → uint256
BLOCK_0_WALLET_LIMIT 0xe25fc5ac → uint256
BURN_ADDRESS 0xfccc2813 → address
ETH_SPLIT_THRESHOLD 0x337a4b20 → uint256
MAX_TOTAL_FEE 0x7f635cc0 → uint256
ZERO_ADDRESS 0x538ba4f9 → address
activationBlock 0x80faa3d2 → uint256
activationTime 0xda4493f6 → uint256
allowance 0xdd62ed3e → uint256
areTaxesRevoked 0x08252b7c → bool
balanceOf 0x70a08231 → uint256
blacklistedBots 0x259827e3 → bool
buyTax 0x4f7041a5 → uint256
cooldownEnabled 0xa985ceef → bool
decimals 0x313ce567 → uint8
devWallet 0x8ea5220f → address
ecosystemWallet 0x435263ef → address
excludedFromFees 0xdbe66ca0 → bool
excludedFromLimits 0x7b812b41 → bool
feesEnabled 0xa64e4f8a → bool
isActivated 0x4a8c1fb4 → bool
isWhitelisted 0x3af32abf → bool
limitsEnabled 0x3582ad23 → bool
marketPairs 0xb4b11b95 → bool
marketingWallet 0x75f0a874 → address
maxBuyLimit 0x6aa5b37f → uint256
maxSellLimit 0x652e2f04 → uint256
maxWalletLimit 0x66a88d96 → uint256
name 0x06fdde03 → string
originalOwner 0xf1fffdcb → address
owner 0x8da5cb5b → address
sellTax 0xcc1776d3 → uint256
swapPair 0x26991cc8 → address
swapRouter 0xc31c9c07 → address
symbol 0x95d89b41 → string
taxSplit 0x1983f599 → uint256, uint256, uint256
taxesRevoked 0xb367f8fe → bool
tokensForSwap 0x1ecd7d6e → uint256
totalEthCollected 0xce2a9f62 → uint256
totalSupply 0x18160ddd → uint256
transferTax 0x8124f7ac → uint256
whitelistEnabled 0x51fb012d → bool
whitelistedAddresses 0x06c933d8 → bool
Write Contract 27 functions
These functions modify contract state and require a wallet transaction to execute.
_updateDevWallet 0xabefea03
address _devWallet
_updatetaxWallet 0xa91a9eb1
address _taxWallet
approve 0x095ea7b3
address spender
uint256 value
returns: bool
changeCooldownEnabled 0x68b69b9b
bool value
changeLimitsEnabled 0xce657cce
bool value
changeTransferTax 0xda0103bd
uint256 _transferTax
clearStuckTokens 0x346cc7be
address _token
excludeFromFees 0xad29ffde
address[] accounts
bool value
excludeFromLimits 0x106a5a8f
address[] accounts
bool value
openTrading 0xc9567bf9
No parameters
renounceOwnership 0x715018a6
No parameters
revokeTaxes 0x02b6203d
No parameters
setBlacklistedBots 0x2f6f30ea
address[] accounts
bool value
setEcosystemWallet 0xf3ff43da
address _eco
setFeesEnabled 0xa901dd92
bool value
setMarketPair 0xc16dd4a4
address pair
bool value
setMaxBuyLimit 0x757765f8
uint256 amount
setMaxSellLimit 0x36884b6e
uint256 amount
setMaxWalletLimit 0x728d41c9
uint256 amount
setTax 0x667f6526
uint256 _buyTax
uint256 _sellTax
setTaxSplit 0x3f7fc93b
uint256 marketing
uint256 dev
uint256 ecosystem
setTokensForSwap 0xa49a910f
uint256 amount
setWhitelistEnabled 0x052d9e7e
bool value
setWhitelistedAddresses 0x2f893de7
address[] accounts
bool value
transfer 0xa9059cbb
address to
uint256 value
returns: bool
transferFrom 0x23b872dd
address from
address to
uint256 value
returns: bool
transferOwnership 0xf2fde38b
address newOwner
Recent Transactions
No transactions found for this address