Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x223028738503838E89Fc5fd5b1A42F1d024d9600
Balance 0 ETH
Nonce 2
Code Size 16514 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

16514 bytes
0x6080604052600436106102e85760003560e01c8063906e9dd011610190578063ad56c13c116100dc578063d0d41fe111610095578063f2fde38b1161006f578063f2fde38b14610a75578063f4c6184a14610a95578063f84e426514610ab5578063ff0984ca14610ad557600080fd5b8063d0d41fe114610a05578063d936547e14610a25578063dd62ed3e14610a5557600080fd5b8063ad56c13c146108fd578063bbcc88b414610947578063bf78019b14610967578063c077ab4b14610987578063c0f306ef1461099c578063cc1776d3146109bc57600080fd5b8063a4e87e3511610149578063a8b9d24011610123578063a8b9d2401461087d578063a9059cbb1461089d578063aa5f7e26146108bd578063ac37d4a1146108dd57600080fd5b8063a4e87e351461080f578063a5ece94114610829578063a8aa1b311461084957600080fd5b8063906e9dd0146106ea57806391719aa61461070a57806395d89b411461078c5780639e8dcc3c146107a15780639e93ad8e146107c1578063a457c2d7146107ef57600080fd5b8063395093511161024f57806364a81f1d1161020857806370a08231116101e257806370a0823114610682578063715018a6146106a257806371778e7d146106b75780638da5cb5b146106cc57600080fd5b806364a81f1d146105c05780636843cd84146105e05780636d7adcad1461060057600080fd5b806339509351146104a95780633ad10ef6146104c957806343e716fe146104e95780634e71d92d146105095780634f7041a51461051e5780635cfb534e146105a057600080fd5b806318160ddd116102a157806318160ddd14610410578063214013ca1461042557806323b872dd1461043857806330bb4cff14610458578063313ce5671461046d57806331e79db01461048957600080fd5b80630106aaef146102f457806306fdde031461030b5780630758d92414610336578063095ea7b31461038257806314bb4edd146103b2578063167c12fe146103e057600080fd5b366102ef57005b600080fd5b34801561030057600080fd5b50610309610af5565b005b34801561031757600080fd5b50610320610c06565b60405161032d9190613956565b60405180910390f35b34801561034257600080fd5b5061036a7f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d81565b6040516001600160a01b03909116815260200161032d565b34801561038e57600080fd5b506103a261039d3660046139b9565b610c98565b604051901515815260200161032d565b3480156103be57600080fd5b506103d26103cd3660046139e5565b610cb2565b60405190815260200161032d565b3480156103ec57600080fd5b506103a26103fb3660046139e5565b60076020526000908152604090205460ff1681565b34801561041c57600080fd5b506002546103d2565b6103096104333660046139e5565b610e87565b34801561044457600080fd5b506103a2610453366004613a09565b6111d0565b34801561046457600080fd5b506103d26111f4565b34801561047957600080fd5b506040516012815260200161032d565b34801561049557600080fd5b506103096104a43660046139e5565b611267565b3480156104b557600080fd5b506103a26104c43660046139b9565b6112f4565b3480156104d557600080fd5b5060095461036a906001600160a01b031681565b3480156104f557600080fd5b50610309610504366004613a4a565b611316565b34801561051557600080fd5b50610309611461565b34801561052a57600080fd5b50600a546105679065ffffffffffff80821691600160301b8104821691600160601b8204811691600160901b8104821691600160c01b9091041685565b6040805165ffffffffffff968716815294861660208601529285169284019290925283166060830152909116608082015260a00161032d565b3480156105ac57600080fd5b506103096105bb366004613a71565b6114d9565b3480156105cc57600080fd5b506103096105db366004613a8e565b611516565b3480156105ec57600080fd5b506103d26105fb3660046139e5565b61163e565b34801561060c57600080fd5b50600d54600e54610647916001600160401b0380821692600160401b8304821692600160801b8104831692600160c01b909104169060ff1685565b604080516001600160401b0396871681529486166020860152928516928401929092529092166060820152901515608082015260a00161032d565b34801561068e57600080fd5b506103d261069d3660046139e5565b6116ae565b3480156106ae57600080fd5b506103096116c9565b3480156106c357600080fd5b506103d261173d565b3480156106d857600080fd5b506005546001600160a01b031661036a565b3480156106f657600080fd5b506103096107053660046139e5565b611787565b34801561071657600080fd5b50600f54610752906001600160601b0380821691600160601b810490911690600160c01b810465ffffffffffff1690600160f01b900460ff1684565b604080516001600160601b03958616815294909316602085015265ffffffffffff909116918301919091521515606082015260800161032d565b34801561079857600080fd5b50610320611818565b3480156107ad57600080fd5b506103096107bc366004613a8e565b611827565b3480156107cd57600080fd5b506107d761271081565b6040516001600160401b03909116815260200161032d565b3480156107fb57600080fd5b506103a261080a3660046139b9565b611938565b34801561081b57600080fd5b506010546103a29060ff1681565b34801561083557600080fd5b5060085461036a906001600160a01b031681565b34801561085557600080fd5b5061036a7f00000000000000000000000079d49c3231a824740649c7afa126b144d480322581565b34801561088957600080fd5b506103d26108983660046139e5565b6119b3565b3480156108a957600080fd5b506103a26108b83660046139b9565b6119e6565b3480156108c957600080fd5b506103096108d8366004613a4a565b6119f4565b3480156108e957600080fd5b506103096108f8366004613ad2565b611aaf565b34801561090957600080fd5b5061091d6109183660046139e5565b611c63565b604080516001600160a01b039095168552602085019390935291830152606082015260800161032d565b34801561095357600080fd5b506103d2610962366004613a4a565b611ce7565b34801561097357600080fd5b50610309610982366004613b26565b611eae565b34801561099357600080fd5b506103d2611ffc565b3480156109a857600080fd5b506103096109b73660046139e5565b6121a2565b3480156109c857600080fd5b50600b546105679065ffffffffffff80821691600160301b8104821691600160601b8204811691600160901b8104821691600160c01b9091041685565b348015610a1157600080fd5b50610309610a203660046139e5565b6121fe565b348015610a3157600080fd5b506103a2610a403660046139e5565b60066020526000908152604090205460ff1681565b348015610a6157600080fd5b506103d2610a70366004613b5f565b61228f565b348015610a8157600080fd5b50610309610a903660046139e5565b6122ba565b348015610aa157600080fd5b50610309610ab0366004613ad2565b6123a5565b348015610ac157600080fd5b50610309610ad0366004613b26565b612559565b348015610ae157600080fd5b50600c5461036a906001600160a01b031681565b6005546001600160a01b03163314610b285760405162461bcd60e51b8152600401610b1f90613b8d565b60405180910390fd5b6010805460ff191690556040805160808101825260008082526020820181905291810182905260608101919091526000610b6160025490565b6001600160601b03811680845260208401819052600f805460408087015160608801516001600160c01b03199093168517600160601b9095029490941766ffffffffffffff60c01b1916600160c01b65ffffffffffff9095169490940260ff60f01b191693909317600160f01b91151591909102179055519091507fa4ffae85e880608d5d4365c2b682786545d136145537788e7e0940dff9f0b98c90600090a15050565b606060038054610c1590613bc2565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4190613bc2565b8015610c8e5780601f10610c6357610100808354040283529160200191610c8e565b820191906000526020600020905b815481529060010190602001808311610c7157829003601f168201915b5050505050905090565b600033610ca681858561267c565b60019150505b92915050565b600080610cbe836119b3565b905080600003610cd15750600092915050565b6040805160028082526060820183526000926020830190803683370190505090507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600081518110610d2657610d26613c12565b60200260200101906001600160a01b031690816001600160a01b0316815250503081600181518110610d5a57610d5a613c12565b6001600160a01b03928316602091820292909201015260405163d06ca61f60e01b81526000917f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d169063d06ca61f90610db99086908690600401613c6c565b600060405180830381865afa158015610dd6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dfe9190810190613c85565b600a5490915061271090610e2290600160c01b900465ffffffffffff166032613d58565b65ffffffffffff1682600181518110610e3d57610e3d613c12565b6020026020010151610e4f9190613d7e565b610e599190613dab565b81600181518110610e6c57610e6c613c12565b6020026020010151610e7e9190613dbf565b95945050505050565b6005546001600160a01b03163314610eb15760405162461bcd60e51b8152600401610b1f90613b8d565b600047118015610ec957506000610ec7306116ae565b115b610ed257600080fd5b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b158015610f2d57600080fd5b505af1158015610f41573d6000803e3d6000fd5b5050505050610f79307f00000000000000000000000079d49c3231a824740649c7afa126b144d4803225610f74306116ae565b6127a0565b6040516370a0823160e01b81523060048201527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03169063a9059cbb907f00000000000000000000000079d49c3231a824740649c7afa126b144d48032259083906370a0823190602401602060405180830381865afa158015611007573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102b9190613dd2565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611076573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109a9190613deb565b506040516335313c2160e11b81526001600160a01b0382811660048301527f00000000000000000000000079d49c3231a824740649c7afa126b144d48032251690636a627842906024016020604051808303816000875af1158015611103573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111279190613dd2565b5043601355600f805460ff60f01b1916600160f01b179055604080516350d25bcd60e01b815290516001600160a01b037f0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b841916916350d25bcd91600482810192602092919082900301816000875af11580156111a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ca9190613dd2565b60155550565b6000336111de858285612945565b6111e98585856129bf565b506001949350505050565b600c54604080516342d359d760e11b815290516000926001600160a01b0316916385a6b3ae9160048083019260209291908290030181865afa15801561123e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112629190613dd2565b905090565b6005546001600160a01b031633146112915760405162461bcd60e51b8152600401610b1f90613b8d565b600c5460405163031e79db60e41b81526001600160a01b038381166004830152909116906331e79db0906024015b600060405180830381600087803b1580156112d957600080fd5b505af11580156112ed573d6000803e3d6000fd5b5050505050565b600033610ca6818585611307838361228f565b6113119190613e08565b61267c565b6005546001600160a01b031633146113405760405162461bcd60e51b8152600401610b1f90613b8d565b620186a061134d60025490565b611358906001613d7e565b6113629190613dab565b8110156113cf5760405162461bcd60e51b815260206004820152603560248201527f5377617020616d6f756e742063616e6e6f74206265206c6f776572207468616e60448201527410181718181892903a37ba30b61039bab838363c9760591b6064820152608401610b1f565b6103e86113db60025490565b6113e6906005613d7e565b6113f09190613dab565b81111561145c5760405162461bcd60e51b815260206004820152603460248201527f5377617020616d6f756e742063616e6e6f742062652068696768657220746861604482015273371018171a92903a37ba30b61039bab838363c9760611b6064820152608401610b1f565b601455565b600c5460405163bc4c4b3760e01b8152336004820152600060248201526001600160a01b039091169063bc4c4b37906044016020604051808303816000875af11580156114b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d69190613deb565b50565b6005546001600160a01b031633146115035760405162461bcd60e51b8152600401610b1f90613b8d565b6012805460ff1916911515919091179055565b6005546001600160a01b031633146115405760405162461bcd60e51b8152600401610b1f90613b8d565b61154c6012600a613eff565b6103e861155860025490565b611563906005613d7e565b61156d9190613dab565b6115779190613dab565b816001600160601b031610156115b95760405162461bcd60e51b8152602060048201526007602482015266546f6f206c6f7760c81b6044820152606401610b1f565b6115c56012600a613eff565b6115d8906001600160601b038316613d7e565b600f8054600160601b600160c01b031916600160601b6001600160601b0393841681029190911791829055604051910490911681527fde064515fae8f8bb6d8ff19d2c6ba704322def7494147d8a971266430ade0788906020015b60405180910390a150565b600c5460405163156dbbf560e31b81526001600160a01b038381166004830152600092169063ab6ddfa8906024015b602060405180830381865afa15801561168a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cac9190613dd2565b6001600160a01b031660009081526020819052604090205490565b6005546001600160a01b031633146116f35760405162461bcd60e51b8152600401610b1f90613b8d565b6005546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580546001600160a01b0319169055565b600c546040805163ad7a672f60e01b815290516000926001600160a01b03169163ad7a672f9160048083019260209291908290030181865afa15801561123e573d6000803e3d6000fd5b6005546001600160a01b031633146117b15760405162461bcd60e51b8152600401610b1f90613b8d565b6001600160a01b0381166117f65760405162461bcd60e51b815260206004820152600c60248201526b7a65726f206164647265737360a01b6044820152606401610b1f565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b606060048054610c1590613bc2565b6005546001600160a01b031633146118515760405162461bcd60e51b8152600401610b1f90613b8d565b61185d6012600a613eff565b6103e861186960025490565b611874906005613d7e565b61187e9190613dab565b6118889190613dab565b816001600160601b031610156118ca5760405162461bcd60e51b8152602060048201526007602482015266546f6f206c6f7760c81b6044820152606401610b1f565b6118d66012600a613eff565b6118e9906001600160601b038316613d7e565b600f80546001600160601b0319166001600160601b039290921691821790556040519081527f6710da7d4acedae09cb83751ae24c150719ef67dcbc1e02049f171d13c6b44e690602001611633565b60003381611946828661228f565b9050838110156119a65760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610b1f565b6111e9828686840361267c565b600c546040516302a2e74960e61b81526001600160a01b038381166004830152600092169063a8b9d2409060240161166d565b600033610ca68185856129bf565b600c5460405163dcb95ed960e01b81523360048201526000916001600160a01b03169063dcb95ed9906024016020604051808303816000875af1158015611a3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a639190613dd2565b90508015611a7a57611a76818333612b2d565b5050565b60405162461bcd60e51b815260206004820152600a6024820152694e6f207265776172647360b01b6044820152606401610b1f565b6005546001600160a01b03163314611ad95760405162461bcd60e51b8152600401610b1f90613b8d565b6040805160a0810182526000608082015265ffffffffffff868116825285811692820192909252838216602082015290821660608201528183611b1c8688613d58565b611b269190613d58565b611b309190613d58565b65ffffffffffff16608082018190526103e81015611b855760405162461bcd60e51b81526020600482015260126024820152714b656570207461782062656c6f772031302560701b6044820152606401610b1f565b608081015160405165ffffffffffff90911681527f7a758dc8e99047b028278b3e2ff1416d8493a7aacee7a5dc30b6bf93270eccce9060200160405180910390a18051600a805460208401516040850151606086015160809096015165ffffffffffff908116600160c01b0265ffffffffffff60c01b19978216600160901b0265ffffffffffff60901b19938316600160601b0293909316600160601b600160c01b0319948316600160301b026001600160601b03199096169290971691909117939093179190911693909317929092179290921617905550505050565b600c5460405163fbcbc0f160e01b81526001600160a01b038381166004830152600092839283928392169063fbcbc0f190602401608060405180830381865afa158015611cb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd89190613f0e565b93509350935093509193509193565b600081600003611cf957506000919050565b6040805160028082526060820183526000926020830190803683370190505090507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600081518110611d4e57611d4e613c12565b60200260200101906001600160a01b031690816001600160a01b0316815250503081600181518110611d8257611d82613c12565b6001600160a01b03928316602091820292909201015260405163d06ca61f60e01b81526000917f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d169063d06ca61f90611de19087908690600401613c6c565b600060405180830381865afa158015611dfe573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611e269190810190613c85565b600a5490915061271090611e4a90600160c01b900465ffffffffffff166032613d58565b65ffffffffffff1682600181518110611e6557611e65613c12565b6020026020010151611e779190613d7e565b611e819190613dab565b81600181518110611e9457611e94613c12565b6020026020010151611ea69190613dbf565b949350505050565b6005546001600160a01b03163314611ed85760405162461bcd60e51b8152600401610b1f90613b8d565b6001600160a01b038216611f1d5760405162461bcd60e51b815260206004820152600c60248201526b5a65726f204164647265737360a01b6044820152606401610b1f565b80611f98577f00000000000000000000000079d49c3231a824740649c7afa126b144d48032256001600160a01b0316826001600160a01b031603611f985760405162461bcd60e51b815260206004820152601260248201527121b0b73737ba103932b6b7bb32903830b4b960711b6044820152606401610b1f565b6001600160a01b038216600081815260076020908152604091829020805460ff19168515159081179091558251938452908301527f0712a8411c7892e205c3d35c5d2beabe76bb0b484bec43945f2024cd28eaae8d91015b60405180910390a15050565b60006305f5e100670de0b6b3a764000061201761dead6116ae565b6002546120249190613dbf565b61204d7f00000000000000000000000079d49c3231a824740649c7afa126b144d48032256116ae565b6015547f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d29190613f4d565b6040516370a0823160e01b81526001600160a01b037f00000000000000000000000079d49c3231a824740649c7afa126b144d48032258116600483015291909116906370a0823190602401602060405180830381865afa15801561213a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061215e9190613dd2565b61217090670de0b6b3a7640000613d7e565b61217a9190613d7e565b6121849190613dab565b61218e9190613d7e565b6121989190613dab565b6112629190613dab565b6005546001600160a01b031633146121cc5760405162461bcd60e51b8152600401610b1f90613b8d565b600c5460405163c0f306ef60e01b81526001600160a01b0383811660048301529091169063c0f306ef906024016112bf565b6005546001600160a01b031633146122285760405162461bcd60e51b8152600401610b1f90613b8d565b6001600160a01b03811661226d5760405162461bcd60e51b815260206004820152600c60248201526b7a65726f206164647265737360a01b6044820152606401610b1f565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6005546001600160a01b031633146122e45760405162461bcd60e51b8152600401610b1f90613b8d565b6001600160a01b0381166123495760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b1f565b6005546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b031633146123cf5760405162461bcd60e51b8152600401610b1f90613b8d565b6040805160a0810182526000608082015265ffffffffffff8681168252858116928201929092528382166020820152908216606082015281836124128688613d58565b61241c9190613d58565b6124269190613d58565b65ffffffffffff16608082018190526103e8101561247b5760405162461bcd60e51b81526020600482015260126024820152714b656570207461782062656c6f772031302560701b6044820152606401610b1f565b608081015160405165ffffffffffff90911681527fa6255338a5f732d64ceba7f4c18182567f9d1067eb984b46d478b37d72a52d119060200160405180910390a18051600b805460208401516040850151606086015160809096015165ffffffffffff908116600160c01b0265ffffffffffff60c01b19978216600160901b0265ffffffffffff60901b19938316600160601b0293909316600160601b600160c01b0319948316600160301b026001600160601b03199096169290971691909117939093179190911693909317929092179290921617905550505050565b6005546001600160a01b031633146125835760405162461bcd60e51b8152600401610b1f90613b8d565b6001600160a01b0382166125c85760405162461bcd60e51b815260206004820152600c60248201526b5a65726f204164647265737360a01b6044820152606401610b1f565b306001600160a01b038316036126205760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f7420756e6578636c7564656420636f6e74726163740000000000006044820152606401610b1f565b6001600160a01b038216600081815260066020908152604091829020805460ff19168515159081179091558251938452908301527fc4eea32423e96d678d53f47ddd9b7a5103eea02606d7daa81c77038c54dc8edb9101611ff0565b6001600160a01b0383166126de5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610b1f565b6001600160a01b03821661273f5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610b1f565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166128045760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610b1f565b6001600160a01b0382166128665760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610b1f565b6001600160a01b038316600090815260208190526040902054818110156128de5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610b1f565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350505050565b6000612951848461228f565b905060001981146129b957818110156129ac5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610b1f565b6129b9848484840361267c565b50505050565b6001600160a01b03831660009081526006602052604090205460ff16158015612a0157506001600160a01b03821660009081526006602052604090205460ff16155b15612a2957612a11838383612c52565b612a1c83838361305d565b612a269082613dbf565b90505b612a348383836127a0565b600c546001600160a01b031663e30443bc83612a4f816116ae565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612a9557600080fd5b505af1158015612aa9573d6000803e3d6000fd5b5050600c546001600160a01b0316915063e30443bc905084612aca816116ae565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612b1057600080fd5b505af1158015612b24573d6000803e3d6000fd5b50505050505050565b6040805160028082526060820183526000926020830190803683370190505090507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600081518110612b8257612b82613c12565b60200260200101906001600160a01b031690816001600160a01b0316815250503081600181518110612bb657612bb6613c12565b6001600160a01b03928316602091820292909201015260405163b6f9de9560e01b81527f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d9091169063b6f9de95908690612c1a908790869088904290600401613f6a565b6000604051808303818588803b158015612c3357600080fd5b505af1158015612c47573d6000803e3d6000fd5b505050505050505050565b60105460ff1615612f9b576001600160a01b03821660009081526007602052604081205460ff1690612c83846116ae565b60408051608081018252600f546001600160601b038082168352600160601b8204166020830152600160c01b810465ffffffffffff1692820192909252600160f01b90910460ff16151560608201529091507f00000000000000000000000079d49c3231a824740649c7afa126b144d48032256001600160a01b03908116908716148015612d0f575082155b15612e9c5780516001600160601b0316841115612d585760405162461bcd60e51b815260206004820152600760248201526626b0bc102a3c3760c91b6044820152606401610b1f565b60208101516001600160601b0316612d708386613e08565b1115612dab5760405162461bcd60e51b815260206004820152600a60248201526913585e0815d85b1b195d60b21b6044820152606401610b1f565b806060015115612e9757601354612dc3906004613e08565b4310612e3b57600060608201528051600f80546020840151604085015160ff60f01b1965ffffffffffff909116600160c01b021666ffffffffffffff60c01b196001600160601b03928316600160601b026001600160c01b031990941692909516919091179190911792909216919091179055612f97565b806040015165ffffffffffff163a1115612e975760405162461bcd60e51b815260206004820152601860248201527f4761732070726963652065786365656473206c696d69742e00000000000000006044820152606401610b1f565b612f97565b7f00000000000000000000000079d49c3231a824740649c7afa126b144d48032256001600160a01b0316856001600160a01b0316148015612ef657506001600160a01b03861660009081526007602052604090205460ff16155b15612f3f5780516001600160601b0316841115612e975760405162461bcd60e51b815260206004820152600760248201526626b0bc102a3c3760c91b6044820152606401610b1f565b82612f975760208101516001600160601b0316612f5c8386613e08565b1115612f975760405162461bcd60e51b815260206004820152600a60248201526913585e0815d85b1b195d60b21b6044820152606401610b1f565b5050505b60125460ff1615613031577f00000000000000000000000079d49c3231a824740649c7afa126b144d48032256001600160a01b0316826001600160a01b031603613036576001600160a01b03831660009081526011602052604090205443116130315760405162461bcd60e51b815260206004820152600860248201526720b73a349026a2ab60c11b6044820152606401610b1f565b505050565b506001600160a01b0316600090815260116020526040808220439081905532835291205550565b600060145461306b306116ae565b101580156130ab57507f00000000000000000000000079d49c3231a824740649c7afa126b144d48032256001600160a01b0316846001600160a01b031614155b156130b8576130b861349c565b6040805160a08101825260008082526020820181905291810182905260608101829052608081018290527f00000000000000000000000079d49c3231a824740649c7afa126b144d48032256001600160a01b0316856001600160a01b03160361317557506040805160a081018252600b5465ffffffffffff8082168352600160301b820481166020840152600160601b8204811693830193909352600160901b810483166060830152600160c01b90049091166080820152613204565b7f00000000000000000000000079d49c3231a824740649c7afa126b144d48032256001600160a01b0316866001600160a01b03160361320457506040805160a081018252600a5465ffffffffffff8082168352600160301b820481166020840152600160601b8204811693830193909352600160901b810483166060830152600160c01b900490911660808201525b608081015165ffffffffffff161561348a576040805160a081018252600d546001600160401b038082168352600160401b820481166020840152600160801b8204811693830193909352600160c01b90049091166060820152600e5460ff161515608080830191909152820151612710906132879065ffffffffffff1687613d7e565b6132919190613dab565b9250633b9aca00826080015165ffffffffffff16836040015165ffffffffffff16856132bd9190613f9f565b6132c79190613fca565b6132d19190613fca565b816020018181516132e29190613ff0565b6001600160401b031690525060808201518251633b9aca009165ffffffffffff90811691613311911686613f9f565b61331b9190613fca565b6133259190613fca565b81518290613334908390613ff0565b6001600160401b031690525060808201516020830151633b9aca009165ffffffffffff90811691613366911686613f9f565b6133709190613fca565b61337a9190613fca565b8160400181815161338b9190613ff0565b6001600160401b031690525060808201516060830151633b9aca009165ffffffffffff908116916133bd911686613f9f565b6133c79190613fca565b6133d19190613fca565b816060018181516133e29190613ff0565b6001600160401b039081169091528251600d80546020860151604087015160608801518616600160c01b026001600160c01b03918716600160801b02919091166001600160801b03928716600160401b026fffffffffffffffffffffffffffffffff199094169590961694909417919091178116939093179190911790556080830151600e805491151560ff1990921691909117905561348891508890309086166127a0565b505b506001600160801b0316949350505050565b60006134a7306116ae565b6040805160a081018252600d546001600160401b03808216808452600160401b8304821660208501819052600160801b84048316958501869052600160c01b90930490911660608401819052600e5460ff16151560808501529495509193600093909290916135169190613ff0565b6135209190613ff0565b61352a9190613ff0565b6001600160401b03169050821580613540575080155b1561354a57505050565b6014805461355791613d7e565b83111561356e576014805461356b91613d7e565b92505b60208201516001600160401b03161561366a5760008183602001516001600160401b03168561359d9190613d7e565b6135a79190613dab565b90506135d4307f00000000000000000000000079d49c3231a824740649c7afa126b144d4803225836127a0565b7f00000000000000000000000079d49c3231a824740649c7afa126b144d48032256001600160a01b031663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561362f57600080fd5b505af1925050508015613640575060015b5061364b8185613dbf565b935082602001516001600160401b0316826136669190613dbf565b9150505b82156137fc5761367983613832565b604082015147906000906001600160401b03161561370b5760095460408501516001600160a01b039091169084906136ba906001600160401b031685613d7e565b6136c49190613dab565b604051600081818185875af1925050503d8060008114613700576040519150601f19603f3d011682016040523d82523d6000602084013e613705565b606091505b50909150505b60608401516001600160401b03161561379857600c5460608501516001600160a01b03909116908490613747906001600160401b031685613d7e565b6137519190613dab565b604051600081818185875af1925050503d806000811461378d576040519150601f19603f3d011682016040523d82523d6000602084013e613792565b606091505b50909150505b47915081156137f9576008546040516001600160a01b03909116908390600081818185875af1925050503d80600081146137ee576040519150601f19603f3d011682016040523d82523d6000602084013e6137f3565b606091505b50909150505b50505b506000602082018190528082526040820181905260608201819052600d5560800151600e805460ff191691151591909117905550565b604080516002808252606082018352600092602083019080368337019050509050308160008151811061386757613867613c12565b60200260200101906001600160a01b031690816001600160a01b0316815250507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2816001815181106138bb576138bb613c12565b6001600160a01b03928316602091820292909201015260405163791ac94760e01b81527f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d9091169063791ac94790613920908590600090869030904290600401614010565b600060405180830381600087803b15801561393a57600080fd5b505af115801561394e573d6000803e3d6000fd5b505050505050565b600060208083528351808285015260005b8181101561398357858101830151858201604001528201613967565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b03811681146114d657600080fd5b600080604083850312156139cc57600080fd5b82356139d7816139a4565b946020939093013593505050565b6000602082840312156139f757600080fd5b8135613a02816139a4565b9392505050565b600080600060608486031215613a1e57600080fd5b8335613a29816139a4565b92506020840135613a39816139a4565b929592945050506040919091013590565b600060208284031215613a5c57600080fd5b5035919050565b80151581146114d657600080fd5b600060208284031215613a8357600080fd5b8135613a0281613a63565b600060208284031215613aa057600080fd5b81356001600160601b0381168114613a0257600080fd5b803565ffffffffffff81168114613acd57600080fd5b919050565b60008060008060808587031215613ae857600080fd5b613af185613ab7565b9350613aff60208601613ab7565b9250613b0d60408601613ab7565b9150613b1b60608601613ab7565b905092959194509250565b60008060408385031215613b3957600080fd5b8235613b44816139a4565b91506020830135613b5481613a63565b809150509250929050565b60008060408385031215613b7257600080fd5b8235613b7d816139a4565b91506020830135613b54816139a4565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600181811c90821680613bd657607f821691505b602082108103613bf657634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015613c615781516001600160a01b031687529582019590820190600101613c3c565b509495945050505050565b828152604060208201526000611ea66040830184613c28565b60006020808385031215613c9857600080fd5b82516001600160401b0380821115613caf57600080fd5b818501915085601f830112613cc357600080fd5b815181811115613cd557613cd5613bfc565b8060051b604051601f19603f83011681018181108582111715613cfa57613cfa613bfc565b604052918252848201925083810185019188831115613d1857600080fd5b938501935b82851015613d3657845184529385019392850192613d1d565b98975050505050505050565b634e487b7160e01b600052601160045260246000fd5b65ffffffffffff818116838216019080821115613d7757613d77613d42565b5092915050565b8082028115828204841417610cac57610cac613d42565b634e487b7160e01b600052601260045260246000fd5b600082613dba57613dba613d95565b500490565b81810381811115610cac57610cac613d42565b600060208284031215613de457600080fd5b5051919050565b600060208284031215613dfd57600080fd5b8151613a0281613a63565b80820180821115610cac57610cac613d42565b600181815b80851115613e56578160001904821115613e3c57613e3c613d42565b80851615613e4957918102915b93841c9390800290613e20565b509250929050565b600082613e6d57506001610cac565b81613e7a57506000610cac565b8160018114613e905760028114613e9a57613eb6565b6001915050610cac565b60ff841115613eab57613eab613d42565b50506001821b610cac565b5060208310610133831016604e8410600b8410161715613ed9575081810a610cac565b613ee38383613e1b565b8060001904821115613ef757613ef7613d42565b029392505050565b6000613a0260ff841683613e5e565b60008060008060808587031215613f2457600080fd5b8451613f2f816139a4565b60208601516040870151606090970151919890975090945092505050565b600060208284031215613f5f57600080fd5b8151613a02816139a4565b848152608060208201526000613f836080830186613c28565b6001600160a01b03949094166040830152506060015292915050565b6001600160801b03818116838216028082169190828114613fc257613fc2613d42565b505092915050565b60006001600160801b0380841680613fe457613fe4613d95565b92169190910492915050565b6001600160401b03818116838216019080821115613d7757613d77613d42565b85815284602082015260a06040820152600061402f60a0830186613c28565b6001600160a01b039490941660608301525060800152939250505056fea26469706673582212200ec730051cc1281b273660cf33bc1f5c2960f51890997fcf8f64ac345a30df1164736f6c63430008130033

