Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x35aDb2D8A5D9B9Aec8945eFbA39aFD4b8c00a9fa
Balance 0 ETH
Nonce 1
Code Size 12910 bytes
Last Active
Indexed Transactions 36 (10,793,71724,320,692)
Value (indexed) ↓ 9.3943 ETH
Gas Used (indexed) 11,404,140
External Etherscan · Sourcify

Contract Bytecode

12910 bytes
0x6080604052600436106100dd5760003560e01c8063a06dd6dc1161007f578063dd58d9d511610059578063dd58d9d51461046a578063e9c4aa6a146104ad578063f39d3c49146104f5578063fdd5660514610525576100dd565b8063a06dd6dc146103f8578063aa8b99d21461040d578063cbd99d0314610437576100dd565b80634eb9b592116100bb5780634eb9b59214610165578063590c2a8b146101965780635de3326c1461025b5780639d63848a14610393576100dd565b8063167e4781146100e2578063441a3e701461011e57806348cd4cb114610150575b600080fd5b3480156100ee57600080fd5b5061010c6004803603602081101561010557600080fd5b5035610560565b60408051918252519081900360200190f35b34801561012a57600080fd5b5061014e6004803603604081101561014157600080fd5b5080359060200135610575565b005b34801561015c57600080fd5b5061010c6109f1565b34801561017157600080fd5b5061017a6109f7565b604080516001600160a01b039092168252519081900360200190f35b3480156101a257600080fd5b506101c6600480360360408110156101b957600080fd5b5080359060200135610a06565b604051808a6001600160a01b0316815260200189815260200188815260200187815260200186815260200185815260200184815260200180602001838152602001828103825284818151815260200191508051906020019060200280838360005b8381101561023f578181015183820152602001610227565b505050509050019a505050505050505050505060405180910390f35b34801561026757600080fd5b50610270610b39565b6040518080602001806020018060200180602001858103855289818151815260200191508051906020019060200280838360005b838110156102bc5781810151838201526020016102a4565b50505050905001858103845288818151815260200191508051906020019060200280838360005b838110156102fb5781810151838201526020016102e3565b50505050905001858103835287818151815260200191508051906020019060200280838360005b8381101561033a578181015183820152602001610322565b50505050905001858103825286818151815260200191508051906020019060200280838360005b83811015610379578181015183820152602001610361565b505050509050019850505050505050505060405180910390f35b34801561039f57600080fd5b506103a8610c9d565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103e45781810151838201526020016103cc565b505050509050019250505060405180910390f35b34801561040457600080fd5b5061014e610cff565b34801561041957600080fd5b5061010c6004803603602081101561043057600080fd5b5035611263565b34801561044357600080fd5b5061014e6004803603602081101561045a57600080fd5b50356001600160a01b0316611275565b34801561047657600080fd5b506104946004803603602081101561048d57600080fd5b503561143b565b6040805192835260208301919091528051918290030190f35b3480156104b957600080fd5b506104d7600480360360208110156104d057600080fd5b50356118d5565b60408051938452602084019290925282820152519081900360600190f35b34801561050157600080fd5b5061014e6004803603604081101561051857600080fd5b508035906020013561195b565b61014e600480360360c081101561053b57600080fd5b5080359060208101359060408101359060608101359060808101359060a00135611dcb565b6000818152600260205260409020545b919050565b61057d613022565b600083815260096020908152604080832085845282529182902082516101208101845281546001600160a01b031681526001820154818401526002820154818501526003820154606082015260048201546080820152600582015460a0820152600682015460c08201526007820180548551818602810186019096528086529194929360e0860193929083018282801561063657602002820191906000526020600020905b815481526020019060010190808311610622575b5050505050815260200160088201548152505090508060c0015143101561068e5760405162461bcd60e51b815260040180806020018281038252602681526020018061319c6026913960400191505060405180910390fd5b6007546040805163ec55688960e01b815290516000926001600160a01b03169163ec556889916004808301926020929190829003018186803b1580156106d357600080fd5b505afa1580156106e7573d6000803e3d6000fd5b505050506040513d60208110156106fd57600080fd5b5051604080516321df0da760e01b815290516001600160a01b03909216916321df0da791600480820192602092909190829003018186803b15801561074157600080fd5b505afa158015610755573d6000803e3d6000fd5b505050506040513d602081101561076b57600080fd5b505160a08301519091501561080657806001600160a01b031663a9059cbb83600001518460a001516040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156107d957600080fd5b505af11580156107ed573d6000803e3d6000fd5b505050506040513d602081101561080357600080fd5b50505b735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6001600160a01b031663e6a4390582600185602001518154811061083b57fe5b60009182526020918290200154604080516001600160e01b031960e087901b1681526001600160a01b03948516600482015293909116602484015251604480840193829003018186803b15801561089157600080fd5b505afa1580156108a5573d6000803e3d6000fd5b505050506040513d60208110156108bb57600080fd5b5051825160808401516040805163a9059cbb60e01b81526001600160a01b0393841660048201526024810192909252519293509083169163a9059cbb916044808201926020929091908290030181600087803b15801561091a57600080fd5b505af115801561092e573d6000803e3d6000fd5b505050506040513d602081101561094457600080fd5b50506080808301805160208581018051600090815260028352604080822054835183529181902094909103909355518651838801516060808a0151965160a0808c01518851338152978801949094528688019890985290850152958301959095529151919388936001600160a01b03909116927fec4d7fc8319e44dfa849ab87f565622b9cf848ce9959568c3066615ce9e2ef149281900390910190a46109eb8484612183565b50505050565b60085490565b6007546001600160a01b031690565b600080600080600080600060606000610a1d613022565b60008c81526009602090815260408083208e845282529182902082516101208101845281546001600160a01b031681526001820154818401526002820154818501526003820154606082015260048201546080820152600582015460a0820152600682015460c08201526007820180548551818602810186019096528086529194929360e08601939290830182828015610ad657602002820191906000526020600020905b815481526020019060010190808311610ac2575b505050505081526020016008820154815250509050806000015181602001518260400151836060015184608001518560a001518660c001518760e00151886101000151995099509950995099509950995099509950509295985092959850929598565b606080606080600360046005600683805480602002602001604051908101604052809291908181526020018280548015610b9257602002820191906000526020600020905b815481526020019060010190808311610b7e575b5050505050935082805480602002602001604051908101604052809291908181526020018280548015610be457602002820191906000526020600020905b815481526020019060010190808311610bd0575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015610c3657602002820191906000526020600020905b815481526020019060010190808311610c22575b5050505050915080805480602002602001604051908101604052809291908181526020018280548015610c8857602002820191906000526020600020905b815481526020019060010190808311610c74575b50505050509050935093509350935090919293565b60606001805480602002602001604051908101604052809291908181526020018280548015610cf557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610cd7575b5050505050905090565b6007546040805163ec55688960e01b815290516000926001600160a01b03169163ec556889916004808301926020929190829003018186803b158015610d4457600080fd5b505afa158015610d58573d6000803e3d6000fd5b505050506040513d6020811015610d6e57600080fd5b505160408051633380ac3560e11b815290519192506001600160a01b03831691636701586a91600480820192602092909190829003018186803b158015610db457600080fd5b505afa158015610dc8573d6000803e3d6000fd5b505050506040513d6020811015610dde57600080fd5b5051604080516318c8e99960e11b815233600482015290516001600160a01b0390921691633191d33291602480820192602092909190829003018186803b158015610e2857600080fd5b505afa158015610e3c573d6000803e3d6000fd5b505050506040513d6020811015610e5257600080fd5b5051610e9c576040805162461bcd60e51b8152602060048201526014602482015273556e617574686f72697a656420416374696f6e2160601b604482015290519081900360640190fd5b6000816001600160a01b03166331c6903d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ed757600080fd5b505afa158015610eeb573d6000803e3d6000fd5b505050506040513d6020811015610f0157600080fd5b5051604080516321df0da760e01b815290519192506000916001600160a01b038516916321df0da7916004808301926020929190829003018186803b158015610f4957600080fd5b505afa158015610f5d573d6000803e3d6000fd5b505050506040513d6020811015610f7357600080fd5b5051604080516370a0823160e01b8152306004820152905191925082916000916001600160a01b038416916370a0823191602480820192602092909190829003018186803b158015610fc457600080fd5b505afa158015610fd8573d6000803e3d6000fd5b505050506040513d6020811015610fee57600080fd5b50519050801561107c57816001600160a01b031663a9059cbb85836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561104f57600080fd5b505af1158015611063573d6000803e3d6000fd5b505050506040513d602081101561107957600080fd5b50505b506000805b60015481101561125b57735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6001600160a01b031663e6a4390585600184815481106110bc57fe5b60009182526020918290200154604080516001600160e01b031960e087901b1681526001600160a01b03948516600482015293909116602484015251604480840193829003018186803b15801561111257600080fd5b505afa158015611126573d6000803e3d6000fd5b505050506040513d602081101561113c57600080fd5b5051604080516370a0823160e01b815230600482015290519194506001600160a01b038516916370a0823191602480820192602092909190829003018186803b15801561118857600080fd5b505afa15801561119c573d6000803e3d6000fd5b505050506040513d60208110156111b257600080fd5b50519150811561124f57826001600160a01b031663a9059cbb86846040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561121357600080fd5b505af1158015611227573d6000803e3d6000fd5b505050506040513d602081101561123d57600080fd5b50506000818152600260205260408120555b60009150600101611081565b505050505050565b6000908152600a602052604090205490565b600760009054906101000a90046001600160a01b03166001600160a01b031663ec5568896040518163ffffffff1660e01b815260040160206040518083038186803b1580156112c357600080fd5b505afa1580156112d7573d6000803e3d6000fd5b505050506040513d60208110156112ed57600080fd5b505160408051633380ac3560e11b815290516001600160a01b0390921691636701586a91600480820192602092909190829003018186803b15801561133157600080fd5b505afa158015611345573d6000803e3d6000fd5b505050506040513d602081101561135b57600080fd5b5051604080516318c8e99960e11b815233600482015290516001600160a01b0390921691633191d33291602480820192602092909190829003018186803b1580156113a557600080fd5b505afa1580156113b9573d6000803e3d6000fd5b505050506040513d60208110156113cf57600080fd5b5051611419576040805162461bcd60e51b8152602060048201526014602482015273556e617574686f72697a656420416374696f6e2160601b604482015290519081900360640190fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000600760009054906101000a90046001600160a01b03166001600160a01b031663ec5568896040518163ffffffff1660e01b815260040160206040518083038186803b15801561148e57600080fd5b505afa1580156114a2573d6000803e3d6000fd5b505050506040513d60208110156114b857600080fd5b50516040805163ba83c16f60e01b815290516001600160a01b039092169163ba83c16f91600480820192602092909190829003018186803b1580156114fc57600080fd5b505afa158015611510573d6000803e3d6000fd5b505050506040513d602081101561152657600080fd5b505190506060611535856122cd565b9050606061154a611545306123a5565b612518565b9050826001600160a01b0316630bb687e3828460405160200180806739ba30b5b4b7339760c11b81525060080183805190602001908083835b602083106115a25780518252601f199092019160209182019101611583565b51815160209384036101000a6000190180199092169116179052662e74696572735b60c81b919093019081528451600790910192850191508083835b602083106115fd5780518252601f1990920191602091820191016115de565b6001836020036101000a038019825116818451168082178552505050505050905001806705d2e6d696e4361760c41b815250600801925050506040516020818303038152906040526040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611691578181015183820152602001611679565b50505050905090810190601f1680156116be5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156116db57600080fd5b505afa1580156116ef573d6000803e3d6000fd5b505050506040513d602081101561170557600080fd5b50516040516739ba30b5b4b7339760c11b602082810191825284516001600160a01b03881693630bb687e39387938993919260280191908501908083835b602083106117625780518252601f199092019160209182019101611743565b51815160209384036101000a6000190180199092169116179052662e74696572735b60c81b919093019081528451600790910192850191508083835b602083106117bd5780518252601f19909201916020918201910161179e565b6001836020036101000a038019825116818451168082178552505050505050905001806805d2e686172644361760bc1b815250600901925050506040516020818303038152906040526040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561185257818101518382015260200161183a565b50505050905090810190601f16801561187f5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561189c57600080fd5b505afa1580156118b0573d6000803e3d6000fd5b505050506040513d60208110156118c657600080fd5b50519095509350505050915091565b60008060006118e38461143b565b6000868152600a60205260408120549295509093508392505b8181101561195257600086815260096020908152604080832084845290915290206006015443101561194a576000868152600960209081526040808320848452909152902060020154909203915b6001016118fc565b50509193909250565b611963613022565b600083815260096020908152604080832085845282529182902082516101208101845281546001600160a01b031681526001820154818401526002820154818501526003820154606082015260048201546080820152600582015460a0820152600682015460c08201526007820180548551818602810186019096528086529194929360e08601939290830182828015611a1c57602002820191906000526020600020905b815481526020019060010190808311611a08575b5050505050815260200160088201548152505090508060c001514310611a4c57611a468383610575565b50611dc7565b60008160a0015111611a8f5760405162461bcd60e51b81526004018080602001828103825260288152602001806131746028913960400191505060405180910390fd5b6000805b8260e0015151811015611b145760008360e001518281518110611ab257fe5b6020026020010151118015611ade57508260e001518181518110611ad257fe5b60200260200101514310155b15611b0c578261010001518201915060008360e001518281518110611aff57fe5b6020026020010181815250505b600101611a93565b508160a001518111611b265780611b2c565b8160a001515b905060008111611b79576040805162461bcd60e51b81526020600482015260136024820152724e6f2072657761726420746f2072656465656d60681b604482015290519081900360640190fd5b6007546040805163ec55688960e01b815290516000926001600160a01b03169163ec556889916004808301926020929190829003018186803b158015611bbe57600080fd5b505afa158015611bd2573d6000803e3d6000fd5b505050506040513d6020811015611be857600080fd5b5051604080516321df0da760e01b815290516001600160a01b03909216916321df0da791600480820192602092909190829003018186803b158015611c2c57600080fd5b505afa158015611c40573d6000803e3d6000fd5b505050506040513d6020811015611c5657600080fd5b505183516040805163a9059cbb60e01b81526001600160a01b0392831660048201526024810186905290519293509083169163a9059cbb916044808201926020929091908290030181600087803b158015611cb057600080fd5b505af1158015611cc4573d6000803e3d6000fd5b505050506040513d6020811015611cda57600080fd5b505060a08301805183900381526000868152600960209081526040808320888452825291829020865181546001600160a01b0319166001600160a01b0390911617815581870151600182015591860151600283015560608601516003830155608086015160048301559151600582015560c0850151600682015560e085015180518693611d6e926007850192910190613077565b50610100919091015160089091015582516040805133815260208101859052815188936001600160a01b0316927f5777300364834e2d145b85cee28a0d45c4be04f1c7c24116ec72a6b5c839631b928290030190a35050505b5050565b600854431015611e22576040805162461bcd60e51b815260206004820152601e60248201527f5374616b696e67206973207374696c6c206e6f7420617661696c61626c650000604482015290519081900360640190fd5b6001548510611e67576040805162461bcd60e51b815260206004820152600c60248201526b155b9adb9bdddb88141bdbdb60a21b604482015290519081900360640190fd5b6003548610611eac576040805162461bcd60e51b815260206004820152600c60248201526b2ab735b737bbb7103a34b2b960a11b604482015290519081900360640190fd5b60008411611eeb5760405162461bcd60e51b81526004018080602001828103825260238152602001806131c26023913960400191505060405180910390fd5b60008054600180546001600160a01b039092169188908110611f0957fe5b6000918252602090912001546001600160a01b031614611f295782611f2b565b345b905060008111611f6c5760405162461bcd60e51b81526004018080602001828103825260248152602001806132156024913960400191505060405180910390fd5b6007546040805163ec55688960e01b815290516000926001600160a01b03169163ec556889916004808301926020929190829003018186803b158015611fb157600080fd5b505afa158015611fc5573d6000803e3d6000fd5b505050506040513d6020811015611fdb57600080fd5b5051604080516321df0da760e01b815290519192506000916001600160a01b038416916321df0da7916004808301926020929190829003018186803b15801561202357600080fd5b505afa158015612037573d6000803e3d6000fd5b505050506040513d602081101561204d57600080fd5b5051905061205b81886125ea565b6120866001898154811061206b57fe5b6000918252602090912001546001600160a01b0316846125ea565b60006001898154811061209557fe5b60009182526020822001546001600160a01b0316915080806120bb8b8b898b89896127b3565b60008f81526002602052604081208054830190559295509093509150806120e18f6118d5565b9250509150818510156121255760405162461bcd60e51b81526004018080602001828103825260308152602001806131e56030913960400191505060405180910390fd5b808511156121645760405162461bcd60e51b815260040180806020018281038252603b815260200180613139603b913960400191505060405180910390fd5b6121728f8f8787878d612ac8565b505050505050505050505050505050565b6000828152600a6020526040902054811061219d57611dc7565b6000828152600a6020526040902080546000190190819055811015612259576000828152600960209081526040808320600a83528184205484529091528082208383529120815481546001600160a01b0319166001600160a01b039091161781556001808301549082015560028083015490820155600380830154908201556004808301549082015560058083015490820155600680830154908201556007808301805461224e92840191906130c2565b506008918201549101555b6000828152600960209081526040808320600a8352818420548452909152812080546001600160a01b0319168155600181018290556002810182905560038101829055600481018290556005810182905560068101829055906122bf6007830182613102565b600882016000905550505050565b6060816122f257506040805180820190915260018152600360fc1b6020820152610570565b8160005b811561230a57600101600a820491506122f6565b60608167ffffffffffffffff8111801561232357600080fd5b506040519080825280601f01601f19166020018201604052801561234e576020820181803683370190505b50905060001982015b851561239c57600a860660300160f81b8282806001900393508151811061237a57fe5b60200101906001600160f81b031916908160001a905350600a86049550612357565b50949350505050565b604080518082018252601081526f181899199a1a9b1b9c1cb0b131b232b360811b60208201528151602a80825260608281019094526001600160a01b03851692918491602082018180368337019050509050600360fc1b8160008151811061240957fe5b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061243257fe5b60200101906001600160f81b031916908160001a90535060005b601481101561239c578260048583600c016020811061246757fe5b1a60f81b6001600160f81b031916901c60f81c60ff168151811061248757fe5b602001015160f81c60f81b8282600202600201815181106124a457fe5b60200101906001600160f81b031916908160001a905350828482600c01602081106124cb57fe5b825191901a600f169081106124dc57fe5b602001015160f81c60f81b8282600202600301815181106124f957fe5b60200101906001600160f81b031916908160001a90535060010161244c565b60608160005b81518110156125e357604160f81b82828151811061253857fe5b01602001516001600160f81b031916108015906125735750605a60f81b82828151811061256157fe5b01602001516001600160f81b03191611155b6125975781818151811061258357fe5b01602001516001600160f81b0319166125b8565b8181815181106125a357fe5b602001015160f81c60f81b60f81c60200160f81b5b8282815181106125c457fe5b60200101906001600160f81b031916908160001a90535060010161251e565b5092915050565b6000546001600160a01b038381169116141561260557611dc7565b604080516323b872dd60e01b815233600482015230602482015260448101839052905183916001600160a01b038316916323b872dd916064808201926020929091908290030181600087803b15801561265d57600080fd5b505af1158015612671573d6000803e3d6000fd5b505050506040513d602081101561268757600080fd5b505060408051636eb1769f60e11b8152306004820152737a250d5630b4cf539739df2c5dacb4c659f2488d6024820152905183916001600160a01b0384169163dd62ed3e91604480820192602092909190829003018186803b1580156126ec57600080fd5b505afa158015612700573d6000803e3d6000fd5b505050506040513d602081101561271657600080fd5b5051116127ae576040805163095ea7b360e01b8152737a250d5630b4cf539739df2c5dacb4c659f2488d6004820152600019602482015290516001600160a01b0383169163095ea7b39160448083019260209291908290030181600087803b15801561278157600080fd5b505af1158015612795573d6000803e3d6000fd5b505050506040513d60208110156127ab57600080fd5b50505b505050565b60008054819081906001600160a01b0385811691161415612897576040805163f305d71960e01b81526001600160a01b0387166004820152602481018b9052604481018a9052606481018890523060848201526103e8420160a48201529051737a250d5630b4cf539739df2c5dacb4c659f2488d9163f305d719918a9160c48082019260609290919082900301818588803b15801561285157600080fd5b505af1158015612865573d6000803e3d6000fd5b50505050506040513d606081101561287c57600080fd5b50805160208201516040909201519094509092509050612968565b6040805162e8e33760e81b81526001600160a01b03878116600483015286166024820152604481018b905260648101899052608481018a905260a481018890523060c48201526103e8420160e48201529051737a250d5630b4cf539739df2c5dacb4c659f2488d9163e8e33700916101048083019260609291908290030181600087803b15801561292757600080fd5b505af115801561293b573d6000803e3d6000fd5b505050506040513d606081101561295157600080fd5b508051602082015160409092015190945090925090505b888310156129ed576040805163a9059cbb60e01b8152336004820152848b03602482015290516001600160a01b0387169163a9059cbb9160448083019260209291908290030181600087803b1580156129c057600080fd5b505af11580156129d4573d6000803e3d6000fd5b505050506040513d60208110156129ea57600080fd5b50505b86821015612abc576000546001600160a01b0385811691161415612a3f57604051339083890380156108fc02916000818181858888f19350505050158015612a39573d6000803e3d6000fd5b50612abc565b6040805163a9059cbb60e01b8152336004820152838903602482015290516001600160a01b0386169163a9059cbb9160448083019260209291908290030181600087803b158015612a8f57600080fd5b505af1158015612aa3573d6000803e3d6000fd5b505050506040513d6020811015612ab957600080fd5b50505b96509650969350505050565b600060068781548110612ad757fe5b906000526020600020015460038881548110612aef57fe5b906000526020600020015481612b0157fe5b049050606060068881548110612b1357fe5b906000526020600020015467ffffffffffffffff81118015612b3457600080fd5b50604051908082528060200260200182016040528015612b5e578160200160208202803683370190505b50805190915015612bca5781430181600081518110612b7957fe5b602090810291909101015260015b8151811015612bc85782826001830381518110612ba057fe5b602002602001015101828281518110612bb557fe5b6020908102919091010152600101612b87565b505b600060058981548110612bd957fe5b906000526020600020015460048a81548110612bf157fe5b9060005260206000200154880281612c0557fe5b049050612c10613022565b604051806101200160405280336001600160a01b031681526020018a815260200189815260200188815260200187815260200183815260200160038c81548110612c5657fe5b90600052602060002001544301815260200184815260200160068c81548110612c7b57fe5b90600052602060002001548481612c8e57fe5b0490529050612c9d8a82612f57565b50506040805160006020808301829052828401829052606083018690523060808085019190915284518085038201815260a08501808752639e813f1f60e01b905260a48501958652600f60e48601526e39ba30b5b4b733aa3930b739b332b960891b61010486015260c48501918252805161012486015280516001600160a01b038c1696639e813f1f96929590948594936101440192908701918190849084905b83811015612d56578181015183820152602001612d3e565b50505050905090810190601f168015612d835780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015612da357600080fd5b505af1158015612db7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612de057600080fd5b8101908080516040519392919084640100000000821115612e0057600080fd5b908301906020820185811115612e1557600080fd5b8251640100000000811182820188101715612e2f57600080fd5b82525081516020918201929091019080838360005b83811015612e5c578181015183820152602001612e44565b50505050905090810190601f168015612e895780820380516001836020036101000a031916815260200191505b5060405250505050888a336001600160a01b03167f904bffde498b5f8b9c482208599445964bca8e5fe0837abba34df545d09aed428b8b8b888860c001518b8a61010001516040518088815260200187815260200186815260200185815260200184815260200180602001838152602001828103825284818151815260200191508051906020019060200280838360005b83811015612f32578181015183820152602001612f1a565b505050509050019850505050505050505060405180910390a450505050505050505050565b6000828152600960209081526040808320600a83528184205484528252808320845181546001600160a01b0319166001600160a01b03909116178155848301516001820155908401516002820155606084015160038201556080840151600482015560a0840151600582015560c0840151600682015560e084015180518493869392612fec9260078501929190910190613077565b50610100919091015160089091015550506000918252600a60205260409091208054600101905560a081015160c0909101519091565b60405180610120016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160608152602001600081525090565b8280548282559060005260206000209081019282156130b2579160200282015b828111156130b2578251825591602001919060010190613097565b506130be929150613123565b5090565b8280548282559060005260206000209081019282156130b25760005260206000209182015b828111156130b25782548255916001019190600101906130e7565b50805460008255906000526020600020908101906131209190613123565b50565b5b808211156130be576000815560010161312456fe416d6f756e7420746f207374616b65206d757374206265206c657373207468616e207468652063757272656e742072656d61696e696e67206f6e654e6f206d6f72652072657761726420666f722074686973207374616b696e6720706f736974696f6e43616e6e6f742061637475616c6c79207769746864726177207468697320706f736974696f6e466972737420616d6f756e74206d7573742062652067726561746572207468616e2030416d6f756e7420746f207374616b65206973206c657373207468616e207468652063757272656e74206d696e206361705365636f6e6420616d6f756e74206d7573742062652067726561746572207468616e2030a264697066735822122005cb8c16848065602012eb1d67f99bf9b88dff18e2ae0a0a8c951f15ca520ef064736f6c63430007010033

