Address Contract Verified
Address
0x626D8eb5B818a712a9D50b74cdD8e205BD00BaE1
Balance
0 ETH
Nonce
1
Code Size
11544 bytes
Creator
0x7edBaC99...A853 at tx 0x1d6166eb...cb5995
Indexed Transactions
0
Contract Bytecode
11544 bytes
0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063864daf81116100de578063c0ab9cbc11610097578063f2fde38b11610071578063f2fde38b146105ec578063f502f77314610630578063f6888d1d1461064e578063f9f65de5146106925761018e565b8063c0ab9cbc1461055e578063e660e74714610568578063e95efda0146105865761018e565b8063864daf81146104175780638da5cb5b146104675780638da7ad231461049b578063947ef8a4146104fa578063abe50f1914610504578063b6715b5a146105545761018e565b8063715018a61161014b5780637c3a00fd116101255780637c3a00fd146103415780637d70b7d91461035f578063822094681461039357806384e77aa6146103e35761018e565b8063715018a6146102af5780637921b072146102b95780637bf34671146102fd5761018e565b80630c4d01c51461019357806338d07436146101b15780634d020e06146102015780635f84f3021461022f57806360e59e7b1461025d5780636532834f14610291575b600080fd5b61019b6106ca565b6040518082815260200191505060405180910390f35b6101e9600480360360408110156101c757600080fd5b81019080803590602001909291908035151590602001909291905050506106d0565b60405180821515815260200191505060405180910390f35b61022d6004803603602081101561021757600080fd5b8101908080359060200190929190505050610df4565b005b61025b6004803603602081101561024557600080fd5b8101908080359060200190929190505050610f4d565b005b6102656110a6565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102996110cc565b6040518082815260200191505060405180910390f35b6102b76110d2565b005b6102e7600480360360208110156102cf57600080fd5b81019080803515159060200190929190505050611258565b6040518082815260200191505060405180910390f35b6103296004803603602081101561031357600080fd5b8101908080359060200190929190505050611367565b60405180821515815260200191505060405180910390f35b61034961157b565b6040518082815260200191505060405180910390f35b610367611581565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103cb600480360360408110156103a957600080fd5b81019080803590602001909291908035151590602001909291905050506115a7565b60405180821515815260200191505060405180910390f35b6103eb6115c3565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61044f6004803603604081101561042d57600080fd5b81019080803590602001909291908035151590602001909291905050506115e9565b60405180821515815260200191505060405180910390f35b61046f611605565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104dd600480360360208110156104b157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061162e565b604051808381526020018281526020019250505060405180910390f35b610502611652565b005b61053c6004803603604081101561051a57600080fd5b8101908080359060200190929190803515159060200190929190505050611707565b60405180821515815260200191505060405180910390f35b61055c611d92565b005b610566611da4565b005b610570611e59565b6040518082815260200191505060405180910390f35b6105c86004803603602081101561059c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e5f565b60405180848152602001838152602001828152602001935050505060405180910390f35b61062e6004803603602081101561060257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e89565b005b610638612094565b6040518082815260200191505060405180910390f35b61067c6004803603602081101561066457600080fd5b81019080803515159060200190929190505050612423565b6040518082815260200191505060405180910390f35b6106c8600480360360408110156106a857600080fd5b8101908080359060200190929190803590602001909291905050506124d4565b005b60085481565b60008083905082156109f3576000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180606001604052908160008201548152602001600182015481526020016002820154815250509050600061075982602001516001612652565b905060008114156107b5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180612bc16036913960400191505060405180910390fd5b62ed4e008260400151420311610816576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180612cb7602c913960400191505060405180910390fd5b82811015610822578092505b6000610837848361281090919063ffffffff16565b9050600061090e600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7fb07b06040518163ffffffff1660e01b815260040160206040518083038186803b1580156108a657600080fd5b505afa1580156108ba573d6000803e3d6000fd5b505050506040513d60208110156108d057600080fd5b81019080805190602001909291905050506109006b033b2e3c9fd0803ce80000008561285a90919063ffffffff16565b6128e090919063ffffffff16565b905061093b846020015161092d8360095461292a90919063ffffffff16565b61281090919063ffffffff16565b60098190555061095484600001518560200151896129b2565b8511156109a35781600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055505b80600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555050505050610ca9565b6000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820154815260200160018201548152505090506000610a6682602001516000612652565b90506000811415610ac2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180612bf76036913960400191505060405180910390fd5b82811015610ace578092505b6000610af184610ae385602001516000612652565b61281090919063ffffffff16565b90506000610bc8600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7fb07b06040518163ffffffff1660e01b815260040160206040518083038186803b158015610b6057600080fd5b505afa158015610b74573d6000803e3d6000fd5b505050506040513d6020811015610b8a57600080fd5b8101908080519060200190929190505050610bba6b033b2e3c9fd0803ce80000008561285a90919063ffffffff16565b6128e090919063ffffffff16565b9050610bf58460200151610be78360085461292a90919063ffffffff16565b61281090919063ffffffff16565b600881905550610c0e84600001518560200151896129b2565b851115610c5d5781600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055505b80600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550505050505b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610d3c57600080fd5b505af1158015610d50573d6000803e3d6000fd5b505050506040513d6020811015610d6657600080fd5b8101908080519060200190929190505050610de9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5b452d33345d2d4661696c656420746f207472616e7366657220746f6b656e2e81525060200191505060405180910390fd5b600191505092915050565b610dfc612a0c565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ebc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6808984f0f048d16402a811115610f3b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5b452d3231315d2d43616e2774206265206d6f7265207468616e20353030252e81525060200191505060405180910390fd5b610f43611652565b8060058190555050565b610f55612a0c565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611015576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6808984f0f048d16402a811115611094576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5b452d3230325d2d43616e2774206265206d6f7265207468616e20353030252e81525060200191505060405180910390fd5b61109c611da4565b8060048190555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60095481565b6110da612a0c565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461119a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600081156112e8576000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806060016040529081600082015481526020016001820154815260200160028201548152505090506112e08160000151826020015160016129b2565b915050611362565b6000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180604001604052908160008201548152602001600182015481525050905061135e8160000151826020015160006129b2565b9150505b919050565b6000611371612a0c565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611431576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156114e257600080fd5b505af11580156114f6573d6000803e3d6000fd5b505050506040513d602081101561150c57600080fd5b8101908080519060200190929190505050611572576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612c2d6021913960400191505060405180910390fd5b60019050919050565b60045481565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006115b1611d92565b6115bb83836106d0565b905092915050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006115f3611d92565b6115fd8383611707565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60066020528060005260406000206000915090508060000154908060010154905082565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166382ab890a6005546040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156116c957600080fd5b505af11580156116dd573d6000803e3d6000fd5b505050506040513d60208110156116f357600080fd5b810190808051906020019092919050505050565b6000808311611761576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526048815260200180612c6f6048913960600191505060405180910390fd5b81156119f3576000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905060006117f6856117e884602001516001612652565b61292a90919063ffffffff16565b905060006118cd600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7fb07b06040518163ffffffff1660e01b815260040160206040518083038186803b15801561186557600080fd5b505afa158015611879573d6000803e3d6000fd5b505050506040513d602081101561188f57600080fd5b81019080805190602001909291905050506118bf6b033b2e3c9fd0803ce80000008561285a90919063ffffffff16565b6128e090919063ffffffff16565b90506118fa83602001516118ec8360095461292a90919063ffffffff16565b61281090919063ffffffff16565b60098190555061191786846000015161292a90919063ffffffff16565b600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555080600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555042600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550505050611c2a565b6000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820154815260200160018201548152505090506000611a7885611a6a84602001516000612652565b61292a90919063ffffffff16565b90506000611b4f600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7fb07b06040518163ffffffff1660e01b815260040160206040518083038186803b158015611ae757600080fd5b505afa158015611afb573d6000803e3d6000fd5b505050506040513d6020811015611b1157600080fd5b8101908080519060200190929190505050611b416b033b2e3c9fd0803ce80000008561285a90919063ffffffff16565b6128e090919063ffffffff16565b9050611b7c8360200151611b6e8360085461292a90919063ffffffff16565b61281090919063ffffffff16565b600881905550611b9986846000015161292a90919063ffffffff16565b600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555080600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055505050505b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330866040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015611cdb57600080fd5b505af1158015611cef573d6000803e3d6000fd5b505050506040513d6020811015611d0557600080fd5b8101908080519060200190929190505050611d88576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5b452d31325d2d4661696c656420746f207472616e7366657220746f6b656e2e81525060200191505060405180910390fd5b6001905092915050565b611d9a611da4565b611da2611652565b565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166382ab890a6004546040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015611e1b57600080fd5b505af1158015611e2f573d6000803e3d6000fd5b505050506040513d6020811015611e4557600080fd5b810190808051906020019092919050505050565b60055481565b60076020528060005260406000206000915090508060000154908060010154908060020154905083565b611e91612a0c565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611f51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611fd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612b9b6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600061209e612a0c565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461215e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156121e957600080fd5b505afa1580156121fd573d6000803e3d6000fd5b505050506040513d602081101561221357600080fd5b8101908080519060200190929190505050905060006122fd6b033b2e3c9fd0803ce80000006122ef600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7fb07b06040518163ffffffff1660e01b815260040160206040518083038186803b1580156122a357600080fd5b505afa1580156122b7573d6000803e3d6000fd5b505050506040513d60208110156122cd57600080fd5b810190808051906020019092919050505060085461285a90919063ffffffff16565b6128e090919063ffffffff16565b905060006123d66b033b2e3c9fd0803ce80000006123c8600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7fb07b06040518163ffffffff1660e01b815260040160206040518083038186803b15801561237c57600080fd5b505afa158015612390573d6000803e3d6000fd5b505050506040513d60208110156123a657600080fd5b810190808051906020019092919050505060095461285a90919063ffffffff16565b6128e090919063ffffffff16565b905061241b6123ee828461292a90919063ffffffff16565b61240d6b033b2e3c9fd0803ce80000008661285a90919063ffffffff16565b6128e090919063ffffffff16565b935050505090565b6000811561247f57612478600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101546001612652565b90506124cf565b6124cc600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101546000612652565b90505b919050565b6124dc612a0c565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461259c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6808984f0f048d16402a82111580156125be57506808984f0f048d16402a8111155b612630576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5b452d3232315d2d43616e2774206265206d6f7265207468616e20353030252e81525060200191505060405180910390fd5b612638611da4565b612640611652565b81600481905550806005819055505050565b600081156127345761272d6b033b2e3c9fd0803ce800000061271f600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7fb07b06040518163ffffffff1660e01b815260040160206040518083038186803b1580156126d557600080fd5b505afa1580156126e9573d6000803e3d6000fd5b505050506040513d60208110156126ff57600080fd5b81019080805190602001909291905050508661285a90919063ffffffff16565b6128e090919063ffffffff16565b905061280a565b6128076b033b2e3c9fd0803ce80000006127f9600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7fb07b06040518163ffffffff1660e01b815260040160206040518083038186803b1580156127af57600080fd5b505afa1580156127c3573d6000803e3d6000fd5b505050506040513d60208110156127d957600080fd5b81019080805190602001909291905050508661285a90919063ffffffff16565b6128e090919063ffffffff16565b90505b92915050565b600061285283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612a14565b905092915050565b60008083141561286d57600090506128da565b600082840290508284828161287e57fe5b04146128d5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612c4e6021913960400191505060405180910390fd5b809150505b92915050565b600061292283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612ad4565b905092915050565b6000808284019050838110156129a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6000806000905082156129d0576129c98484612652565b90506129dd565b6129da8484612652565b90505b8481116129ee576000915050612a05565b612a01858261281090919063ffffffff16565b9150505b9392505050565b600033905090565b6000838311158290612ac1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612a86578082015181840152602081019050612a6b565b50505050905090810190601f168015612ab35780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60008083118290612b80576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612b45578082015181840152602081019050612b2a565b50505050905090810190601f168015612b725780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581612b8c57fe5b04905080915050939250505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735b452d33315d2d546865206465706f73697420646f6573206e6f742065786973742c206661696c656420746f2077697468647261772e5b452d33335d2d546865206465706f73697420646f6573206e6f742065786973742c206661696c656420746f2077697468647261772e5b452d3233315d2d4661696c656420746f207472616e7366657220746f6b656e2e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775b452d31315d2d496e76616c69642076616c756520666f7220746865207374616b6520616d6f756e742c206661696c656420746f207374616b652061207a65726f2076616c75652e5b452d33325d2d46756e647320617265206e6f7420617661696c61626c6520666f722077697468647261772ea264697066735822122028ae430df900d33af02273d8d8935928e40a7964681dfb79607d3e6cc4641e1c64736f6c63430007060033
Verified Source Code Full Match
Compiler: v0.7.6+commit.7338295f
EVM: istanbul
Optimization: No
Staking2.sol 713 lines
pragma solidity ^0.7.0;
library DSMath {
/// @dev github.com/makerdao/dss implementation
/// of exponentiation by squaring
// nth power of x mod b
function rpow(uint x, uint n, uint b) internal pure returns (uint z) {
assembly {
switch x case 0 {switch n case 0 {z := b} default {z := 0}}
default {
switch mod(n, 2) case 0 { z := b } default { z := x }
let half := div(b, 2) // for rounding.
for { n := div(n, 2) } n { n := div(n,2) } {
let xx := mul(x, x)
if iszero(eq(div(xx, x), x)) { revert(0,0) }
let xxRound := add(xx, half)
if lt(xxRound, xx) { revert(0,0) }
x := div(xxRound, b)
if mod(n,2) {
let zx := mul(z, x)
if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
let zxRound := add(zx, half)
if lt(zxRound, zx) { revert(0,0) }
z := div(zxRound, b)
}
}
}
}
}
}
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// 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;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
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;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
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);
}
contract CompoundRateKeeper is Ownable {
using SafeMath for uint256;
struct CompoundRate {
uint256 rate;
uint256 lastUpdate;
}
CompoundRate public compoundRate;
constructor () {
compoundRate.rate = 1 * 10 ** 27;
compoundRate.lastUpdate = block.timestamp;
}
function getCurrentRate() view external returns(uint256) {
return compoundRate.rate;
}
function getLastUpdate() view external returns(uint256) {
return compoundRate.lastUpdate;
}
function update(uint256 _interestRate) external onlyOwner returns(uint256) {
uint256 _decimal = 10 ** 27;
uint256 _period = (block.timestamp).sub(compoundRate.lastUpdate);
uint256 _newRate = compoundRate.rate
.mul(DSMath.rpow(_interestRate.add(_decimal), _period, _decimal)).div(_decimal);
compoundRate.rate = _newRate;
compoundRate.lastUpdate = block.timestamp;
return _newRate;
}
}
interface IEpanStaking {
/**
* @notice Update compound rate
*/
function updateCompoundRate() external;
/**
* @notice Update compound rate timeframe
*/
function updateCompoundRateTimeframe() external;
/**
* @notice Update both compound rates
*/
function updateCompoundRates() external;
/**
* @notice Update compound rate and stake tokens to user balance
* @param _amount Amount to stake
* @param _isTimeframe If true, stake to timeframe structure
*/
function updateCompoundAndStake(uint256 _amount, bool _isTimeframe) external returns (bool);
/**
* @notice Update compound rate and withdraw tokens from contract
* @param _amount Amount to stake
* @param _isTimeframe If true, withdraw from timeframe structure
*/
function updateCompoundAndWithdraw(uint256 _amount, bool _isTimeframe) external returns (bool);
/**
* @notice Stake tokens to user balance
* @param _amount Amount to stake
* @param _isTimeframe If true, stake to timeframe structure
*/
function stake(uint256 _amount, bool _isTimeframe) external returns (bool);
/**
* @notice Withdraw tokens from user balance. Only for timeframe stake
* @param _amount Amount to withdraw
* @param _isTimeframe If true, withdraws from timeframe structure
*/
function withdraw(uint256 _amount, bool _isTimeframe) external returns (bool);
/**
* @notice Returns the staking balance of the user
* @param _isTimeframe If true, return balance from timeframe structure
*/
function getBalance(bool _isTimeframe) external view returns (uint256);
/**
* @notice Set interest rate
*/
function setInterestRate(uint256 _newInterestRate) external;
/**
* @notice Set interest rate timeframe
* @param _newInterestRate New interest rate
*/
function setInterestRateTimeframe(uint256 _newInterestRate) external;
/**
* @notice Set interest rates
* @param _newInterestRateTimeframe New interest rate timeframe
*/
function setInterestRates(uint256 _newInterestRate, uint256 _newInterestRateTimeframe) external;
/**
* @notice Add tokens to contract address to be spent as rewards
* @param _amount Token amount that will be added to contract as reward
*/
function supplyRewardPool(uint256 _amount) external returns (bool);
/**
* @notice Get reward amount for sender address
* @param _isTimeframe If timeframe, calculate reward for user from timeframe structure
*/
function getRewardAmount(bool _isTimeframe) external view returns (uint256);
/**
* @notice Get coefficient. Tokens on the contract / reward to be paid
*/
function monitorSecurityMargin() external view returns (uint256);
}
contract EpanStaking is IEpanStaking, Ownable {
using SafeMath for uint;
CompoundRateKeeper public compRateKeeper;
CompoundRateKeeper public compRateKeeperTimeframe;
IERC20 public epanToken;
struct Stake {
uint256 amount;
uint256 normalizedAmount;
}
struct StakeTimeframe {
uint256 amount;
uint256 normalizedAmount;
uint256 lastStakeTime;
}
uint256 public interestRate;
uint256 public interestRateTimeframe;
mapping(address => Stake) public userStakes;
mapping(address => StakeTimeframe) public userStakesTimeframe;
uint256 public aggregatedNormalizedStake;
uint256 public aggregatedNormalizedStakeTimeframe;
constructor(address _token, address _compRateKeeper, address _compRateKeeperTimeframe) {
compRateKeeper = CompoundRateKeeper(_compRateKeeper);
compRateKeeperTimeframe = CompoundRateKeeper(_compRateKeeperTimeframe);
epanToken = IERC20(_token);
}
/**
* @notice Update compound rate
*/
function updateCompoundRate() public override {
compRateKeeper.update(interestRate);
}
/**
* @notice Update compound rate timeframe
*/
function updateCompoundRateTimeframe() public override {
compRateKeeperTimeframe.update(interestRateTimeframe);
}
/**
* @notice Update both compound rates
*/
function updateCompoundRates() public override {
updateCompoundRate();
updateCompoundRateTimeframe();
}
/**
* @notice Update compound rate and stake tokens to user balance
* @param _amount Amount to stake
* @param _isTimeframe If true, stake to timeframe structure
*/
function updateCompoundAndStake(uint256 _amount, bool _isTimeframe) external override returns (bool) {
updateCompoundRates();
return stake(_amount, _isTimeframe);
}
/**
* @notice Update compound rate and withdraw tokens from contract
* @param _amount Amount to stake
* @param _isTimeframe If true, withdraw from timeframe structure
*/
function updateCompoundAndWithdraw(uint256 _amount, bool _isTimeframe) external override returns (bool) {
updateCompoundRates();
return withdraw(_amount, _isTimeframe);
}
/**
* @notice Stake tokens to user balance
* @param _amount Amount to stake
* @param _isTimeframe If true, stake to timeframe structure
*/
function stake(uint256 _amount, bool _isTimeframe) public override returns (bool) {
require(_amount > 0, "[E-11]-Invalid value for the stake amount, failed to stake a zero value.");
if (_isTimeframe) {
StakeTimeframe memory _stake = userStakesTimeframe[msg.sender];
uint256 _newAmount = _getBalance(_stake.normalizedAmount, true).add(_amount);
uint256 _newNormalizedAmount = _newAmount.mul(10 ** 27).div(compRateKeeperTimeframe.getCurrentRate());
aggregatedNormalizedStakeTimeframe = aggregatedNormalizedStakeTimeframe.add(_newNormalizedAmount)
.sub(_stake.normalizedAmount);
userStakesTimeframe[msg.sender].amount = _stake.amount.add(_amount);
userStakesTimeframe[msg.sender].normalizedAmount = _newNormalizedAmount;
userStakesTimeframe[msg.sender].lastStakeTime = block.timestamp;
} else {
Stake memory _stake = userStakes[msg.sender];
uint256 _newAmount = _getBalance(_stake.normalizedAmount, false).add(_amount);
uint256 _newNormalizedAmount = _newAmount.mul(10 ** 27).div(compRateKeeper.getCurrentRate());
aggregatedNormalizedStake = aggregatedNormalizedStake.add(_newNormalizedAmount)
.sub(_stake.normalizedAmount);
userStakes[msg.sender].amount = _stake.amount.add(_amount);
userStakes[msg.sender].normalizedAmount = _newNormalizedAmount;
}
require(epanToken.transferFrom(msg.sender, address(this), _amount), "[E-12]-Failed to transfer token.");
return true;
}
/**
* @notice Withdraw tokens from user balance. Only for timeframe stake
* @param _amount Amount to withdraw
* @param _isTimeframe If true, withdraws from timeframe structure
*/
function withdraw(uint256 _amount, bool _isTimeframe) public override returns (bool) {
uint256 _withdrawAmount = _amount;
if (_isTimeframe) {
StakeTimeframe memory _stake = userStakesTimeframe[msg.sender];
uint256 _userAmount = _getBalance(_stake.normalizedAmount, true);
require(_userAmount != 0, "[E-31]-The deposit does not exist, failed to withdraw.");
require(block.timestamp - _stake.lastStakeTime > 180 days, "[E-32]-Funds are not available for withdraw.");
if (_userAmount < _withdrawAmount) _withdrawAmount = _userAmount;
uint256 _newAmount = _userAmount.sub(_withdrawAmount);
uint256 _newNormalizedAmount = _newAmount.mul(10 ** 27).div(compRateKeeperTimeframe.getCurrentRate());
aggregatedNormalizedStakeTimeframe = aggregatedNormalizedStakeTimeframe.add(_newNormalizedAmount)
.sub(_stake.normalizedAmount);
if (_withdrawAmount > _getRewardAmount(_stake.amount, _stake.normalizedAmount, _isTimeframe)) {
userStakesTimeframe[msg.sender].amount = _newAmount;
}
userStakesTimeframe[msg.sender].normalizedAmount = _newNormalizedAmount;
} else {
Stake memory _stake = userStakes[msg.sender];
uint256 _userAmount = _getBalance(_stake.normalizedAmount, false);
require(_userAmount != 0, "[E-33]-The deposit does not exist, failed to withdraw.");
if (_userAmount < _withdrawAmount) _withdrawAmount = _userAmount;
uint256 _newAmount = _getBalance(_stake.normalizedAmount, false).sub(_withdrawAmount);
uint256 _newNormalizedAmount = _newAmount.mul(10 ** 27).div(compRateKeeper.getCurrentRate());
aggregatedNormalizedStake = aggregatedNormalizedStake.add(_newNormalizedAmount)
.sub(_stake.normalizedAmount);
if (_withdrawAmount > _getRewardAmount(_stake.amount, _stake.normalizedAmount, _isTimeframe)) {
userStakes[msg.sender].amount = _newAmount;
}
userStakes[msg.sender].normalizedAmount = _newNormalizedAmount;
}
require(epanToken.transfer(msg.sender, _withdrawAmount), "[E-34]-Failed to transfer token.");
return true;
}
/**
* @notice Returns the staking balance of the user
* @param _isTimeframe If true, return balance from timeframe structure
*/
function getBalance(bool _isTimeframe) public view override returns (uint256) {
if (_isTimeframe) {
return _getBalance(userStakesTimeframe[msg.sender].normalizedAmount, true);
}
return _getBalance(userStakes[msg.sender].normalizedAmount, false);
}
/**
* @notice Returns the staking balance of the user
* @param _normalizedAmount User normalized amount
* @param _isTimeframe If true, return balance from timeframe structure
*/
function _getBalance(uint256 _normalizedAmount, bool _isTimeframe) private view returns (uint256) {
if (_isTimeframe) {
return _normalizedAmount.mul(compRateKeeperTimeframe.getCurrentRate()).div(10 ** 27);
}
return _normalizedAmount.mul(compRateKeeper.getCurrentRate()).div(10 ** 27);
}
/**
* @notice Set interest rate
*/
function setInterestRate(uint256 _newInterestRate) external override onlyOwner {
require(_newInterestRate <= 158548959918822932522, "[E-202]-Can't be more than 500%.");
updateCompoundRate();
interestRate = _newInterestRate;
}
/**
* @notice Set interest rate timeframe
* @param _newInterestRate New interest rate
*/
function setInterestRateTimeframe(uint256 _newInterestRate) external override onlyOwner {
require(_newInterestRate <= 158548959918822932522, "[E-211]-Can't be more than 500%.");
updateCompoundRateTimeframe();
interestRateTimeframe = _newInterestRate;
}
/**
* @notice Set interest rates
* @param _newInterestRateTimeframe New interest rate timeframe
*/
function setInterestRates(uint256 _newInterestRate, uint256 _newInterestRateTimeframe) external override onlyOwner {
require(_newInterestRate <= 158548959918822932522 && _newInterestRateTimeframe <= 158548959918822932522,
"[E-221]-Can't be more than 500%.");
updateCompoundRate();
updateCompoundRateTimeframe();
interestRate = _newInterestRate;
interestRateTimeframe = _newInterestRateTimeframe;
}
/**
* @notice Add tokens to contract address to be spent as rewards
* @param _amount Token amount that will be added to contract as reward
*/
function supplyRewardPool(uint256 _amount) external override onlyOwner returns (bool) {
require(epanToken.transferFrom(msg.sender, address(this), _amount), "[E-231]-Failed to transfer token.");
return true;
}
/**
* @notice Get reward amount for sender address
* @param _isTimeframe If timeframe, calculate reward for user from timeframe structure
*/
function getRewardAmount(bool _isTimeframe) external view override returns (uint256) {
if (_isTimeframe) {
StakeTimeframe memory _stake = userStakesTimeframe[msg.sender];
return _getRewardAmount(_stake.amount, _stake.normalizedAmount, true);
}
Stake memory _stake = userStakes[msg.sender];
return _getRewardAmount(_stake.amount, _stake.normalizedAmount, false);
}
/**
* @notice Get reward amount by params
* @param _amount Token amount
* @param _normalizedAmount Normalized token amount
* @param _isTimeframe If timeframe, calculate reward for user from timeframe structure
*/
function _getRewardAmount(uint256 _amount, uint256 _normalizedAmount, bool _isTimeframe) private view returns (uint256) {
uint256 _balance = 0;
if (_isTimeframe) {
_balance = _getBalance(_normalizedAmount, _isTimeframe);
} else {
_balance = _getBalance(_normalizedAmount, _isTimeframe);
}
if (_balance <= _amount) return 0;
return _balance.sub(_amount);
}
/**
* @notice Get coefficient. Tokens on the contract / total stake + total reward to be paid
*/
function monitorSecurityMargin() external view override onlyOwner returns (uint256) {
uint256 _contractBalance = epanToken.balanceOf(address(this));
uint256 _toReward = aggregatedNormalizedStake.mul(compRateKeeper.getCurrentRate()).div(10 ** 27);
uint256 _toRewardTimeframe = aggregatedNormalizedStakeTimeframe.mul(compRateKeeperTimeframe.getCurrentRate())
.div(10 ** 27);
return _contractBalance.mul(10 ** 27).div(_toReward.add(_toRewardTimeframe));
}
}
Read Contract
aggregatedNormalizedStake 0x0c4d01c5 → uint256
aggregatedNormalizedStakeTimeframe 0x6532834f → uint256
compRateKeeper 0x7d70b7d9 → address
compRateKeeperTimeframe 0x60e59e7b → address
epanToken 0x84e77aa6 → address
getBalance 0xf6888d1d → uint256
getRewardAmount 0x7921b072 → uint256
interestRate 0x7c3a00fd → uint256
interestRateTimeframe 0xe660e747 → uint256
monitorSecurityMargin 0xf502f773 → uint256
owner 0x8da5cb5b → address
userStakes 0x8da7ad23 → uint256, uint256
userStakesTimeframe 0xe95efda0 → uint256, uint256, uint256
Write Contract 13 functions
These functions modify contract state and require a wallet transaction to execute.
renounceOwnership 0x715018a6
No parameters
setInterestRate 0x5f84f302
uint256 _newInterestRate
setInterestRateTimeframe 0x4d020e06
uint256 _newInterestRate
setInterestRates 0xf9f65de5
uint256 _newInterestRate
uint256 _newInterestRateTimeframe
stake 0xabe50f19
uint256 _amount
bool _isTimeframe
returns: bool
supplyRewardPool 0x7bf34671
uint256 _amount
returns: bool
transferOwnership 0xf2fde38b
address newOwner
updateCompoundAndStake 0x864daf81
uint256 _amount
bool _isTimeframe
returns: bool
updateCompoundAndWithdraw 0x82209468
uint256 _amount
bool _isTimeframe
returns: bool
updateCompoundRate 0xc0ab9cbc
No parameters
updateCompoundRateTimeframe 0x947ef8a4
No parameters
updateCompoundRates 0xb6715b5a
No parameters
withdraw 0x38d07436
uint256 _amount
bool _isTimeframe
returns: bool
Recent Transactions
No transactions found for this address