Verified Source Code Full Match

Compiler: v0.8.19+commit.7dd6d404 EVM: paris Optimization: Yes (200 runs)
Token.sol 1368 lines
pragma solidity 0.8.19;


// SPDX-License-Identifier: MIT

import "./StructLibrary.sol";
import "./Context.sol";
import "./IERC20.sol";
import "./DEXInterfaces.sol";

interface IERC20Metadata is IERC20{
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(address from, address to, uint256 amount) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += amount;
        }

        emit Transfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _totalSupply += amount;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    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");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }
}

contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    function owner() public view returns (address) {
        return _owner;
    }

    modifier onlyOwner() {
        require(_owner == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    function renounceOwnership() external virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

library Address {
    function isContract(address account) internal view returns (bool) {
        return account.code.length > 0;
    }

    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");
    }

    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    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);
        }
    }
}

library SafeERC20 {
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }

    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }
}

library SafeMath {
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, 'SafeMath: addition overflow');

        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, 'SafeMath: subtraction overflow');
    }

    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // 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 0;
        }

        uint256 c = a * b;
        require(c / a == b, 'SafeMath: multiplication overflow');

        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, 'SafeMath: division by zero');
    }

    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, 'SafeMath: modulo by zero');
    }

    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }

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

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

library SafeMathInt {
    int256 private constant MIN_INT256 = int256(1) << 255;
    int256 private constant MAX_INT256 = ~(int256(1) << 255);

    /**
     * @dev Multiplies two int256 variables and fails on overflow.
     */
    function mul(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a * b;

        // Detect overflow when multiplying MIN_INT256 with -1
        require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
        require((b == 0) || (c / b == a));
        return c;
    }

    /**
     * @dev Division of two int256 variables and fails on overflow.
     */
    function div(int256 a, int256 b) internal pure returns (int256) {
        // Prevent overflow when dividing MIN_INT256 by -1
        require(b != -1 || a != MIN_INT256);

        // Solidity already throws when dividing by 0.
        return a / b;
    }

    /**
     * @dev Subtracts two int256 variables and fails on overflow.
     */
    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a));
        return c;
    }

    /**
     * @dev Adds two int256 variables and fails on overflow.
     */
    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a));
        return c;
    }

    /**
     * @dev Converts to absolute value, and fails on overflow.
     */
    function abs(int256 a) internal pure returns (int256) {
        require(a != MIN_INT256);
        return a < 0 ? -a : a;
    }


    function toUint256Safe(int256 a) internal pure returns (uint256) {
        require(a >= 0);
        return uint256(a);
    }
}