Verified Source Code Partial Match

Compiler: v0.7.1+commit.f4a555be EVM: istanbul Optimization: Yes (200 runs)
DFOStake.sol 412 lines
pragma solidity ^0.7.1;

contract DFOStake {

    address private constant UNISWAP_V2_FACTORY = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;

    address private constant UNISWAP_V2_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;

    address private WETH_ADDRESS = IUniswapV2Router(UNISWAP_V2_ROUTER).WETH();

    address[] private TOKENS;

    mapping(uint256 => uint256) private _totalPoolAmount;

    uint256[] private TIME_WINDOWS;

    uint256[] private REWARD_MULTIPLIERS;

    uint256[] private REWARD_DIVIDERS;

    uint256[] private REWARD_SPLIT_TRANCHES;

    address private _doubleProxy;

    struct StakeInfo {
        address sender;
        uint256 poolPosition;
        uint256 firstAmount;
        uint256 secondAmount;
        uint256 poolAmount;
        uint256 reward;
        uint256 endBlock;
        uint256[] partialRewardBlockTimes;
        uint256 splittedReward;
    }

    uint256 private _startBlock;

    mapping(uint256 => mapping(uint256 => StakeInfo)) private _stakeInfo;
    mapping(uint256 => uint256) private _stakeInfoLength;

    event Staked(address indexed sender, uint256 indexed tier, uint256 indexed poolPosition, uint256 firstAmount, uint256 secondAmount, uint256 poolAmount, uint256 reward, uint256 endBlock, uint256[] partialRewardBlockTimes, uint256 splittedReward);
    event Withdrawn(address sender, address indexed receiver, uint256 indexed tier, uint256 indexed poolPosition, uint256 firstAmount, uint256 secondAmount, uint256 poolAmount, uint256 reward);
    event PartialWithdrawn(address sender, address indexed receiver, uint256 indexed tier, uint256 reward);

    constructor(uint256 startBlock, address doubleProxy, address[] memory tokens, uint256[] memory timeWindows, uint256[] memory rewardMultipliers, uint256[] memory rewardDividers, uint256[] memory rewardSplitTranches) public {

        _startBlock = startBlock;

        _doubleProxy = doubleProxy;

        for(uint256 i = 0; i < tokens.length; i++) {
            TOKENS.push(tokens[i]);
        }

        assert(timeWindows.length == rewardMultipliers.length && rewardMultipliers.length == rewardDividers.length && rewardDividers.length == rewardSplitTranches.length);
        for(uint256 i = 0; i < timeWindows.length; i++) {
            TIME_WINDOWS.push(timeWindows[i]);
        }

        for(uint256 i = 0; i < rewardMultipliers.length; i++) {
            REWARD_MULTIPLIERS.push(rewardMultipliers[i]);
        }

        for(uint256 i = 0; i < rewardDividers.length; i++) {
            REWARD_DIVIDERS.push(rewardDividers[i]);
        }

        for(uint256 i = 0; i < rewardSplitTranches.length; i++) {
            REWARD_SPLIT_TRANCHES.push(rewardSplitTranches[i]);
        }
    }

    function doubleProxy() public view returns(address) {
        return _doubleProxy;
    }

    function tokens() public view returns(address[] memory) {
        return TOKENS;
    }

    function tierData() public view returns(uint256[] memory, uint256[] memory, uint256[] memory, uint256[] memory) {
        return (TIME_WINDOWS, REWARD_MULTIPLIERS, REWARD_DIVIDERS, REWARD_SPLIT_TRANCHES);
    }

    function startBlock() public view returns(uint256) {
        return _startBlock;
    }

    function totalPoolAmount(uint256 poolPosition) public view returns(uint256) {
        return _totalPoolAmount[poolPosition];
    }

    function setDoubleProxy(address newDoubleProxy) public {
        require(IMVDFunctionalitiesManager(IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDFunctionalitiesManagerAddress()).isAuthorizedFunctionality(msg.sender), "Unauthorized Action!");
        _doubleProxy = newDoubleProxy;
    }

    function emergencyFlush() public {
        IMVDProxy proxy = IMVDProxy(IDoubleProxy(_doubleProxy).proxy());
        require(IMVDFunctionalitiesManager(proxy.getMVDFunctionalitiesManagerAddress()).isAuthorizedFunctionality(msg.sender), "Unauthorized Action!");
        address walletAddress = proxy.getMVDWalletAddress();
        address tokenAddress = proxy.getToken();
        IERC20 token = IERC20(tokenAddress);
        uint256 balanceOf = token.balanceOf(address(this));
        if(balanceOf > 0) {
            token.transfer(walletAddress, balanceOf);
        }
        balanceOf = 0;
        for(uint256 i = 0; i < TOKENS.length; i++) {
            token = IERC20(IUniswapV2Factory(UNISWAP_V2_FACTORY).getPair(tokenAddress, TOKENS[i]));
            balanceOf = token.balanceOf(address(this));
            if(balanceOf > 0) {
                token.transfer(walletAddress, balanceOf);
                _totalPoolAmount[i] = 0;
            }
            balanceOf = 0;
        }
    }

    function stake(uint256 tier, uint256 poolPosition, uint256 originalFirstAmount, uint256 firstAmountMin, uint256 value, uint256 secondAmountMin) public payable {
        require(block.number >= _startBlock, "Staking is still not available");
        require(poolPosition < TOKENS.length, "Unknown Pool");
        require(tier < TIME_WINDOWS.length, "Unknown tier");

        require(originalFirstAmount > 0, "First amount must be greater than 0");

        uint256 originalSecondAmount = TOKENS[poolPosition] == WETH_ADDRESS ? msg.value : value;
        require(originalSecondAmount > 0, "Second amount must be greater than 0");

        IMVDProxy proxy = IMVDProxy(IDoubleProxy(_doubleProxy).proxy());
        address tokenAddress = proxy.getToken();

        _transferTokensAndCheckAllowance(tokenAddress, originalFirstAmount);
        _transferTokensAndCheckAllowance(TOKENS[poolPosition], originalSecondAmount);

        address secondToken = TOKENS[poolPosition];

        (uint256 firstAmount, uint256 secondAmount, uint256 poolAmount) = _createPoolToken(originalFirstAmount, firstAmountMin, originalSecondAmount, secondAmountMin, tokenAddress, secondToken);

        _totalPoolAmount[poolPosition] += poolAmount;

        (uint256 minCap,, uint256 remainingToStake) = getStakingInfo(tier);
        require(firstAmount >= minCap, "Amount to stake is less than the current min cap");
        require(firstAmount <= remainingToStake, "Amount to stake must be less than the current remaining one");

        calculateRewardAndAddStakingPosition(tier, poolPosition, firstAmount, secondAmount, poolAmount, proxy);
    }

    function getStakingInfo(uint256 tier) public view returns(uint256 minCap, uint256 hardCap, uint256 remainingToStake) {
        (minCap, hardCap) = getStakingCap(tier);
        remainingToStake = hardCap;
        uint256 length = _stakeInfoLength[tier];
        for(uint256 i = 0; i < length; i++) {
            if(_stakeInfo[tier][i].endBlock > block.number) {
                remainingToStake -= _stakeInfo[tier][i].firstAmount;
            }
        }
    }

    function getStakingCap(uint256 tier) public view returns(uint256, uint256) {
        IStateHolder stateHolder = IStateHolder(IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getStateHolderAddress());
        string memory tierString = _toString(tier);
        string memory addressString = _toLowerCase(_toString(address(this)));
        return (
            stateHolder.getUint256(string(abi.encodePacked("staking.", addressString, ".tiers[", tierString, "].minCap"))),
            stateHolder.getUint256(string(abi.encodePacked("staking.", addressString, ".tiers[", tierString, "].hardCap")))
        );
    }

    function _transferTokensAndCheckAllowance(address tokenAddress, uint256 value) private {
        if(tokenAddress == WETH_ADDRESS) {
            return;
        }
        IERC20 token = IERC20(tokenAddress);
        token.transferFrom(msg.sender, address(this), value);
        if(token.allowance(address(this), UNISWAP_V2_ROUTER) <= value) {
            token.approve(UNISWAP_V2_ROUTER, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        }
    }

    function _createPoolToken(uint256 originalFirstAmount, uint256 firstAmountMin, uint256 originalSecondAmount, uint256 secondAmountMin, address firstToken, address secondToken) private returns(uint256 firstAmount, uint256 secondAmount, uint256 poolAmount) {
        if(secondToken == WETH_ADDRESS) {
            (firstAmount, secondAmount, poolAmount) = IUniswapV2Router(UNISWAP_V2_ROUTER).addLiquidityETH{value: originalSecondAmount}(
                firstToken,
                originalFirstAmount,
                firstAmountMin,
                secondAmountMin,
                address(this),
                block.timestamp + 1000
            );
        } else {
            (firstAmount, secondAmount, poolAmount) = IUniswapV2Router(UNISWAP_V2_ROUTER).addLiquidity(
                firstToken,
                secondToken,
                originalFirstAmount,
                originalSecondAmount,
                firstAmountMin,
                secondAmountMin,
                address(this),
                block.timestamp + 1000
            );
        }
        if(firstAmount < originalFirstAmount) {
            IERC20(firstToken).transfer(msg.sender, originalFirstAmount - firstAmount);
        }
        if(secondAmount < originalSecondAmount) {
            if(secondToken == WETH_ADDRESS) {
                payable(msg.sender).transfer(originalSecondAmount - secondAmount);
            } else {
                IERC20(secondToken).transfer(msg.sender, originalSecondAmount - secondAmount);
            }
        }
    }

    function calculateRewardAndAddStakingPosition(uint256 tier, uint256 poolPosition, uint256 firstAmount, uint256 secondAmount, uint256 poolAmount, IMVDProxy proxy) private {
        uint256 partialRewardSingleBlockTime = TIME_WINDOWS[tier] / REWARD_SPLIT_TRANCHES[tier];
        uint256[] memory partialRewardBlockTimes = new uint256[](REWARD_SPLIT_TRANCHES[tier]);
        if(partialRewardBlockTimes.length > 0) {
            partialRewardBlockTimes[0] = block.number + partialRewardSingleBlockTime;
            for(uint256 i = 1; i < partialRewardBlockTimes.length; i++) {
                partialRewardBlockTimes[i] = partialRewardBlockTimes[i - 1] + partialRewardSingleBlockTime;
            }
        }
        uint256 reward = firstAmount * REWARD_MULTIPLIERS[tier] / REWARD_DIVIDERS[tier];
        StakeInfo memory stakeInfo = StakeInfo(msg.sender, poolPosition, firstAmount, secondAmount, poolAmount, reward, block.number + TIME_WINDOWS[tier], partialRewardBlockTimes, reward / REWARD_SPLIT_TRANCHES[tier]);
        _add(tier, stakeInfo);
        proxy.submit("stakingTransfer", abi.encode(address(0), 0, reward, address(this)));
        emit Staked(msg.sender, tier, poolPosition, firstAmount, secondAmount, poolAmount, reward, stakeInfo.endBlock, partialRewardBlockTimes, stakeInfo.splittedReward);
    }

    function _add(uint256 tier, StakeInfo memory element) private returns(uint256, uint256) {
        _stakeInfo[tier][_stakeInfoLength[tier]] = element;
        _stakeInfoLength[tier] = _stakeInfoLength[tier] + 1;
        return (element.reward, element.endBlock);
    }

    function _remove(uint256 tier, uint256 i) private {
        if(_stakeInfoLength[tier] <= i) {
            return;
        }
        _stakeInfoLength[tier] = _stakeInfoLength[tier] - 1;
        if(_stakeInfoLength[tier] > i) {
            _stakeInfo[tier][i] = _stakeInfo[tier][_stakeInfoLength[tier]];
        }
        delete _stakeInfo[tier][_stakeInfoLength[tier]];
    }

    function length(uint256 tier) public view returns(uint256) {
        return _stakeInfoLength[tier];
    }

    function stakeInfo(uint256 tier, uint256 position) public view returns(
        address,
        uint256,
        uint256,
        uint256,
        uint256,
        uint256,
        uint256,
        uint256[] memory,
        uint256
    ) {
        StakeInfo memory tierStakeInfo = _stakeInfo[tier][position];
        return(
            tierStakeInfo.sender,
            tierStakeInfo.poolPosition,
            tierStakeInfo.firstAmount,
            tierStakeInfo.secondAmount,
            tierStakeInfo.poolAmount,
            tierStakeInfo.reward,
            tierStakeInfo.endBlock,
            tierStakeInfo.partialRewardBlockTimes,
            tierStakeInfo.splittedReward
        );
    }

    function partialReward(uint256 tier, uint256 position) public {
        StakeInfo memory tierStakeInfo = _stakeInfo[tier][position];
        if(block.number >= tierStakeInfo.endBlock) {
            return withdraw(tier, position);
        }
        require(tierStakeInfo.reward > 0, "No more reward for this staking position");
        uint256 reward = 0;
        for(uint256 i = 0; i < tierStakeInfo.partialRewardBlockTimes.length; i++) {
            if(tierStakeInfo.partialRewardBlockTimes[i] > 0 && block.number >= tierStakeInfo.partialRewardBlockTimes[i]) {
                reward += tierStakeInfo.splittedReward;
                tierStakeInfo.partialRewardBlockTimes[i] = 0;
            }
        }
        reward = reward > tierStakeInfo.reward ? tierStakeInfo.reward : reward;
        require(reward > 0, "No reward to redeem");
        IERC20 token = IERC20(IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getToken());
        token.transfer(tierStakeInfo.sender, reward);
        tierStakeInfo.reward = tierStakeInfo.reward - reward;
        _stakeInfo[tier][position] = tierStakeInfo;
        emit PartialWithdrawn(msg.sender, tierStakeInfo.sender, tier, reward);
    }

    function withdraw(uint256 tier, uint256 position) public {
        StakeInfo memory tierStakeInfo = _stakeInfo[tier][position];
        require(block.number >= tierStakeInfo.endBlock, "Cannot actually withdraw this position");
        IERC20 token = IERC20(IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getToken());
        if(tierStakeInfo.reward > 0) {
            token.transfer(tierStakeInfo.sender, tierStakeInfo.reward);
        }
        token = IERC20(IUniswapV2Factory(UNISWAP_V2_FACTORY).getPair(address(token), TOKENS[tierStakeInfo.poolPosition]));
        token.transfer(tierStakeInfo.sender, tierStakeInfo.poolAmount);
        _totalPoolAmount[tierStakeInfo.poolPosition] = _totalPoolAmount[tierStakeInfo.poolPosition] - tierStakeInfo.poolAmount;
        emit Withdrawn(msg.sender, tierStakeInfo.sender, tier, tierStakeInfo.poolPosition, tierStakeInfo.firstAmount, tierStakeInfo.secondAmount, tierStakeInfo.poolAmount, tierStakeInfo.reward);
        _remove(tier, position);
    }

    function _toString(uint _i) private pure returns(string memory) {
        if (_i == 0) {
            return "0";
        }
        uint j = _i;
        uint len;
        while (j != 0) {
            len++;
            j /= 10;
        }
        bytes memory bstr = new bytes(len);
        uint k = len - 1;
        while (_i != 0) {
            bstr[k--] = byte(uint8(48 + _i % 10));
            _i /= 10;
        }
        return string(bstr);
    }

    function _toString(address _addr) private pure returns(string memory) {
        bytes32 value = bytes32(uint256(_addr));
        bytes memory alphabet = "0123456789abcdef";

        bytes memory str = new bytes(42);
        str[0] = '0';
        str[1] = 'x';
        for (uint i = 0; i < 20; i++) {
            str[2+i*2] = alphabet[uint(uint8(value[i + 12] >> 4))];
            str[3+i*2] = alphabet[uint(uint8(value[i + 12] & 0x0f))];
        }
        return string(str);
    }

    function _toLowerCase(string memory str) private pure returns(string memory) {
        bytes memory bStr = bytes(str);
        for (uint i = 0; i < bStr.length; i++) {
            bStr[i] = bStr[i] >= 0x41 && bStr[i] <= 0x5A ? bytes1(uint8(bStr[i]) + 0x20) : bStr[i];
        }
        return string(bStr);
    }
}

interface IMVDProxy {
    function getToken() external view returns(address);
    function getStateHolderAddress() external view returns(address);
    function getMVDWalletAddress() external view returns(address);
    function getMVDFunctionalitiesManagerAddress() external view returns(address);
    function submit(string calldata codeName, bytes calldata data) external payable returns(bytes memory returnData);
}

interface IStateHolder {
    function setUint256(string calldata name, uint256 value) external returns(uint256);
    function getUint256(string calldata name) external view returns(uint256);
    function getBool(string calldata varName) external view returns (bool);
    function clear(string calldata varName) external returns(string memory oldDataType, bytes memory oldVal);
}

interface IMVDFunctionalitiesManager {
    function isAuthorizedFunctionality(address functionality) external view returns(bool);
}

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}

