Forkchoice Ethereum Mainnet

Address Contract Partially Verified

Address 0x77ed2726e90eBCA17426B897a5eAc6D32Fc64D57
Balance 0 ETH
Nonce 1
Code Size 13390 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

13390 bytes
0x6080604052600436106101c5575f3560e01c80638da5cb5b116100f6578063c17ae74111610094578063d2ec694d11610063578063d2ec694d1461066b578063dc07065714610695578063e8c7dd59146106bd578063f2fde38b146106e557610205565b8063c17ae741146105e5578063cb6d3b171461060f578063cc42364d14610637578063cd2b64d91461064157610205565b8063a6e517d8116100d0578063a6e517d81461052c578063a80a50b914610568578063b462068414610590578063b6c03713146105b857610205565b80638da5cb5b146104c45780639e281a98146104ee578063a0ef91df1461051657610205565b806334b2e3ce11610163578063715018a61161013d578063715018a61461040a5780637299a72914610420578063745408001461044a5780638ca0ff541461048857610205565b806334b2e3ce1461038c57806338af3eed146103b6578063712307d1146103e057610205565b80631722835e1161019f5780631722835e146102ae5780632f48ab7d146102ea5780633246c689146103145780633417fa5f1461035057610205565b8063090694431461024057806311de78561461026857806312efb3f41461027257610205565b36610205576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101fc90612471565b60405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610237906124d9565b60405180910390fd5b34801561024b575f5ffd5b506102666004803603810190610261919061289b565b61070d565b005b610270610a57565b005b34801561027d575f5ffd5b506102986004803603810190610293919061293f565b610d90565b6040516102a59190612984565b60405180910390f35b3480156102b9575f5ffd5b506102d460048036038101906102cf919061299d565b610dad565b6040516102e191906129ea565b60405180910390f35b3480156102f5575f5ffd5b506102fe610f2d565b60405161030b9190612a12565b60405180910390f35b34801561031f575f5ffd5b5061033a6004803603810190610335919061293f565b610f52565b6040516103479190612a3a565b60405180910390f35b34801561035b575f5ffd5b506103766004803603810190610371919061293f565b610f6f565b60405161038391906129ea565b60405180910390f35b348015610397575f5ffd5b506103a0610f84565b6040516103ad91906129ea565b60405180910390f35b3480156103c1575f5ffd5b506103ca610f8a565b6040516103d79190612a12565b60405180910390f35b3480156103eb575f5ffd5b506103f4610faf565b60405161040191906129ea565b60405180910390f35b348015610415575f5ffd5b5061041e610fb5565b005b34801561042b575f5ffd5b50610434610fc8565b6040516104419190612a12565b60405180910390f35b348015610455575f5ffd5b50610470600480360381019061046b919061293f565b610fed565b60405161047f93929190612a53565b60405180910390f35b348015610493575f5ffd5b506104ae60048036038101906104a9919061293f565b611085565b6040516104bb91906129ea565b60405180910390f35b3480156104cf575f5ffd5b506104d861109a565b6040516104e59190612a12565b60405180910390f35b3480156104f9575f5ffd5b50610514600480360381019061050f919061299d565b6110c1565b005b348015610521575f5ffd5b5061052a6111f9565b005b348015610537575f5ffd5b50610552600480360381019061054d919061293f565b6112cd565b60405161055f91906129ea565b60405180910390f35b348015610573575f5ffd5b5061058e60048036038101906105899190612ae1565b6112e2565b005b34801561059b575f5ffd5b506105b660048036038101906105b1919061293f565b6114e9565b005b3480156105c3575f5ffd5b506105cc611637565b6040516105dc9493929190612b2c565b60405180910390f35b3480156105f0575f5ffd5b506105f9611655565b60405161060691906129ea565b60405180910390f35b34801561061a575f5ffd5b506106356004803603810190610630919061299d565b61165b565b005b61063f611a20565b005b34801561064c575f5ffd5b50610655611d59565b60405161066291906129ea565b60405180910390f35b348015610676575f5ffd5b5061067f611d5f565b60405161068c91906129ea565b60405180910390f35b3480156106a0575f5ffd5b506106bb60048036038101906106b6919061293f565b611d65565b005b3480156106c8575f5ffd5b506106e360048036038101906106de919061299d565b611e30565b005b3480156106f0575f5ffd5b5061070b6004803603810190610706919061293f565b6121f5565b005b610715612279565b81518351148015610727575080518251145b610766576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075d90612bb9565b60405180910390fd5b5f835190505f60095460075461077c9190612c04565b90505f600a60029054906101000a900460ff16600a61079b9190612d66565b600d5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054836108059190612db0565b61080f9190612e1e565b90506007546009819055508060085f82825461082b9190612e4e565b925050819055505f5f90505b83811015610a1f575f87828151811061085357610852612e81565b5b602002602001015190505f87838151811061087157610870612e81565b5b602002602001015190505f87848151811061088f5761088e612e81565b5b602002602001015190505f81116108db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d290612ef8565b60405180910390fd5b6001600b5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555081600c5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908360ff16021790555080600d5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550808260ff168473ffffffffffffffffffffffffffffffffffffffff167f7b5906735faf5fee0c1cfda9eeb9a894beee1a6c8f6e86b43c20eed8161b7cb960405160405180910390a45050508080600101915050610837565b504281837fcb836f71bb0e489fc073f606c37bcf0e5b0eb68495784b84270f7d63992323cd60405160405180910390a4505050505050565b610a5f612300565b5f600d5f60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205411610aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af690612f60565b60405180910390fd5b5f3411610b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3890612fc8565b60405180910390fd5b5f610b6d60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1634610dad565b90505f8111610bb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba890613030565b60405180910390fd5b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1634604051610bf79061307b565b5f6040518083038185875af1925050503d805f8114610c31576040519150601f19603f3d011682016040523d82523d5f602084013e610c36565b606091505b5050905080610c7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c71906130d9565b60405180910390fd5b8160075f828254610c8b9190612e4e565b925050819055508160055f828254610ca39190612e4e565b9250508190555081600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610cf69190612e4e565b925050819055503460045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8daf503382665d950e449b86172be5222275c90f4ddf69c29fdaa8237a562a6d85604051610d7c91906129ea565b60405180910390a45050610d8e612346565b565b600b602052805f5260405f205f915054906101000a900460ff1681565b5f600b5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16610e37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2e90613141565b60405180910390fd5b5f600d5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205411610eb6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ead90612f60565b60405180910390fd5b600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054600a60029054906101000a900460ff16600a610f109190612d66565b83610f1b9190612db0565b610f259190612e1e565b905092915050565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600c602052805f5260405f205f915054906101000a900460ff1681565b600d602052805f5260405f205f915090505481565b60095481565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60075481565b610fbd612279565b610fc65f61234f565b565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f5f600e5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549150600f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050808261107c9190612e4e565b92509193909250565b600e602052805f5260405f205f915090505481565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6110c9612279565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611158576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114f906131a9565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b81526004016111b49291906131c7565b6020604051808303815f875af11580156111d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111f49190613218565b505050565b611201612279565b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16476040516112479061307b565b5f6040518083038185875af1925050503d805f8114611281576040519150601f19603f3d011682016040523d82523d5f602084013e611286565b606091505b50509050806112ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c1906130d9565b60405180910390fd5b50565b600f602052805f5260405f205f915090505481565b6112ea612279565b5f8282905090505f5f90505b818110156114e3575f84848381811061131257611311612e81565b5b9050602002016020810190611327919061293f565b9050600b5f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff166113b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a990613141565b60405180910390fd5b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550600c5f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81549060ff0219169055600d5f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f90558073ffffffffffffffffffffffffffffffffffffffff167f4c910b69fe65a61f7531b9c5042b2329ca7179c77290aa7e2eb3afa3c8511fd360405160405180910390a25080806001019150506112f6565b50505050565b6114f1612279565b5f600a60019054906101000a900460ff1660ff1614611545576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153c9061328d565b60405180910390fd5b6001600a60016101000a81548160ff021916908360ff16021790555060045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036115f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115e7906132f5565b60405180910390fd5b428173ffffffffffffffffffffffffffffffffffffffff167fa200937cb72273d8e618bb06108060cb0c737cc4838e5ecd0b76a37f98c0d67b60405160405180910390a350565b5f5f5f5f600754935060085492506005549150600654905090919293565b60085481565b611663612300565b600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff166116ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e390613141565b60405180910390fd5b5f600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541161176b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176290612f60565b60405180910390fd5b5f81116117ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a490612fc8565b60405180910390fd5b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361183c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118339061335d565b60405180910390fd5b5f6118478383610dad565b90505f811161188b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188290613030565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3360035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856040518463ffffffff1660e01b81526004016118e99392919061337b565b6020604051808303815f875af1158015611905573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119299190613218565b508060075f82825461193b9190612e4e565b925050819055508060055f8282546119539190612e4e565b9250508190555080600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546119a69190612e4e565b92505081905550818373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8daf503382665d950e449b86172be5222275c90f4ddf69c29fdaa8237a562a6d84604051611a0b91906129ea565b60405180910390a450611a1c612346565b5050565b611a28612300565b5f600d5f60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205411611ac8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611abf90612f60565b60405180910390fd5b5f3411611b0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b0190612fc8565b60405180910390fd5b5f611b3660045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1634610dad565b90505f8111611b7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b7190613030565b60405180910390fd5b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1634604051611bc09061307b565b5f6040518083038185875af1925050503d805f8114611bfa576040519150601f19603f3d011682016040523d82523d5f602084013e611bff565b606091505b5050905080611c43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3a906130d9565b60405180910390fd5b8160075f828254611c549190612e4e565b925050819055508160065f828254611c6c9190612e4e565b9250508190555081600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611cbf9190612e4e565b925050819055503460045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8daf503382665d950e449b86172be5222275c90f4ddf69c29fdaa8237a562a6d85604051611d4591906129ea565b60405180910390a45050611d57612346565b565b60065481565b60055481565b611d6d612279565b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fe72eaf6addaa195f3c83095031dd08f3a96808dcf047babed1fe4e4f69d6c62260405160405180910390a35050565b611e38612300565b600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611ec1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb890613141565b60405180910390fd5b5f600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205411611f40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3790612f60565b60405180910390fd5b5f8111611f82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f7990612fc8565b60405180910390fd5b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612011576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612008906133fa565b60405180910390fd5b5f61201c8383610dad565b90505f8111612060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205790613030565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3360035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856040518463ffffffff1660e01b81526004016120be9392919061337b565b6020604051808303815f875af11580156120da573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120fe9190613218565b508060075f8282546121109190612e4e565b925050819055508060065f8282546121289190612e4e565b9250508190555080600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461217b9190612e4e565b92505081905550818373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8daf503382665d950e449b86172be5222275c90f4ddf69c29fdaa8237a562a6d846040516121e091906129ea565b60405180910390a4506121f1612346565b5050565b6121fd612279565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361226d575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016122649190612a12565b60405180910390fd5b6122768161234f565b50565b612281612410565b73ffffffffffffffffffffffffffffffffffffffff1661229f61109a565b73ffffffffffffffffffffffffffffffffffffffff16146122fe576122c2612410565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016122f59190612a12565b60405180910390fd5b565b60026001540361233c576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600181905550565b60018081905550565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f33905090565b5f82825260208201905092915050565b7f557365206275792f7374616b65207769746820455448000000000000000000005f82015250565b5f61245b601683612417565b915061246682612427565b602082019050919050565b5f6020820190508181035f8301526124888161244f565b9050919050565b7f46756e6374696f6e2f6d6574686f64204944206973206e6f7420666f756e64005f82015250565b5f6124c3601f83612417565b91506124ce8261248f565b602082019050919050565b5f6020820190508181035f8301526124f0816124b7565b9050919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6125528261250c565b810181811067ffffffffffffffff821117156125715761257061251c565b5b80604052505050565b5f6125836124f7565b905061258f8282612549565b919050565b5f67ffffffffffffffff8211156125ae576125ad61251c565b5b602082029050602081019050919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6125ec826125c3565b9050919050565b6125fc816125e2565b8114612606575f5ffd5b50565b5f81359050612617816125f3565b92915050565b5f61262f61262a84612594565b61257a565b90508083825260208201905060208402830185811115612652576126516125bf565b5b835b8181101561267b57806126678882612609565b845260208401935050602081019050612654565b5050509392505050565b5f82601f83011261269957612698612508565b5b81356126a984826020860161261d565b91505092915050565b5f67ffffffffffffffff8211156126cc576126cb61251c565b5b602082029050602081019050919050565b5f60ff82169050919050565b6126f2816126dd565b81146126fc575f5ffd5b50565b5f8135905061270d816126e9565b92915050565b5f612725612720846126b2565b61257a565b90508083825260208201905060208402830185811115612748576127476125bf565b5b835b81811015612771578061275d88826126ff565b84526020840193505060208101905061274a565b5050509392505050565b5f82601f83011261278f5761278e612508565b5b813561279f848260208601612713565b91505092915050565b5f67ffffffffffffffff8211156127c2576127c161251c565b5b602082029050602081019050919050565b5f819050919050565b6127e5816127d3565b81146127ef575f5ffd5b50565b5f81359050612800816127dc565b92915050565b5f612818612813846127a8565b61257a565b9050808382526020820190506020840283018581111561283b5761283a6125bf565b5b835b81811015612864578061285088826127f2565b84526020840193505060208101905061283d565b5050509392505050565b5f82601f83011261288257612881612508565b5b8135612892848260208601612806565b91505092915050565b5f5f5f606084860312156128b2576128b1612500565b5b5f84013567ffffffffffffffff8111156128cf576128ce612504565b5b6128db86828701612685565b935050602084013567ffffffffffffffff8111156128fc576128fb612504565b5b6129088682870161277b565b925050604084013567ffffffffffffffff81111561292957612928612504565b5b6129358682870161286e565b9150509250925092565b5f6020828403121561295457612953612500565b5b5f61296184828501612609565b91505092915050565b5f8115159050919050565b61297e8161296a565b82525050565b5f6020820190506129975f830184612975565b92915050565b5f5f604083850312156129b3576129b2612500565b5b5f6129c085828601612609565b92505060206129d1858286016127f2565b9150509250929050565b6129e4816127d3565b82525050565b5f6020820190506129fd5f8301846129db565b92915050565b612a0c816125e2565b82525050565b5f602082019050612a255f830184612a03565b92915050565b612a34816126dd565b82525050565b5f602082019050612a4d5f830184612a2b565b92915050565b5f606082019050612a665f8301866129db565b612a7360208301856129db565b612a8060408301846129db565b949350505050565b5f5ffd5b5f5f83601f840112612aa157612aa0612508565b5b8235905067ffffffffffffffff811115612abe57612abd612a88565b5b602083019150836020820283011115612ada57612ad96125bf565b5b9250929050565b5f5f60208385031215612af757612af6612500565b5b5f83013567ffffffffffffffff811115612b1457612b13612504565b5b612b2085828601612a8c565b92509250509250929050565b5f608082019050612b3f5f8301876129db565b612b4c60208301866129db565b612b5960408301856129db565b612b6660608301846129db565b95945050505050565b7f4172726179206c656e677468206d69736d6174636800000000000000000000005f82015250565b5f612ba3601583612417565b9150612bae82612b6f565b602082019050919050565b5f6020820190508181035f830152612bd081612b97565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612c0e826127d3565b9150612c19836127d3565b9250828203905081811115612c3157612c30612bd7565b5b92915050565b5f8160011c9050919050565b5f5f8291508390505b6001851115612c8c57808604811115612c6857612c67612bd7565b5b6001851615612c775780820291505b8081029050612c8585612c37565b9450612c4c565b94509492505050565b5f82612ca45760019050612d5f565b81612cb1575f9050612d5f565b8160018114612cc75760028114612cd157612d00565b6001915050612d5f565b60ff841115612ce357612ce2612bd7565b5b8360020a915084821115612cfa57612cf9612bd7565b5b50612d5f565b5060208310610133831016604e8410600b8410161715612d355782820a905083811115612d3057612d2f612bd7565b5b612d5f565b612d428484846001612c43565b92509050818404811115612d5957612d58612bd7565b5b81810290505b9392505050565b5f612d70826127d3565b9150612d7b836126dd565b9250612da87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484612c95565b905092915050565b5f612dba826127d3565b9150612dc5836127d3565b9250828202612dd3816127d3565b91508282048414831517612dea57612de9612bd7565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f612e28826127d3565b9150612e33836127d3565b925082612e4357612e42612df1565b5b828204905092915050565b5f612e58826127d3565b9150612e63836127d3565b9250828201905080821115612e7b57612e7a612bd7565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f52617465206d7573742062652067726561746572207468616e203000000000005f82015250565b5f612ee2601b83612417565b9150612eed82612eae565b602082019050919050565b5f6020820190508181035f830152612f0f81612ed6565b9050919050565b7f52617465206e6f742073657400000000000000000000000000000000000000005f82015250565b5f612f4a600c83612417565b9150612f5582612f16565b602082019050919050565b5f6020820190508181035f830152612f7781612f3e565b9050919050565b7f416d6f756e74206d7573742062652067726561746572207468616e20300000005f82015250565b5f612fb2601d83612417565b9150612fbd82612f7e565b602082019050919050565b5f6020820190508181035f830152612fdf81612fa6565b9050919050565b7f50575420616d6f756e7420746f6f20736d616c6c0000000000000000000000005f82015250565b5f61301a601483612417565b915061302582612fe6565b602082019050919050565b5f6020820190508181035f8301526130478161300e565b9050919050565b5f81905092915050565b50565b5f6130665f8361304e565b915061307182613058565b5f82019050919050565b5f6130858261305b565b9150819050919050565b7f4661696c656420746f2073656e642045746865720000000000000000000000005f82015250565b5f6130c3601483612417565b91506130ce8261308f565b602082019050919050565b5f6020820190508181035f8301526130f0816130b7565b9050919050565b7f546f6b656e206e6f7420737570706f72746564000000000000000000000000005f82015250565b5f61312b601383612417565b9150613136826130f7565b602082019050919050565b5f6020820190508181035f8301526131588161311f565b9050919050565b7f55736520776974686472617745746828290000000000000000000000000000005f82015250565b5f613193601183612417565b915061319e8261315f565b602082019050919050565b5f6020820190508181035f8301526131c081613187565b9050919050565b5f6040820190506131da5f830185612a03565b6131e760208301846129db565b9392505050565b6131f78161296a565b8114613201575f5ffd5b50565b5f81519050613212816131ee565b92915050565b5f6020828403121561322d5761322c612500565b5b5f61323a84828501613204565b91505092915050565b7f50575420616c726561647920696e697469616c697a65640000000000000000005f82015250565b5f613277601783612417565b915061328282613243565b602082019050919050565b5f6020820190508181035f8301526132a48161326b565b9050919050565b7f496e76616c6964206164647265737300000000000000000000000000000000005f82015250565b5f6132df600f83612417565b91506132ea826132ab565b602082019050919050565b5f6020820190508181035f83015261330c816132d3565b9050919050565b7f557365206275795077745769746845746820666f7220455448000000000000005f82015250565b5f613347601983612417565b915061335282613313565b602082019050919050565b5f6020820190508181035f8301526133748161333b565b9050919050565b5f60608201905061338e5f830186612a03565b61339b6020830185612a03565b6133a860408301846129db565b949350505050565b7f557365207374616b655077745769746845746820666f722045544800000000005f82015250565b5f6133e4601b83612417565b91506133ef826133b0565b602082019050919050565b5f6020820190508181035f830152613411816133d8565b905091905056fea2646970667358221220b917145335e5cfce813f1e6feeb19d734eebcdc1c005a5993f362ef987394add64736f6c634300081c0033