library SafeMathUint {
  function toInt256Safe(uint256 a) internal pure returns (int256) {
    int256 b = int256(a);
    require(b >= 0);
    return b;
  }
}

interface DividendPayingContractOptionalInterface {
  function withdrawableDividendOf(address _owner) external view returns(uint256);
  function withdrawnDividendOf(address _owner) external view returns(uint256);
  function accumulativeDividendOf(address _owner) external view returns(uint256);
}

interface DividendPayingContractInterface {
  function dividendOf(address _owner) external view returns(uint256);
  function distributeDividends() external payable;
  function withdrawDividend() external;
  event DividendsDistributed(
    address indexed from,
    uint256 weiAmount
  );
  event DividendWithdrawn(
    address indexed to,
    uint256 weiAmount
  );
}

contract DividendPayingContract is DividendPayingContractInterface, DividendPayingContractOptionalInterface, Ownable {
    using SafeMath for uint256;
    using SafeMathUint for uint256;
    using SafeMathInt for int256;

    uint256 constant internal magnitude = 2**128;

    uint256 internal magnifiedDividendPerShare;
                                                                            
    mapping(address => int256) internal magnifiedDividendCorrections;
    mapping(address => uint256) internal withdrawnDividends;
    
    mapping (address => uint256) public holderBalance;
    uint256 public totalBalance;

    uint256 public totalDividendsDistributed;

    receive() external payable {
        distributeDividends();
    }

    function distributeDividends() public override payable {
        if(totalBalance > 0 && msg.value > 0){
            magnifiedDividendPerShare = magnifiedDividendPerShare.add(
                (msg.value).mul(magnitude) / totalBalance
            );
            emit DividendsDistributed(msg.sender, msg.value);

            totalDividendsDistributed = totalDividendsDistributed.add(msg.value);
        }
    }

    function withdrawDividend() external virtual override {
        _withdrawDividendOfUser(payable(msg.sender));
    }

    function _withdrawDividendOfUser(address payable user) internal returns (uint256) {
        uint256 _withdrawableDividend = withdrawableDividendOf(user);
        if (_withdrawableDividend > 0) {
        withdrawnDividends[user] = withdrawnDividends[user].add(_withdrawableDividend);

        emit DividendWithdrawn(user, _withdrawableDividend);
        (bool success,) = user.call{value: _withdrawableDividend}("");

        if(!success) {
            withdrawnDividends[user] = withdrawnDividends[user].sub(_withdrawableDividend);
            return 0;
        }

        return _withdrawableDividend;
        }

        return 0;
    }

    function withdrawDividendOfUserForCompound(address payable user) external onlyOwner returns (uint256 _withdrawableDividend) {
        _withdrawableDividend = withdrawableDividendOf(user);
        if (_withdrawableDividend > 0) {
            withdrawnDividends[user] = withdrawnDividends[user] + _withdrawableDividend;
            emit DividendWithdrawn(user, _withdrawableDividend);
        }
        (bool success,) = owner().call{value: _withdrawableDividend}("");
        if(!success) {
            withdrawnDividends[user] = withdrawnDividends[user].sub(_withdrawableDividend);
            return 0;
        }
    }

    function dividendOf(address _owner) external view override returns(uint256) {
        return withdrawableDividendOf(_owner);
    }

    function withdrawableDividendOf(address _owner) public view override returns(uint256) {
        return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]);
    }

    function withdrawnDividendOf(address _owner) external view override returns(uint256) {
        return withdrawnDividends[_owner];
    }

    function accumulativeDividendOf(address _owner) public view override returns(uint256) {
        return magnifiedDividendPerShare.mul(holderBalance[_owner]).toInt256Safe()
        .add(magnifiedDividendCorrections[_owner]).toUint256Safe() / magnitude;
    }

    function _increase(address account, uint256 value) internal {
        magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
        .sub( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
    }

    function _reduce(address account, uint256 value) internal {
        magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
        .add( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
    }

    function _setBalance(address account, uint256 newBalance) internal {
        uint256 currentBalance = holderBalance[account];
        holderBalance[account] = newBalance;
        if(newBalance > currentBalance) {
        uint256 increaseAmount = newBalance.sub(currentBalance);
        _increase(account, increaseAmount);
        totalBalance += increaseAmount;
        } else if(newBalance < currentBalance) {
        uint256 reduceAmount = currentBalance.sub(newBalance);
        _reduce(account, reduceAmount);
        totalBalance -= reduceAmount;
        }
    }
}


contract RevShare is DividendPayingContract {

    event Claim(address indexed account, uint256 amount, bool indexed automatic);

    mapping (address => bool) public excludedFromDividends;

    constructor() {}

    function getAccount(address _account)
        public view returns (
            address account,
            uint256 withdrawableDividends,
            uint256 totalDividends,
            uint256 balance) {
        account = _account;

        withdrawableDividends = withdrawableDividendOf(account);
        totalDividends = accumulativeDividendOf(account);

        balance = holderBalance[account];
    }
    function setBalance(address payable account, uint256 newBalance) external onlyOwner {
        if(excludedFromDividends[account]) {
    		return;
    	}

        _setBalance(account, newBalance);

    	processAccount(account, true);
    }
    
    function processAccount(address payable account, bool automatic) public onlyOwner returns (bool) {
        uint256 amount = _withdrawDividendOfUser(account);

    	if(amount > 0) {
            emit Claim(account, amount, automatic);
    		return true;
    	}

    	return false;
    }

    function getTotalDividendsDistributed() external view returns (uint256) {
        return totalDividendsDistributed;
    }

	function dividendTokenBalanceOf(address account) public view returns (uint256) {
		return holderBalance[account];
	}

    function getNumberOfDividends() external view returns(uint256) {
        return totalBalance;
    }

    function excludeFromDividends(address account) external onlyOwner {
    	excludedFromDividends[account] = true;

    	_setBalance(account, 0);
    }

    function includeInDividends(address account) external onlyOwner {
    	require(excludedFromDividends[account]);
    	excludedFromDividends[account] = false;
        _setBalance(account, IERC20(owner()).balanceOf(account)); // sets balance back to token balance
    }
}

interface IWETH {
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    function withdraw(uint) external;
}

interface IPriceFeed {
    function latestAnswer() external returns (int256);
}

contract DGNS is ERC20, Ownable {

    mapping (address => bool) public whitelisted;
    mapping (address => bool) public excludedFromTxLimits;

    address public marketingAddress;
    address public devAddress;

    Tax public buyTax;
    Tax public sellTax;

    RevShare public revenueShare;

    TokenDistributionForTax public tokensForTax;

    TxLimits public txnLimits;
    bool public txnLimitsActive = true;

    mapping(address => uint256) private _holderLastTransferBlock; // MEV protection
    bool private antiSandwichEnabled = true;
    uint256 private launchBlock;

    uint256 private swapTokensAtAmount;

    address public immutable pair;
    IDexRouter public immutable dexRouter;
    IWETH private immutable WETH;

    IPriceFeed internal immutable priceFeed;
    uint256 private latestEthPrice = 0;

    uint64 public constant FEE_DIVISOR = 10000;

    // structs

    struct TxLimits {
        uint96 transactionLimit;
        uint96 walletLimit;
        uint48 gasLimit;
        bool gasLimitActive;
    }

    struct Tax {
        uint48 mktingTax;
        uint48 devTax;
        uint48 lpTax;
        uint48 revenueShareTax;
        uint48 totalTax;
    }

    struct TokenDistributionForTax {
        uint64 tokensForMkting;
        uint64 tokensForLP;
        uint64 tokensForDev;
        uint64 tokensForRevShare;
        bool gasSaver;
    }

    // events

    event UpdatedTransactionLimit(uint newMax);
    event UpdatedWalletLimit(uint newMax);
    event SetExcludedFromFees(address _address, bool _isExcluded);
    event SetExcludedFromLimits(address _address, bool _isExcluded);
    event RemovedLimits();
    event BuyTaxUpdated(uint newAmount);
    event SellTaxUpdated(uint newAmount);

    // constructor

    constructor(StructLibrary.Params memory params)
        ERC20(params.name, params.symbol)
    {   
        _mint(address(this), params.totalSupply * 1e18 * params.liquidityPercentage / 10000);
        uint256 leftoverTokens = (params.totalSupply * 1e18) - balanceOf(address(this));
        if(leftoverTokens > 0){
            _mint(msg.sender, leftoverTokens);
        }

        address _v2Router;
        address _priceFeed;

        if(block.chainid == 1){
            _v2Router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; // ETH: Uniswap V2
            _priceFeed = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419;
        } else if(block.chainid == 5){
            _v2Router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; // Goerli ETH: Uniswap V2
            _priceFeed = 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e;
        } else if(block.chainid == 56){
            _v2Router = 0x10ED43C718714eb63d5aA57B78B54704E256024E; // BNB Chain: PCS V2
            _priceFeed = 0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE;
        } else if(block.chainid == 97){
            _v2Router = 0xD99D1c33F9fC3444f8101754aBC46c52416550D1; // BNB Chain Testnet: PCS V2
            _priceFeed = 0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526;
        } else if(block.chainid == 42161){
            _v2Router = 0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506; // Arbitrum: SushiSwap
            _priceFeed = 0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612;
        } else {
            revert("Chain not configured");
        }

        priceFeed = IPriceFeed(_priceFeed);
        require(priceFeed.latestAnswer() > 0, "wrong price feed");

        revenueShare = new RevShare();

        dexRouter = IDexRouter(_v2Router);

        txnLimits.transactionLimit = uint96(totalSupply() * params.transactionLimit / 10000);
        txnLimits.walletLimit = uint96(totalSupply() * params.walletLimit / 10000);
        txnLimits.gasLimit = params.gasLimit * 1 gwei;
        swapTokensAtAmount = totalSupply() * 25 / 100000;

        marketingAddress = params.marketingAddress; // update
        devAddress = params.devAddress; // update

        buyTax.mktingTax = params.marketingTaxBuy;
        buyTax.lpTax = params.lpTaxBuy;
        buyTax.devTax = params.devTaxBuy;
        buyTax.revenueShareTax = params.revenueShareTaxBuy;
        buyTax.totalTax = buyTax.mktingTax + buyTax.lpTax + buyTax.devTax + buyTax.revenueShareTax;

        sellTax.mktingTax = params.marketingTaxSell;
        sellTax.lpTax = params.lpTaxSell;
        sellTax.devTax = params.devTaxSell;
        sellTax.revenueShareTax = params.revenueShareTaxSell;
        sellTax.totalTax = sellTax.mktingTax + sellTax.lpTax + sellTax.devTax + buyTax.revenueShareTax;

        tokensForTax.gasSaver = true;

        WETH = IWETH(dexRouter.WETH());
        pair = IDexFactory(dexRouter.factory()).createPair(address(this), address(WETH));

        excludedFromTxLimits[pair] = true;
        excludedFromTxLimits[msg.sender] = true;
        excludedFromTxLimits[address(this)] = true;
        excludedFromTxLimits[_v2Router] = true;

        whitelisted[msg.sender] = true;
        whitelisted[address(this)] = true;
        whitelisted[address(0xdead)] = true;
        whitelisted[_v2Router] = true;

        revenueShare.excludeFromDividends(address(this));
        revenueShare.excludeFromDividends(address(pair));
        revenueShare.excludeFromDividends(address(0xdead));
 
        _approve(address(this), address(dexRouter), type(uint256).max);
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        
        if(!whitelisted[from] && !whitelisted[to]){
            handleLimits(from, to, amount);
            amount -= handleFee(from, to, amount);
        }

        super._transfer(from,to,amount);

        revenueShare.setBalance(payable(to), balanceOf(to));
        revenueShare.setBalance(payable(from), balanceOf(from));
    }

    function handleLimits(address from, address to, uint256 amount) internal {
        if(txnLimitsActive){
            bool exFromLimitsTo = excludedFromTxLimits[to];
            uint256 balanceOfTo = balanceOf(to);
            TxLimits memory _txnLimits = txnLimits;
            // buy
            if (from == pair && !exFromLimitsTo) {
                require(amount <= _txnLimits.transactionLimit, "Max Txn");
                require(amount + balanceOfTo <= _txnLimits.walletLimit, "Max Wallet");
                if(_txnLimits.gasLimitActive){
                    if(block.number >= launchBlock + 4){
                        _txnLimits.gasLimitActive = false;
                        txnLimits = _txnLimits;
                    } else {
                        require(tx.gasprice <= _txnLimits.gasLimit, "Gas price exceeds limit.");
                    }
                }
            } 
            // sell
            else if (to == pair && !excludedFromTxLimits[from]) {
                require(amount <= _txnLimits.transactionLimit, "Max Txn");
            }
            else if(!exFromLimitsTo) {
                require(amount + balanceOfTo <= _txnLimits.walletLimit, "Max Wallet");
            }

            
        }

        if (antiSandwichEnabled){
            if(to == pair){
                require(_holderLastTransferBlock[from] < block.number, "Anti MEV");
            } else {
                _holderLastTransferBlock[to] = block.number;
                _holderLastTransferBlock[tx.origin] = block.number;
            }
        }
    }

    function handleFee(address from, address to, uint256 amount) internal returns (uint256){

        if(balanceOf(address(this)) >= swapTokensAtAmount && from != pair) {
            swapBack();
        }
        
        uint128 tax = 0;

        Tax memory taxes;

        if (to == pair){
            taxes = sellTax;
        } else if (from == pair){
            taxes = buyTax;
        }

        if(taxes.totalTax > 0){
            TokenDistributionForTax memory tokensForTaxUpdate = tokensForTax;
            tax = uint128(amount * taxes.totalTax / FEE_DIVISOR);
            tokensForTaxUpdate.tokensForLP += uint64(tax * taxes.lpTax / taxes.totalTax / 1e9);
            tokensForTaxUpdate.tokensForMkting += uint64(tax * taxes.mktingTax / taxes.totalTax / 1e9);
            tokensForTaxUpdate.tokensForDev += uint64(tax * taxes.devTax / taxes.totalTax / 1e9);
            tokensForTaxUpdate.tokensForRevShare += uint64(tax * taxes.revenueShareTax / taxes.totalTax / 1e9);
            tokensForTax = tokensForTaxUpdate;
            super._transfer(from, address(this), tax);
        }
        
        return tax;
    }

    function swapTokensForETH(uint256 tokenAmount) private {

        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = address(WETH);

        dexRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0,
            path,
            address(this),
            block.timestamp
        );
    }

    function swapBack() private {

        uint256 contractBalance = balanceOf(address(this));
        TokenDistributionForTax memory tokensForTaxMem = tokensForTax;
        uint256 totalTokensToSwap = tokensForTaxMem.tokensForLP + tokensForTaxMem.tokensForMkting + tokensForTaxMem.tokensForDev + tokensForTaxMem.tokensForRevShare;
        
        if(contractBalance == 0 || totalTokensToSwap == 0) {return;}

        if(contractBalance > swapTokensAtAmount * 20){
            contractBalance = swapTokensAtAmount * 20;
        }

        if(tokensForTaxMem.tokensForLP > 0){
            uint256 lpTokens = contractBalance * tokensForTaxMem.tokensForLP / totalTokensToSwap;
            super._transfer(address(this), pair, lpTokens);
            try ILpPair(pair).sync(){} catch {}
            contractBalance -= lpTokens;
            totalTokensToSwap -= tokensForTaxMem.tokensForLP;
        }

        if(contractBalance > 0){

            swapTokensForETH(contractBalance);
            
            uint256 ethBalance = address(this).balance;

            bool success;

            if(tokensForTaxMem.tokensForDev > 0){
                (success,) = devAddress.call{value: ethBalance * tokensForTaxMem.tokensForDev / totalTokensToSwap}("");  
            }

            if(tokensForTaxMem.tokensForRevShare > 0){
                (success,) = address(revenueShare).call{value: ethBalance * tokensForTaxMem.tokensForRevShare/ totalTokensToSwap}("");  
            }

            ethBalance = address(this).balance;

            if(ethBalance > 0){
                (success,) = marketingAddress.call{value: ethBalance}("");  
            }
        }

        tokensForTaxMem.tokensForLP = 0;
        tokensForTaxMem.tokensForMkting = 0;
        tokensForTaxMem.tokensForDev = 0;
        tokensForTaxMem.tokensForRevShare = 0;

        tokensForTax = tokensForTaxMem;
    }

    // owner functions
    function changeExcludedFromFees(address _address, bool _isExcluded) external onlyOwner {
        require(_address != address(0), "Zero Address");
        require(_address != address(this), "Cannot unexcluded contract");
        whitelisted[_address] = _isExcluded;
        emit SetExcludedFromFees(_address, _isExcluded);
    }

    function setExcludedFromLimit(address _address, bool _isExcluded) external onlyOwner {
        require(_address != address(0), "Zero Address");
        if(!_isExcluded){
            require(_address != pair, "Cannot remove pair");
        }
        excludedFromTxLimits[_address] = _isExcluded;
        emit SetExcludedFromLimits(_address, _isExcluded);
    }

    function changeTransactionMax(uint96 newNumInTokens) external onlyOwner {
        require(newNumInTokens >= (totalSupply() * 5 / 1000)/(10**decimals()), "Too low");
        txnLimits.transactionLimit = uint96(newNumInTokens * (10**decimals()));
        emit UpdatedTransactionLimit(txnLimits.transactionLimit);
    }

    function updateWalletLimit(uint96 newNumInTokens) external onlyOwner {
        require(newNumInTokens >= (totalSupply() * 5 / 1000)/(10**decimals()), "Too low");
        txnLimits.walletLimit = uint96(newNumInTokens * (10**decimals()));
        emit UpdatedWalletLimit(txnLimits.walletLimit);
    }

    function setSwapTokensAmount(uint256 newAmount) external onlyOwner {
        require(newAmount >= (totalSupply() * 1) / 100000, "Swap amount cannot be lower than 0.001% total supply.");
        require(newAmount <= (totalSupply() * 5) / 1000, "Swap amount cannot be higher than 0.5% total supply.");
        swapTokensAtAmount = newAmount;
    }

    function setSellTax(uint48 _mktingTax, uint48 _lpTax, uint48 _devTax, uint48 _revenueShareTax) external onlyOwner {
        Tax memory taxes;
        taxes.mktingTax = _mktingTax;
        taxes.lpTax = _lpTax;
        taxes.devTax = _devTax;
        taxes.revenueShareTax = _revenueShareTax;
        taxes.totalTax = _mktingTax + _lpTax + _devTax + _revenueShareTax;
        require(taxes.totalTax  <= 1000, "Keep tax below 10%");
        emit SellTaxUpdated(taxes.totalTax);
        sellTax = taxes;
    }

    function updateBuyTax(uint48 _mktingTax, uint48 _lpTax, uint48 _devTax, uint48 _revenueShareTax) external onlyOwner {
        Tax memory taxes;
        taxes.mktingTax = _mktingTax;
        taxes.lpTax = _lpTax;
        taxes.devTax = _devTax;
        taxes.revenueShareTax = _revenueShareTax;
        taxes.totalTax = _mktingTax + _lpTax + _devTax + _revenueShareTax;
        require(taxes.totalTax  <= 1000, "Keep tax below 10%");
        emit BuyTaxUpdated(taxes.totalTax);
        buyTax = taxes;
    }

    function removeTxLimits() external onlyOwner {
        txnLimitsActive = false;
        TxLimits memory _txnLimits;
        uint256 supply = totalSupply();
        _txnLimits.transactionLimit = uint96(supply);
        _txnLimits.walletLimit = uint96(supply);
        txnLimits = _txnLimits;
        emit RemovedLimits();
    }

    function updateAntiMevEnabled(bool _enabled) external onlyOwner {
        antiSandwichEnabled = _enabled;
    }

    function setMarketingAddress(address _address) external onlyOwner {
        require(_address != address(0), "zero address");
        marketingAddress = _address;
    }

    function setDevAddress(address _address) external onlyOwner {
        require(_address != address(0), "zero address");
        devAddress = _address;
    }

    receive() payable external {}

    // dividend functions

    function claim() external {
        revenueShare.processAccount(payable(msg.sender), false);
    }

    function getTotalDividendsDistributed() external view returns (uint256) {
        return revenueShare.totalDividendsDistributed();
    }

    function withdrawableDividendOf(address account) public view returns(uint256) {
    	return revenueShare.withdrawableDividendOf(account);
  	}

	function dividendTokenBalanceOf(address account) public view returns (uint256) {
		return revenueShare.holderBalance(account);
	}

    function getAccountDividendsInfo(address account)
        external view returns (
            address,
            uint256,
            uint256,
            uint256) {
        return revenueShare.getAccount(account);
    }
    
    function getNumberOfDividends() external view returns(uint256) {
        return revenueShare.totalBalance();
    }

    function excludeFromDividends(address _wallet) external onlyOwner {
        revenueShare.excludeFromDividends(_wallet);
    }

     function includeInDividends(address _wallet) external onlyOwner {
        revenueShare.includeInDividends(_wallet);
    }

    function compound(uint256 minOutput) external {
        uint256 amountEthForCompound = revenueShare.withdrawDividendOfUserForCompound(payable(msg.sender));
        if(amountEthForCompound > 0){
            buyBackTokens(amountEthForCompound, minOutput, msg.sender);
        } else {
            revert("No rewards");
        }
    }

    function buyBackTokens(uint256 ethAmountInWei, uint256 minOut, address to) internal {
        // generate the uniswap pair path of weth -> eth
        address[] memory path = new address[](2);
        path[0] = address(WETH);
        path[1] = address(this);

        // make the swap
        dexRouter.swapExactETHForTokensSupportingFeeOnTransferTokens{value: ethAmountInWei}(
            minOut,
            path,
            address(to),
            block.timestamp
        );
    }

    // helper views

    function getCompoundOutputByUser(uint256 rewardAmount) external view returns(uint256) {
        if(rewardAmount == 0){
            return 0;
        }
        address[] memory path = new address[](2);
        path[0] = address(WETH);
        path[1] = address(this);
        uint256[] memory amounts = dexRouter.getAmountsOut(rewardAmount, path);
        return amounts[1] - (amounts[1] * (buyTax.totalTax + 50) / FEE_DIVISOR);
    }

    function getCompoundOutputByWallet(address wallet) external view returns(uint256) {
        uint256 rewardAmount = withdrawableDividendOf(wallet);
        if(rewardAmount == 0){
            return 0;
        }
        address[] memory path = new address[](2);
        path[0] = address(WETH);
        path[1] = address(this);
        uint256[] memory amounts = dexRouter.getAmountsOut(rewardAmount, path);
        return amounts[1] - (amounts[1] * (buyTax.totalTax + 50) / FEE_DIVISOR);
    }

    function launch(address _to) external onlyOwner payable {
        require(address(this).balance > 0 && balanceOf(address(this)) > 0);

        WETH.deposit{value: address(this).balance}();

        super._transfer(address(this), address(pair), balanceOf(address(this)));
        IERC20(address(WETH)).transfer(address(pair), IERC20(address(WETH)).balanceOf(address(this)));
        ILpPair(pair).mint(_to);
        launchBlock = block.number;
        txnLimits.gasLimitActive = true;
        latestEthPrice = uint256(priceFeed.latestAnswer());
    }

    function getMcap() public view returns (uint256){
        return (IERC20(dexRouter.WETH()).balanceOf(address(pair)) * 1e18 * latestEthPrice / balanceOf(address(pair)) * (totalSupply()-balanceOf(address(0xdead))) / 1e18 / 1e8); 
    }
}
IERC20.sol 78 lines
pragma solidity 0.8.19;