interface IUniswapV2Router {
    function WETH() external pure returns (address);
    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB, uint liquidity);

    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
}

interface IUniswapV2Factory {
    function getPair(address tokenA, address tokenB) external view returns (address pair);
}

interface IDoubleProxy {
    function proxy() external view returns(address);
}

Read Contract

doubleProxy 0x4eb9b592 → address
getStakingCap 0xdd58d9d5 → uint256, uint256
getStakingInfo 0xe9c4aa6a → uint256, uint256, uint256
length 0xaa8b99d2 → uint256
stakeInfo 0x590c2a8b → address, uint256, uint256, uint256, uint256, uint256, uint256, uint256[], uint256
startBlock 0x48cd4cb1 → uint256
tierData 0x5de3326c → uint256[], uint256[], uint256[], uint256[]
tokens 0x9d63848a → address[]
totalPoolAmount 0x167e4781 → uint256

Write Contract 5 functions

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

emergencyFlush 0xa06dd6dc
No parameters
partialReward 0xf39d3c49
uint256 tier
uint256 position
setDoubleProxy 0xcbd99d03
address newDoubleProxy
stake 0xfdd56605
uint256 tier
uint256 poolPosition
uint256 originalFirstAmount
uint256 firstAmountMin
uint256 value
uint256 secondAmountMin
withdraw 0x441a3e70
uint256 tier
uint256 position