Verified Source Code Partial Match

Compiler: v0.8.28+commit.7893614a EVM: cancun Optimization: No
Ownable.sol 100 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * 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);
    }
}
IERC20.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
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);
}
Context.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

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;
    }
}
ReentrancyGuard.sol 87 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)

pragma solidity ^0.8.20;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
 * consider using {ReentrancyGuardTransient} instead.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;

    uint256 private _status;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // Any calls to nonReentrant after this point will fail
        _status = ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}
PWTPresale_250125.sol 332 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

/// @title PWT Manager
/// @author NSLab Co., Ltd.
/// @notice This contract manages the presale process for PWT tokens.

contract PWTManager is Ownable, ReentrancyGuard {
    address public usdt;
    address public beneficiary;
    address public addressZero = address(0);
    uint256 public totalPwtBought;
    uint256 public totalPwtStaked;
    uint256 public totalPwtRaised;
    uint256 public totalPwtRaisedInUsdWei;
    uint256 public totalLastPwtRaised;
    uint8 private _isPreviousDataInit;
    uint8 private _isPwtInit;
    uint8 private _pwtDecimals;

    modifier initPwt() {
        require(_isPwtInit == 0, "PWT already initialized");
        _isPwtInit = 1;
        _;
    }

    // Supported tokens configuration
    mapping(address => bool) public SupportedTokens;
    mapping(address => uint8) public TokenDecimals;

    // Conversion rates for each token (how many tokens needed for 1 PWT)
    mapping(address token => uint256 rate) public TokenRates;

    // Track balance of users who bought PWT
    mapping(address user => uint256 balance) public PwtBoughtTotal;

    // Track balance of users who staked PWT
    mapping(address user => uint256 balance) public PwtStakedTotal;

    // Events
    event BeneficiaryUpdated(
        address indexed oldBeneficiary,
        address indexed newBeneficiary
    );
    event PwtSet(address indexed PwtContract, uint256 indexed timestamp);

    event TokenAdded(
        address indexed token,
        uint8 indexed decimals,
        uint256 indexed rate
    );
    event TokenRemoved(address indexed token);
    event TokenPurchased(
        address indexed buyer,
        address indexed token,
        uint256 indexed amount,
        uint256 pwtAmount
    );
    event PwtRaisedThisPeriod(
        uint256 indexed amountRaised,
        uint256 indexed amountRaisedInUsd,
        uint256 indexed timestamp
    );

    constructor(address _beneficiary) Ownable(msg.sender) {
        beneficiary = _beneficiary;
        usdt = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
        _pwtDecimals = 18;

        address[7] memory users = [
            0x5C903458b9Ca6587408B998DFDe0Bc9a80141e81,
            0x803bbf352C51aC2F4b03881525B8f960875E1770,
            0xeBb057a4483dAa4C721b286a836a00bD6C2c0df2,
            0x7ee6bE6912e8EeD5B7327e6A21c23aCdb7Eb2EB1,
            0x1722cA74a4D6A84D11c2e7b7E7f3dB7059aAAeeF,
            0xE7B56fb86eEcF6F952BE86085aC3c85D4f3640DB,
            0x7b80E47091F6FDB23F83b63A4A2473AFBF715FA7
        ];

        uint256[7] memory balances = [
            uint256(62238736646539712029725),
            uint256(371574547143520668834),
            uint256(12411054112195929174251),
            uint256(11583650504716200562634),
            uint256(1034254509349660764520),
            uint256(1406586132715538639748),
            uint256(1009432401125268906172)
        ];

        for (uint i = 0; i < users.length; i++) {
            PwtBoughtTotal[users[i]] = balances[i];
            totalPwtBought += balances[i];
            totalPwtRaised += balances[i];
        }
    }

    // Set PWT token address. MUST BE FIRST FUNCTION TO CALL AND ONLY ONCE
    function setPwt(address _pwt) external onlyOwner initPwt {
        require(_pwt != addressZero, "Invalid address");
        // pwtPresale = PWTPresale(_pwt);
        emit PwtSet(_pwt, block.timestamp);
    }

    // Owner function to:
    // 1. Add supported token
    // 2. Update the rates for the token
    // Ex:
    // - rates of token X = 1, meaning 1 PWT = 1 token X. getPwtAmount(token X, 1) equals 1
    // - rates of token X = 2e18, meaning 1 PWT = 2 token X. getPwtAmount(token X, 1) equals 0.5
    // 3. emit the total PWT raised in USD for the last period to event

    function updateSupportedToken(
        address[] memory tokens,
        uint8[] memory decimals,
        uint256[] memory rates
    ) public onlyOwner {
        require(
            tokens.length == decimals.length && decimals.length == rates.length,
            "Array length mismatch"
        );
        uint256 length = tokens.length;

        // Save the difference amount of PWT raised from the last update
        uint256 deltaPwt = totalPwtRaised - totalLastPwtRaised;
        uint256 deltaPwtInUsd = (deltaPwt * TokenRates[usdt]) /
            (10 ** _pwtDecimals);

        // Save the current PWT raised for the next update
        totalLastPwtRaised = totalPwtRaised;
        totalPwtRaisedInUsdWei += deltaPwtInUsd;

        for (uint256 i = 0; i < length; i++) {
            address token = tokens[i];
            uint8 decimal = decimals[i];
            uint256 rate = rates[i];
            require(rate > 0, "Rate must be greater than 0");

            SupportedTokens[token] = true;
            TokenDecimals[token] = decimal;
            TokenRates[token] = rate;

            emit TokenAdded(token, decimal, rate);
        }

        emit PwtRaisedThisPeriod(deltaPwt, deltaPwtInUsd, block.timestamp);
    }

    // Owner function to remove supported token
    function removeSupportedToken(
        address[] calldata tokens
    ) external onlyOwner {
        uint256 length = tokens.length;

        for (uint256 i = 0; i < length; i++) {
            address token = tokens[i];
            require(SupportedTokens[token], "Token not supported"); //should output which token is not supported

            SupportedTokens[token] = false;
            delete TokenDecimals[token];
            delete TokenRates[token];

            emit TokenRemoved(token);
        }
    }

    // Function to buy PWT with ETH
    function buyPwtWithEth() public payable nonReentrant {
        require(TokenRates[addressZero] > 0, "Rate not set");
        require(msg.value > 0, "Amount must be greater than 0");

        uint256 pwtAmount = getPwtAmount(addressZero, msg.value);
        require(pwtAmount > 0, "PWT amount too small");

        // Transfer ETH from buyer to beneficiary
        (bool sent, ) = beneficiary.call{value: msg.value}("");
        require(sent, "Failed to send Ether");

        // Record the purchase
        totalPwtRaised += pwtAmount;
        totalPwtBought += pwtAmount;
        PwtBoughtTotal[msg.sender] += pwtAmount;

        emit TokenPurchased(msg.sender, addressZero, msg.value, pwtAmount);
    }

    // Function to buy PWT tokens using ERC20 tokens
    function buyPwtWithErc20(
        address token,
        uint256 amount
    ) public nonReentrant {
        require(SupportedTokens[token], "Token not supported");
        require(TokenRates[token] > 0, "Rate not set");
        require(amount > 0, "Amount must be greater than 0");
        require(token != addressZero, "Use buyPwtWithEth for ETH");

        // Calculate PWT amount to be received with proper decimal handling
        uint256 pwtAmount = getPwtAmount(token, amount);
        require(pwtAmount > 0, "PWT amount too small");

        // Transfer tokens from buyer to beneficiary
        IERC20(token).transferFrom(msg.sender, beneficiary, amount);

        // Record the purchase
        totalPwtRaised += pwtAmount;
        totalPwtBought += pwtAmount;
        PwtBoughtTotal[msg.sender] += pwtAmount;

        emit TokenPurchased(msg.sender, token, amount, pwtAmount);
    }

    // Function to stake PWT with ETH
    function stakePwtWithEth() external payable nonReentrant {
        require(TokenRates[addressZero] > 0, "Rate not set");
        require(msg.value > 0, "Amount must be greater than 0");

        // For ETH (18 decimals), multiply by 1e18 before division to maintain precision
        uint256 pwtAmount = getPwtAmount(addressZero, msg.value);
        require(pwtAmount > 0, "PWT amount too small");

        // Transfer ETH from buyer to beneficiary
        (bool sent, ) = beneficiary.call{value: msg.value}("");
        require(sent, "Failed to send Ether");

        // Record the stake
        totalPwtRaised += pwtAmount;
        totalPwtStaked += pwtAmount;
        PwtStakedTotal[msg.sender] += pwtAmount;

        emit TokenPurchased(msg.sender, addressZero, msg.value, pwtAmount);
    }

    // Function to stake PWT using ERC20 tokens
    function stakePwtWithErc20(
        address token,
        uint256 amount
    ) external nonReentrant {
        require(SupportedTokens[token], "Token not supported");
        require(TokenRates[token] > 0, "Rate not set");
        require(amount > 0, "Amount must be greater than 0");
        require(token != addressZero, "Use stakePwtWithEth for ETH");

        // Calculate PWT amount to be received with proper decimal handling
        uint256 pwtAmount = getPwtAmount(token, amount);
        require(pwtAmount > 0, "PWT amount too small");

        // Transfer tokens from buyer to beneficiary
        IERC20(token).transferFrom(msg.sender, beneficiary, amount);

        // Record the stake
        totalPwtRaised += pwtAmount;
        totalPwtStaked += pwtAmount;
        PwtStakedTotal[msg.sender] += pwtAmount;

        emit TokenPurchased(msg.sender, token, amount, pwtAmount);
    }

    // Change beneficiary
    function changeBeneficiary(address newBeneficiary) external onlyOwner {
        address oldBeneficiary = beneficiary;
        beneficiary = newBeneficiary;

        emit BeneficiaryUpdated(oldBeneficiary, newBeneficiary);
    }

    // GETTER FUNCTIONS //
    // View function to get PWT amount for given token amount
    function getPwtAmount(
        address token,
        uint256 amount
    ) public view returns (uint256) {
        require(SupportedTokens[token], "Token not supported");
        require(TokenRates[token] > 0, "Rate not set");

        return (amount * (10 ** _pwtDecimals)) / TokenRates[token];
    }

    // View function to get total purchased amount for a buyer and token
    function getTotalPurchasedPwt(
        address user
    )
        public
        view
        returns (uint256 totalValue, uint256 totalBought, uint256 totalStaked)
    {
        totalBought = PwtBoughtTotal[user];
        totalStaked = PwtStakedTotal[user];
        totalValue = totalBought + totalStaked;
        return (totalValue, totalBought, totalStaked);
    }

    // View function to get how much PWT has been raised
    function getRaisedPwt()
        public
        view
        returns (
            uint256 totalRaised,
            uint256 totalInUsd,
            uint256 totalBought,
            uint256 totalStaked
        )
    {
        totalRaised = totalPwtRaised;
        totalInUsd = totalPwtRaisedInUsdWei;
        totalBought = totalPwtBought;
        totalStaked = totalPwtStaked;
    }

    // Emergency function to withdraw stuck tokens (only owner)
    function withdrawToken(address token, uint256 amount) external onlyOwner {
        require(token != addressZero, "Use withdrawEth()");
        IERC20(token).transfer(beneficiary, amount);
    }

    function withdrawEth() external onlyOwner {
        // Transfer ETH from buyer to beneficiary
        (bool sent, ) = beneficiary.call{value: (address(this).balance)}("");
        require(sent, "Failed to send Ether");
    }

    // Function to receive ETH
    receive() external payable {
        revert("Use buy/stake with ETH");
    }

    fallback() external payable {
        revert("Function/method ID is not found");
    }
}