// SPDX-License-Identifier: MIT

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

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

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

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

    /**
     * @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);
}
Context.sol 14 lines
pragma solidity 0.8.19;

// SPDX-License-Identifier: MIT

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}
DEXInterfaces.sol 27 lines
pragma solidity 0.8.19;


// SPDX-License-Identifier: MIT

interface ILpPair {
    function sync() external;
    function mint(address to) external returns (uint liquidity);
}

interface IDexRouter {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);
    function swapExactTokensForETHSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external;
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable;
    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}

interface IDexFactory {
    function createPair(address tokenA, address tokenB) external returns (address pair);
}
StructLibrary.sol 25 lines
pragma solidity 0.8.19;

// SPDX-License-Identifier: MIT

library StructLibrary {
    struct Params {
        string name;
        string symbol;
        uint112 totalSupply;
        uint48 liquidityPercentage;
        address marketingAddress;
        address devAddress;
        uint48 marketingTaxBuy;
        uint48 devTaxBuy;
        uint48 lpTaxBuy;
        uint48 revenueShareTaxBuy;
        uint48 marketingTaxSell;
        uint48 devTaxSell;
        uint48 lpTaxSell;
        uint48 revenueShareTaxSell;
        uint128 transactionLimit;
        uint128 walletLimit;
        uint48 gasLimit;
    }
}

Read Contract

FEE_DIVISOR 0x9e93ad8e → uint64
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
buyTax 0x4f7041a5 → uint48, uint48, uint48, uint48, uint48
decimals 0x313ce567 → uint8
devAddress 0x3ad10ef6 → address
dexRouter 0x0758d924 → address
dividendTokenBalanceOf 0x6843cd84 → uint256
excludedFromTxLimits 0x167c12fe → bool
getAccountDividendsInfo 0xad56c13c → address, uint256, uint256, uint256
getCompoundOutputByUser 0xbbcc88b4 → uint256
getCompoundOutputByWallet 0x14bb4edd → uint256
getMcap 0xc077ab4b → uint256
getNumberOfDividends 0x71778e7d → uint256
getTotalDividendsDistributed 0x30bb4cff → uint256
marketingAddress 0xa5ece941 → address
name 0x06fdde03 → string
owner 0x8da5cb5b → address
pair 0xa8aa1b31 → address
revenueShare 0xff0984ca → address
sellTax 0xcc1776d3 → uint48, uint48, uint48, uint48, uint48
symbol 0x95d89b41 → string
tokensForTax 0x6d7adcad → uint64, uint64, uint64, uint64, bool
totalSupply 0x18160ddd → uint256
txnLimits 0x91719aa6 → uint96, uint96, uint48, bool
txnLimitsActive 0xa4e87e35 → bool
whitelisted 0xd936547e → bool
withdrawableDividendOf 0xa8b9d240 → uint256

Write Contract 23 functions

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

approve 0x095ea7b3
address spender
uint256 amount
returns: bool
changeExcludedFromFees 0xf84e4265
address _address
bool _isExcluded
changeTransactionMax 0x9e8dcc3c
uint96 newNumInTokens
claim 0x4e71d92d
No parameters
compound 0xaa5f7e26
uint256 minOutput
decreaseAllowance 0xa457c2d7
address spender
uint256 subtractedValue
returns: bool
excludeFromDividends 0x31e79db0
address _wallet
includeInDividends 0xc0f306ef
address _wallet
increaseAllowance 0x39509351
address spender
uint256 addedValue
returns: bool
launch 0x214013ca
address _to
removeTxLimits 0x0106aaef
No parameters
renounceOwnership 0x715018a6
No parameters
setDevAddress 0xd0d41fe1
address _address
setExcludedFromLimit 0xbf78019b
address _address
bool _isExcluded
setMarketingAddress 0x906e9dd0
address _address
setSellTax 0xf4c6184a
uint48 _mktingTax
uint48 _lpTax
uint48 _devTax
uint48 _revenueShareTax
setSwapTokensAmount 0x43e716fe
uint256 newAmount
transfer 0xa9059cbb
address to
uint256 amount
returns: bool
transferFrom 0x23b872dd
address from
address to
uint256 amount
returns: bool
transferOwnership 0xf2fde38b
address newOwner
updateAntiMevEnabled 0x5cfb534e
bool _enabled
updateBuyTax 0xac37d4a1
uint48 _mktingTax
uint48 _lpTax
uint48 _devTax
uint48 _revenueShareTax
updateWalletLimit 0x64a81f1d
uint96 newNumInTokens

Recent Transactions

No transactions found for this address