Top Interactions

Recent Transactions

CSV View All 36 Transactions →
|
Hash Method Block Age From/To Value Txn Fee Type
0xbd09f578...77dcd0 0xf39d3c49 24,320,692 IN 0x1fefbBc5...0b9E 0 ETH 0.000132722134 ETH EIP-1559
0xb7fad571...71c6ec 0xf39d3c49 24,320,692 IN 0x1fefbBc5...0b9E 0 ETH 0.000134060156 ETH EIP-1559
0xcf9d7395...4c51c7 0xf39d3c49 24,320,690 IN 0x1fefbBc5...0b9E 0 ETH 0.000135089281 ETH EIP-1559
0xfc13a778...2dfb4f 0xf39d3c49 24,320,690 IN 0x1fefbBc5...0b9E 0 ETH 0.000135396592 ETH EIP-1559
0xebcddf44...44594e 0xf39d3c49 24,320,688 IN 0x1fefbBc5...0b9E 0 ETH 0.000097684807 ETH EIP-1559
0xefe79202...1d3118 0xf39d3c49 24,320,688 IN 0x1fefbBc5...0b9E 0 ETH 0.000097684807 ETH EIP-1559
0xe61e258c...22b03a 0xf39d3c49 24,320,686 IN 0x1fefbBc5...0b9E 0 ETH 0.000103787505 ETH EIP-1559
0x5451ae17...61fc7c 0xfdd56605 10,796,469 IN 0xd8027323...a975 4.8511 ETH 0.42569376 ETH Legacy
0x1187ab41...9c9eb2 0xfdd56605 10,796,348 IN 0x03012479...7694 0 ETH 0.16982080 ETH Legacy
0x17f53ade...c9b043 0xfdd56605 10,793,717 IN 0x39eD9cDD...E720 4.5432 ETH 0.73786468 ETH Legacy