Read Contract

PwtBoughtTotal 0x8ca0ff54 → uint256
PwtStakedTotal 0xa6e517d8 → uint256
SupportedTokens 0x12efb3f4 → bool
TokenDecimals 0x3246c689 → uint8
TokenRates 0x3417fa5f → uint256
addressZero 0x7299a729 → address
beneficiary 0x38af3eed → address
getPwtAmount 0x1722835e → uint256
getRaisedPwt 0xb6c03713 → uint256, uint256, uint256, uint256
getTotalPurchasedPwt 0x74540800 → uint256, uint256, uint256
owner 0x8da5cb5b → address
totalLastPwtRaised 0x34b2e3ce → uint256
totalPwtBought 0xd2ec694d → uint256
totalPwtRaised 0x712307d1 → uint256
totalPwtRaisedInUsdWei 0xc17ae741 → uint256
totalPwtStaked 0xcd2b64d9 → uint256
usdt 0x2f48ab7d → address

Write Contract 12 functions

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

buyPwtWithErc20 0xcb6d3b17
address token
uint256 amount
buyPwtWithEth 0x11de7856
No parameters
changeBeneficiary 0xdc070657
address newBeneficiary
removeSupportedToken 0xa80a50b9
address[] tokens
renounceOwnership 0x715018a6
No parameters
setPwt 0xb4620684
address _pwt
stakePwtWithErc20 0xe8c7dd59
address token
uint256 amount
stakePwtWithEth 0xcc42364d
No parameters
transferOwnership 0xf2fde38b
address newOwner
updateSupportedToken 0x09069443
address[] tokens
uint8[] decimals
uint256[] rates
withdrawEth 0xa0ef91df
No parameters
withdrawToken 0x9e281a98
address token
uint256 amount

Recent Transactions

No transactions found for this address