Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0xB5303c22396333D9D27Dc45bDcC8E7Fc502b4B32
Balance 0 ETH
Nonce 1
Code Size 22344 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

22344 bytes
0x608060405234801561001057600080fd5b506004361061032b5760003560e01c806385b4bb53116101b2578063cf309012116100f9578063e4e99222116100a2578063f83d08ba1161007c578063f83d08ba14610a3a578063fc0c546a14610a42578063fccf894014610a4a578063fcd13d6514610aa95761032b565b8063e4e9922214610a0d578063e7ca4ef314610a15578063eec0701f14610a325761032b565b8063d78cd307116100d3578063d78cd3071461093f578063dd57194914610995578063e3270e3b1461099d5761032b565b8063cf309012146108ee578063cfbe49f2146108f6578063d2523526146109375761032b565b8063a948bd311161015b578063b84a207511610135578063b84a2075146107ca578063c7b60862146108de578063cdee9fbb146108e65761032b565b8063a948bd3114610797578063acdb8e04146107ba578063adbe95b1146107c25761032b565b806396bb1fef1161018c57806396bb1fef14610761578063a4e2d63414610787578063a69df4b51461078f5761032b565b806385b4bb53146106b65780638a1f3c02146106f3578063959a4ba21461073b5761032b565b80635797f7c11161027657806362d7c7c51161021f5780637ffdd081116101f95780637ffdd0811461068557806382d716c5146106a657806383c3774e146106ae5761032b565b806362d7c7c5146105fe5780636ff1c9bc1461065757806374c16b231461067d5761032b565b80635f94cd9c116102505780635f94cd9c1461059c57806360416b7a146105a4578063616281ff146105c75761032b565b80635797f7c1146105105780635d6e9e5e146105335780635dd189ff146105705761032b565b806332f98629116102d857806339069d8c116102b257806339069d8c146104a357806346edd016146104c957806348106fe3146105085761032b565b806332f98629146103f7578063333df1541461043957806337cedbeb1461045d5761032b565b80631c7bbde5116103095780631c7bbde51461036e5780632987cea0146103c75780632a1fac72146103ef5761032b565b806313e9728f146103305780631479d34d1461034a5780631a0b2c4f14610366575b600080fd5b610338610acf565b60408051918252519081900360200190f35b610352610ad5565b604080519115158252519081900360200190f35b610352610ae5565b6103946004803603602081101561038457600080fd5b50356001600160a01b0316610b09565b6040805195865260208601949094526001600160a01b039092168484015260608401526080830152519081900360a00190f35b6103ed600480360360208110156103dd57600080fd5b50356001600160a01b0316610b5b565b005b6103ed610bd8565b6103ed600480360360a081101561040d57600080fd5b506001600160a01b03813516906020810135906040810135906060810135151590608001351515610c82565b610441610e5c565b604080516001600160a01b039092168252519081900360200190f35b6104836004803603602081101561047357600080fd5b50356001600160a01b0316610e6b565b6040805163ffffffff909316835290151560208301528051918290030190f35b6103ed600480360360208110156104b957600080fd5b50356001600160a01b0316610e90565b6104ef600480360360208110156104df57600080fd5b50356001600160a01b0316610ef3565b6040805192835260208301919091528051918290030190f35b610352610f44565b6103ed6004803603602081101561052657600080fd5b503563ffffffff16610f54565b61053b611051565b604080516bffffffffffffffffffffffff948516815292909316602083015263ffffffff168183015290519081900360600190f35b6104ef6004803603604081101561058657600080fd5b506001600160a01b038135169060200135611089565b610441611178565b6103ed600480360360208110156105ba57600080fd5b503563ffffffff16611187565b6103ed600480360360408110156105dd57600080fd5b50803563ffffffff1690602001356bffffffffffffffffffffffff166112e3565b6106246004803603602081101561061457600080fd5b50356001600160a01b031661133d565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b6103ed6004803603602081101561066d57600080fd5b50356001600160a01b031661139f565b61044161157b565b61068d61158a565b6040805163ffffffff9092168252519081900360200190f35b6103386115a6565b6103386115ba565b6106be6115f1565b6040805195865263ffffffff948516602087015292841685840152921660608401529015156080830152519081900360a00190f35b6103ed600480360360c081101561070957600080fd5b506001600160a01b03813581169160208101359160408201358116916060810135916080820135169060a00135611691565b6103386004803603602081101561075157600080fd5b50356001600160a01b03166119d0565b6103ed6004803603602081101561077757600080fd5b50356001600160a01b0316611a5d565b610352611ebc565b6103ed611ecc565b6103ed600480360360208110156107ad57600080fd5b503563ffffffff16611f62565b6103ed612058565b6103ed6120fd565b6103ed600480360360808110156107e057600080fd5b8101906020810181356401000000008111156107fb57600080fd5b82018360208201111561080d57600080fd5b8035906020019184602083028401116401000000008311171561082f57600080fd5b91939092909160208101903564010000000081111561084d57600080fd5b82018360208201111561085f57600080fd5b8035906020019184602083028401116401000000008311171561088157600080fd5b91939092909160208101903564010000000081111561089f57600080fd5b8201836020820111156108b157600080fd5b803590602001918460208302840111640100000000831117156108d357600080fd5b9193509150356121f8565b61033861264d565b61068d612776565b610352612789565b6108fe612799565b60405180836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681526020019250505060405180910390f35b6103ed6128bf565b6109656004803603602081101561095557600080fd5b50356001600160a01b0316612947565b604080516bffffffffffffffffffffffff9485168152928416602084015292168183015290519081900360600190f35b61068d612985565b6103ed600480360360208110156109b357600080fd5b8101906020810181356401000000008111156109ce57600080fd5b8201836020820111156109e057600080fd5b80359060200191846020830284011164010000000083111715610a0257600080fd5b5090925090506129a5565b610441612e50565b6103ed60048036036020811015610a2b57600080fd5b5035612e5f565b6103ed612f88565b6103ed61308a565b610441613126565b610a7060048036036020811015610a6057600080fd5b50356001600160a01b0316613135565b604080516bffffffffffffffffffffffff9586168152938516602085015291841683830152909216606082015290519081900360800190f35b6103ed60048036036020811015610abf57600080fd5b50356001600160a01b031661317c565b60075481565b600454600160c01b900460ff1690565b600080546001600160a01b0316610afa6132fc565b6001600160a01b031614905090565b6000806000806000610b1961518d565b600080610b268942613300565b825160408401516020909401516bffffffffffffffffffffffff9182169e9482169d50929b5090911698509650945050505050565b610b63610ae5565b610b9e5760405162461bcd60e51b81526004018080602001828103825260408152602001806156566040913960400191505060405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b610be0610e5c565b6001600160a01b0316336001600160a01b031614610c2f5760405162461bcd60e51b81526004018080602001828103825260268152602001806154ca6026913960400191505060405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040517f2a2b3ea974fb057582c3b210ef8b5f81492d15673f49d4384bfa3b896a964c3c90600090a1565b600354600160a01b900460ff1615610ccb5760405162461bcd60e51b815260040180806020018281038252602581526020018061533f6025913960400191505060405180910390fd5b600b546001600160a01b03163314610d145760405162461bcd60e51b81526004018080602001828103825260248152602001806152446024913960400191505060405180910390fd5b600c54604080517f7c47c16d0000000000000000000000000000000000000000000000000000000081526001600160a01b03888116600483015291516000939290921691637c47c16d91602480820192602092909190829003018186803b158015610d7e57600080fd5b505afa158015610d92573d6000803e3d6000fd5b505050506040513d6020811015610da857600080fd5b50519050610db46151ad565b506040805160a0810182526004546bffffffffffffffffffffffff811682526c01000000000000000000000000810463ffffffff90811660208401527001000000000000000000000000000000008204811693830193909352600160a01b81049092166060820152600160c01b90910460ff1615156080820152610e3661518d565b610e4086836133db565b9050610e518886868a878688613545565b505050505050505050565b6002546001600160a01b031690565b60096020526000908152604090205463ffffffff811690640100000000900460ff1682565b610e98610e5c565b6001600160a01b0316336001600160a01b031614610ee75760405162461bcd60e51b81526004018080602001828103825260268152602001806154ca6026913960400191505060405180910390fd5b610ef0816136ac565b50565b600080610efe61518d565b610f088442613300565b50509050610f146151db565b610f1e8542613764565b505091516040909201516bffffffffffffffffffffffff92831696921694509092505050565b6002546001600160a01b03161590565b610f5c613986565b610f975760405162461bcd60e51b81526004018080602001828103825260248152602001806155236024913960400191505060405180910390fd5b620186a08163ffffffff161115610fdf5760405162461bcd60e51b815260040180806020018281038252604681526020018061529d6046913960600191505060405180910390fd5b6004805463ffffffff8316600160a01b81027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff9092169190911790915560408051918252517f41b601885e44600c749e03dfecdd2ff57bd9468338f4248162dcaf7172bad67b9181900360200190a150565b6006546bffffffffffffffffffffffff808216916c01000000000000000000000000810490911690600160c01b900463ffffffff1683565b6000806110946151db565b61109e8542613764565b505090506110aa61518d565b6110b48642613300565b505090506110c06151db565b6110d3876110ce42896139cb565b613764565b505090506110df61518d565b6110f2886110ed428a6139cb565b613300565b505083518151919250611116916bffffffffffffffffffffffff9081169116613a2c565b6bffffffffffffffffffffffff16955061115d84604001516bffffffffffffffffffffffff1683604001516bffffffffffffffffffffffff16613a2c90919063ffffffff16565b6bffffffffffffffffffffffff169450505050509250929050565b6001546001600160a01b031690565b61118f613986565b6111ca5760405162461bcd60e51b81526004018080602001828103825260248152602001806155236024913960400191505060405180910390fd5b620186a08163ffffffff1611156112125760405162461bcd60e51b815260040180806020018281038252604a815260200180615696604a913960600191505060405180910390fd5b60045463ffffffff600160a01b909104811690821611156112645760405162461bcd60e51b815260040180806020018281038252606b81526020018061545f606b913960800191505060405180910390fd5b6004805463ffffffff831670010000000000000000000000000000000081027fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff9092169190911790915560408051918252517f4d041e13c20fbec9dc54635af5ae0619f090f19f1f49046da068970e606741509181900360200190a150565b6112eb613986565b6113265760405162461bcd60e51b81526004018080602001828103825260248152602001806155236024913960400191505060405180910390fd5b61132e613ad0565b506113398282613beb565b5050565b60008060008060008061134e6151db565b60008061135b8a42613764565b6040830151606084015184516020909501516bffffffffffffffffffffffff9283169e509082169c509381169a509098509091169550935050505091939550919395565b6113a7613d76565b6113e25760405162461bcd60e51b815260040180806020018281038252602381526020018061556a6023913960400191505060405180910390fd5b604080513381526001600160a01b0383166020820152815183927ff5b6d8b404f034718f55a370884db03c4e27e9652e2636d4adcd0540d7c4203f928290030190a1806001600160a01b031663a9059cbb33836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561148157600080fd5b505afa158015611495573d6000803e3d6000fd5b505050506040513d60208110156114ab57600080fd5b5051604080517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b15801561151457600080fd5b505af1158015611528573d6000803e3d6000fd5b505050506040513d602081101561153e57600080fd5b50516113395760405162461bcd60e51b81526004018080602001828103825260338152602001806156e06033913960400191505060405180910390fd5b6000546001600160a01b031690565b6004546c01000000000000000000000000900463ffffffff1690565b6004546bffffffffffffffffffffffff1690565b6000806115c5612799565b9150506115eb600754826bffffffffffffffffffffffff16613db690919063ffffffff16565b91505090565b60008060008060006116016151ad565b50506040805160a0810182526004546bffffffffffffffffffffffff81168083526c01000000000000000000000000820463ffffffff9081166020850181905270010000000000000000000000000000000084048216958501869052600160a01b840490911660608501819052600160c01b90930460ff1615156080909401849052909890975092955093509150565b600354600160a01b900460ff16156116da5760405162461bcd60e51b815260040180806020018281038252602581526020018061533f6025913960400191505060405180910390fd5b600c546001600160a01b031633146117235760405162461bcd60e51b81526004018080602001828103825260268152602001806155ae6026913960400191505060405180910390fd5b61172b6151ad565b506040805160a081018252600480546bffffffffffffffffffffffff8116835263ffffffff6c010000000000000000000000008204811660208501527001000000000000000000000000000000008204811684860152600160a01b820416606084015260ff600160c01b909104161515608080840191909152600b5484517f5f1231ea0000000000000000000000000000000000000000000000000000000081526001600160a01b038c8116948201949094529451939460009485948594931692635f1231ea9260248082019391829003018186803b15801561180d57600080fd5b505afa158015611821573d6000803e3d6000fd5b505050506040513d608081101561183757600080fd5b5080516020820151606090920151909450909250905061185561518d565b61185f82866133db565b90506118696151db565b6118788c8687878f878c613545565b90506118868a8a8e84613df8565b8b6001600160a01b0316886001600160a01b0316146119c257600b54604080517f5f1231ea0000000000000000000000000000000000000000000000000000000081526001600160a01b038b8116600483015291519190921691635f1231ea916024808301926080929190829003018186803b15801561190557600080fd5b505afa158015611919573d6000803e3d6000fd5b505050506040513d608081101561192f57600080fd5b5080516020820151606090920151909650909450925061194d6151db565b61195c898788888c888d613545565b516001600160a01b038c166000908152600a6020526040902080546bffffffffffffffffffffffff9092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff909216919091179055505b505050505050505050505050565b6040805160a0810182526004546bffffffffffffffffffffffff811682526c01000000000000000000000000810463ffffffff90811660208401527001000000000000000000000000000000008204811693830193909352600160a01b81049092166060820152600160c01b90910460ff1615156080820152600090611a57908390613f3d565b92915050565b600354600160a01b900460ff1615611aa65760405162461bcd60e51b815260040180806020018281038252602581526020018061533f6025913960400191505060405180910390fd5b600080611ab283613fbe565b90925090506000611ac382846139cb565b905080611ad257505050610ef0565b6001600160a01b038416600090815260086020526040812060010154611b16906c0100000000000000000000000090046bffffffffffffffffffffffff1685614110565b6001600160a01b0386166000908152600860209081526040808320600190810180546bffffffffffffffffffffffff8088166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff90921691909117909155600a90935290832001549293509091611b9c911685614110565b6001600160a01b038781166000908152600a6020908152604080832060010180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff8716179055600554600e5482517f095ea7b30000000000000000000000000000000000000000000000000000000081529086166004820152602481018a905291519596509093169363095ea7b393604480820194918390030190829087803b158015611c5757600080fd5b505af1158015611c6b573d6000803e3d6000fd5b505050506040513d6020811015611c8157600080fd5b5051611cbe5760405162461bcd60e51b81526004018080602001828103825260238152602001806155476023913960400191505060405180910390fd5b604080516001808252818301909252606091602080830190803683370190505090508681600081518110611cee57fe5b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092526060918160200160208202803683370190505090508481600081518110611d3957fe5b602090810291909101810191909152600e546040517f19d6a88d000000000000000000000000000000000000000000000000000000008152600481018881526060602483019081528651606484015286516001600160a01b03909416946319d6a88d948b948994899490939092604483019260840191878101910280838360005b83811015611dd2578181015183820152602001611dba565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015611e11578181015183820152602001611df9565b5050505090500195505050505050600060405180830381600087803b158015611e3957600080fd5b505af1158015611e4d573d6000803e3d6000fd5b505060408051898152602081018b90526bffffffffffffffffffffffff808816828401528816606082015290516001600160a01b038c1693507f5f51e0cd4567b63928e199868f571929625ded3459b724759a0eb8edbf94158b92509081900360800190a25050505050505050565b600354600160a01b900460ff1690565b611ed4613d76565b611f0f5760405162461bcd60e51b815260040180806020018281038252602381526020018061556a6023913960400191505060405180910390fd5b600380547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556040517f19aad37188a1d3921e29eb3c66acf43d81975e107cb650d58cca878627955fd690600090a1565b600354600160a01b900460ff1615611fab5760405162461bcd60e51b815260040180806020018281038252602581526020018061533f6025913960400191505060405180910390fd5b620186a08163ffffffff161115611ff35760405162461bcd60e51b81526004018080602001828103825260338152602001806154f06033913960400191505060405180910390fd5b60045463ffffffff600160a01b909104811690821611156120455760405162461bcd60e51b815260040180806020018281038252605c8152602001806152e3605c913960600191505060405180910390fd5b61204e336141dd565b610ef033826143c3565b612060610ae5565b61209b5760405162461bcd60e51b81526004018080602001828103825260408152602001806156566040913960400191505060405180910390fd5b600080546040516001600160a01b03909116907f1f5f028be638d6a0e3b8d56fd05b812ce325cc8dc73cdb0e16df94d6b2725c2e908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b612105613d76565b6121405760405162461bcd60e51b815260040180806020018281038252602381526020018061556a6023913960400191505060405180910390fd5b600454600160c01b900460ff166121885760405162461bcd60e51b815260040180806020018281038252602a81526020018061521a602a913960400191505060405180910390fd5b61219061518d565b612198613ad0565b600480547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff16905590506121cb81614493565b506040517f9a68ce2011fec09202b5443f4484b1983ef6ad49111f730f49a65924f539d0e290600090a150565b6000805b8781101561224f5761224585858381811061221357fe5b9050602002013561223f89898581811061222957fe5b90506020020135856139cb90919063ffffffff16565b906139cb565b91506001016121fc565b5080821461228e5760405162461bcd60e51b81526004018080602001828103825260298152602001806155d46029913960400191505060405180910390fd5b811561236e57600554604080517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810185905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b15801561230757600080fd5b505af115801561231b573d6000803e3d6000fd5b505050506040513d602081101561233157600080fd5b505161236e5760405162461bcd60e51b815260040180806020018281038252602d8152602001806153e3602d913960400191505060405180910390fd5b60005b878110156125b9576123d987878381811061238857fe5b90506020020135600860008c8c8681811061239f57fe5b602090810292909201356001600160a01b0316835250810191909152604001600020600101546bffffffffffffffffffffffff1690614110565b600860008b8b858181106123e957fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b0316815260200190815260200160002060010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506124a785858381811061245957fe5b90506020020135600a60008c8c8681811061247057fe5b602090810292909201356001600160a01b0316835250810191909152604001600020546bffffffffffffffffffffffff1690614110565b600a60008b8b858181106124b757fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b0316815260200190815260200160002060000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555088888281811061252457fe5b905060200201356001600160a01b03166001600160a01b03167f3dc5ad7d2bcb290b59b40c376a1ba37e1dff2af15e74a8628e54890dcb02b5c13389898581811061256b57fe5b9050602002013588888681811061257e57fe5b9050602002013560405180846001600160a01b03168152602001838152602001828152602001935050505060405180910390a2600101612371565b506007546125c790836139cb565b6007556006546125f5906c0100000000000000000000000090046bffffffffffffffffffffffff1683614110565b600680546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9092169190911790555050505050505050565b600080600b60009054906101000a90046001600160a01b03166001600160a01b03166346cc116a6040518163ffffffff1660e01b815260040160606040518083038186803b15801561269e57600080fd5b505afa1580156126b2573d6000803e3d6000fd5b505050506040513d60608110156126c857600080fd5b50604090810151815160a0810183526004546bffffffffffffffffffffffff811682526c01000000000000000000000000810463ffffffff90811660208401527001000000000000000000000000000000008204811694830194909452600160a01b81049093166060820152600160c01b90920460ff161515608083015291506115eb90670de0b6b3a76400009061277090620186a09061276a908690614566565b906145d8565b90614631565b600454600160a01b900463ffffffff1690565b600354600160a01b900460ff1681565b6000806000600b60009054906101000a90046001600160a01b03166001600160a01b03166346cc116a6040518163ffffffff1660e01b815260040160606040518083038186803b1580156127ec57600080fd5b505afa158015612800573d6000803e3d6000fd5b505050506040513d606081101561281657600080fd5b5060400151905061282561518d565b6040805160a0810182526004546bffffffffffffffffffffffff811682526c01000000000000000000000000810463ffffffff90811660208401527001000000000000000000000000000000008204811693830193909352600160a01b81049092166060820152600160c01b90910460ff16151560808201526128ab9083904290614673565b508051602090910151909590945092505050565b6001546001600160a01b031633146129085760405162461bcd60e51b81526004018080602001828103825260278152602001806154386027913960400191505060405180910390fd5b60015461291d906001600160a01b03166136ac565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600a60205260009081526040902080546001909101546bffffffffffffffffffffffff808316926c0100000000000000000000000090048116911683565b600454700100000000000000000000000000000000900463ffffffff1690565b600454600160c01b900460ff16156129ee5760405162461bcd60e51b81526004018080602001828103825260358152602001806152686035913960400191505060405180910390fd5b60006129f8614794565b90506001600160a01b038116301415612a58576040805162461bcd60e51b815260206004820152601f60248201527f4e6577207265776172647320636f6e7472616374206973206e6f742073657400604482015290519081900360640190fd5b600060608367ffffffffffffffff81118015612a7357600080fd5b50604051908082528060200260200182016040528015612a9d578160200160208202803683370190505b50905060608467ffffffffffffffff81118015612ab957600080fd5b50604051908082528060200260200182016040528015612ae3578160200160208202803683370190505b50905060005b85811015612b8c57612b15878783818110612b0057fe5b905060200201356001600160a01b0316613fbe565b848381518110612b2157fe5b60200260200101848481518110612b3457fe5b6020026020010182815250828152505050612b82828281518110612b5457fe5b602002602001015161223f858481518110612b6b57fe5b6020026020010151876139cb90919063ffffffff16565b9350600101612ae9565b50600554604080517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790529151919092169163095ea7b39160448083019260209291908290030181600087803b158015612bfc57600080fd5b505af1158015612c10573d6000803e3d6000fd5b505050506040513d6020811015612c2657600080fd5b5051612c635760405162461bcd60e51b81526004018080602001828103825260258152602001806156316025913960400191505060405180910390fd5b836001600160a01b031663b84a207587878585886040518663ffffffff1660e01b81526004018080602001806020018060200185815260200184810384528989828181526020019250602002808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018681038552895181528951602091820193828c0193509102908190849084905b83811015612d1d578181015183820152602001612d05565b50505050905001848103825286818151815260200191508051906020019060200280838360005b83811015612d5c578181015183820152602001612d44565b5050505090500198505050505050505050600060405180830381600087803b158015612d8757600080fd5b505af1158015612d9b573d6000803e3d6000fd5b5050505060005b85811015612e4757868682818110612db657fe5b905060200201356001600160a01b03166001600160a01b03167f854216b077fbbbb1ec8c23db47ba2b21ceae54d75f2998d6b1ac80ee9881c83f848381518110612dfc57fe5b6020026020010151848481518110612e1057fe5b60209081029190910181015160408051938452918301526001600160a01b03891682820152519081900360600190a2600101612da2565b50505050505050565b6003546001600160a01b031690565b612e67613d76565b612ea25760405162461bcd60e51b815260040180806020018281038252602381526020018061556a6023913960400191505060405180910390fd5b600454600160c01b900460ff1615612eeb5760405162461bcd60e51b81526004018080602001828103825260288152602001806154106028913960400191505060405180910390fd5b600680547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b63ffffffff8416810291909117909155600480547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1690911790556040805182815290517f5a5cf98385bad94fae95d7079332030d7467c9a9ae3a8178d183290a5018398e916020908290030190a150565b612f90614855565b600b80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055612fd06148e5565b600c80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055613010614975565b600d80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055613050614a05565b600e80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b613092613d76565b6130cd5760405162461bcd60e51b815260040180806020018281038252602381526020018061556a6023913960400191505060405180910390fd5b600380547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790556040517f0f2e5b6c72c6a4491efd919a9f9a409f324ef0708c11ee57d410c2cb06c0992b90600090a1565b6005546001600160a01b031681565b600860205260009081526040902080546001909101546bffffffffffffffffffffffff808316926c0100000000000000000000000090819004821692808316929190041684565b613184614a95565b6131bf5760405162461bcd60e51b815260040180806020018281038252603e815260200180615364603e913960400191505060405180910390fd5b600354604080517f078cbb7c00000000000000000000000000000000000000000000000000000000815290516001600160a01b039283169284169163078cbb7c916004808301926020929190829003018186803b15801561321f57600080fd5b505afa158015613233573d6000803e3d6000fd5b505050506040513d602081101561324957600080fd5b50516001600160a01b0316146132905760405162461bcd60e51b81526004018080602001828103825260418152602001806153a26041913960600191505060405180910390fd5b600380546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915560408051918252517ffea2d033438b968078a6264409d0104b5f3d2ce7b795afc74918e70f3534f22b9181900360200190a150565b3390565b61330861518d565b600c54604080517ffab46d660000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152825160009485948594939091169263fab46d669260248083019392829003018186803b15801561337157600080fd5b505afa158015613385573d6000803e3d6000fd5b505050506040513d604081101561339b57600080fd5b50805160209091015190935090506133b16151db565b6133bb8487613764565b505090506133ca878383614af0565b919995985090965093945050505050565b6133e361518d565b816080015161343b5750604080516060810182526006546bffffffffffffffffffffffff80821683526c010000000000000000000000008204166020830152600160c01b900463ffffffff1691810191909152611a57565b6000613448844285614673565b81516006805460208086015160408088015163ffffffff16600160c01b027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff6bffffffffffffffffffffffff9384166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff949098167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090961686179390931696909617919091169490941790925582518481529182015281519395509193507f5830b366dc4564bf14d32116f14c979ac2c150a96b7c6b99bea717e6990d56ba92918290030190a15092915050565b61354d6151db565b60008060006135618b8b8b8b8b8b8b614bc5565b6001600160a01b038f1660008181526008602090815260409182902087518154928901517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009384166bffffffffffffffffffffffff928316177fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9081166c010000000000000000000000009284168302178455948a01516001909301805460608c0151951693831693841790951693909116908102929092179092559599509397509195509350917f3880098574881d40bf7b9775086fdc9e6d6edac939d881add769581473c84b4591869161365691614110565b87518a51604080519485526bffffffffffffffffffffffff9384166020860152918316848301526060840187905291909116608083015260a08201869052519081900360c00190a2505050979650505050505050565b6001600160a01b0381166136f15760405162461bcd60e51b81526004018080602001828103825260348152602001806155fd6034913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f1f5f028be638d6a0e3b8d56fd05b812ce325cc8dc73cdb0e16df94d6b2725c2e91a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b61376c6151db565b6000806137776151ad565b506040805160a081018252600480546bffffffffffffffffffffffff8116835263ffffffff6c010000000000000000000000008204811660208501527001000000000000000000000000000000008204811684860152600160a01b820416606084015260ff600160c01b909104161515608080840191909152600b5484517f5f1231ea0000000000000000000000000000000000000000000000000000000081526001600160a01b038b8116948201949094529451939460009485948594931692635f1231ea9260248082019391829003018186803b15801561385957600080fd5b505afa15801561386d573d6000803e3d6000fd5b505050506040513d608081101561388357600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190505050935050925092506000600c60009054906101000a90046001600160a01b03166001600160a01b0316637c47c16d8b6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561391d57600080fd5b505afa158015613931573d6000803e3d6000fd5b505050506040513d602081101561394757600080fd5b5051905061395361518d565b61395e838b88614673565b5090506139708b86878786868c614bc5565b929e909d50919b50909950505050505050505050565b60006139c66040518060400160405280601181526020017f66756e6374696f6e616c4d616e61676572000000000000000000000000000000815250614d5d565b905090565b600082820183811015613a25576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600081826bffffffffffffffffffffffff1614613a90576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b613a2583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614e8b565b613ad861518d565b600b54604080517f46cc116a00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b0316916346cc116a916004808301926060929190829003018186803b158015613b3657600080fd5b505afa158015613b4a573d6000803e3d6000fd5b505050506040513d6060811015613b6057600080fd5b50604090810151815160a0810183526004546bffffffffffffffffffffffff811682526c01000000000000000000000000810463ffffffff90811660208401527001000000000000000000000000000000008204811694830194909452600160a01b81049093166060820152600160c01b90920460ff161515608083015291506115eb9082906133db565b613bf36151ad565b506040805160a0810182526004805463ffffffff7001000000000000000000000000000000008083048216858701819052600160a01b808504841660608801819052600160c01b80870460ff16151560808a01819052958c166020808b018290526bffffffffffffffffffffffff8d16808c527fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090991689177fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c010000000000000000000000008302177fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff1695909602949094177fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff1691909202177fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff16930292909217909355845190815291820152825191927fca8985ddc364f44d5b848534640681ad74dee87e83386b2b801989769592f00a92918290030190a1505050565b60006139c66040518060400160405280601081526020017f6d6967726174696f6e4d616e6167657200000000000000000000000000000000815250614d5d565b6000613a2583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614f3f565b600080613e0361518d565b613e0e878786614af0565b6001600160a01b038a166000818152600a602090815260409182902086518154928801516bffffffffffffffffffffffff9081166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9282167fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009586168117939093161783559388015160019092018054929094169190921681179092559397509195509293507f411edbca4a882d6fbf12b557451a9358a63f73e3011a8c712885cb1e207120dd918691613ef091614110565b8751604080519384526bffffffffffffffffffffffff92831660208501526001600160a01b038b16848201529116606083015260808201869052519081900360a00190a250505050505050565b6000613f47615202565b506001600160a01b03831660009081526009602090815260409182902082518084019093525463ffffffff81168352640100000000900460ff161515908201819052613f97578260400151613f9a565b80515b63ffffffff169150613fb682846060015163ffffffff16614f91565b949350505050565b600080613fca836141dd565b50506001600160a01b038116600090815260086020908152604080832060010180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808216909255600a909352908320805491821690556bffffffffffffffffffffffff9182169291169061404082846139cb565b905061404a61518d565b50604080516060810182526006546bffffffffffffffffffffffff80821683526c010000000000000000000000008204166020830152600160c01b900463ffffffff1691810191909152600754808311156140ab576140a882614493565b90505b6140b58184613db6565b60075560208201516140d5906bffffffffffffffffffffffff1684613a2c565b6006600001600c6101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050915091565b600081826bffffffffffffffffffffffff1614614174576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b8282016bffffffffffffffffffffffff8085169082161015613a25576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6141e56151ad565b506040805160a081018252600480546bffffffffffffffffffffffff811683526c01000000000000000000000000810463ffffffff90811660208501527001000000000000000000000000000000008204811684860152600160a01b820416606080850191909152600160c01b90910460ff1615156080840152600b5484517f46cc116a000000000000000000000000000000000000000000000000000000008152945193946000946001600160a01b03909216936346cc116a93828201939092909190829003018186803b1580156142bd57600080fd5b505afa1580156142d1573d6000803e3d6000fd5b505050506040513d60608110156142e757600080fd5b506040015190506142f661518d565b61430082846133db565b600c54604080517ffab46d660000000000000000000000000000000000000000000000000000000081526001600160a01b03888116600483015282519495506000948594919091169263fab46d669260248082019391829003018186803b15801561436a57600080fd5b505afa15801561437e573d6000803e3d6000fd5b505050506040513d604081101561439457600080fd5b50805160209091015190925090506143aa6151db565b6143b5838588614fa7565b9050612e4787838584613df8565b60408051808201825263ffffffff838116808352600160208085019182526001600160a01b0388166000818152600983528790209551865493517fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009094169516949094177fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff1664010000000092151592909202919091179093558351908152925190927f6dfe6b1412aa34cec2188ca3d7de113a662f2cc283fec85f338571c7d52cece092908290030190a25050565b60075460208201516000906144b6906bffffffffffffffffffffffff1683613a2c565b600d54604080517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff939093166004840181905290519093506001600160a01b0390911691632e1a7d4d91602480830192600092919082900301818387803b15801561452f57600080fd5b505af1158015614543573d6000803e3d6000fd5b5050505061455a81836139cb90919063ffffffff16565b60078190559392505050565b600082156145cf576145ca61459d620186a0612770670de0b6b3a7640000866020015163ffffffff166145d890919063ffffffff16565b83516145c5908690612770906bffffffffffffffffffffffff16670de0b6b3a76400006145d8565b614f91565b613a25565b50600092915050565b6000826145e757506000611a57565b828202828482816145f457fe5b0414613a255760405162461bcd60e51b815260040180806020018281038252602181526020018061558d6021913960400191505060405180910390fd5b6000613a2583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506150f7565b61467b61518d565b50604080516060810182526006546bffffffffffffffffffffffff80821683526c010000000000000000000000008204166020830152600160c01b900463ffffffff169181019190915260808201516000901561478c576006546000906147009087906146fa90889063ffffffff600160c01b909104811690613db616565b8661515c565b60065490915061471e906bffffffffffffffffffffffff1682614110565b6bffffffffffffffffffffffff16835263ffffffff808616604085015261475790670de0b6b3a7640000906127709084908a906145d816565b6020840151909250614777906bffffffffffffffffffffffff1683614110565b6bffffffffffffffffffffffff166020840152505b935093915050565b600354604080517f35817773000000000000000000000000000000000000000000000000000000008152602060048201819052600e60248301527f7374616b696e6752657761726473000000000000000000000000000000000000604483015291516000936001600160a01b03169263358177739260648082019391829003018186803b15801561482457600080fd5b505afa158015614838573d6000803e3d6000fd5b505050506040513d602081101561484e57600080fd5b5051905090565b600354604080517f35817773000000000000000000000000000000000000000000000000000000008152602060048201819052600960248301527f636f6d6d69747465650000000000000000000000000000000000000000000000604483015291516000936001600160a01b03169263358177739260648082019391829003018186803b15801561482457600080fd5b600354604080517f35817773000000000000000000000000000000000000000000000000000000008152602060048201819052600b60248301527f64656c65676174696f6e73000000000000000000000000000000000000000000604483015291516000936001600160a01b03169263358177739260648082019391829003018186803b15801561482457600080fd5b600354604080517f35817773000000000000000000000000000000000000000000000000000000008152602060048201819052601460248301527f7374616b696e675265776172647357616c6c6574000000000000000000000000604483015291516000936001600160a01b03169263358177739260648082019391829003018186803b15801561482457600080fd5b600354604080517f35817773000000000000000000000000000000000000000000000000000000008152602060048201819052600760248301527f7374616b696e6700000000000000000000000000000000000000000000000000604483015291516000936001600160a01b03169263358177739260648082019391829003018186803b15801561482457600080fd5b6003546000906001600160a01b0316331480614ac95750614ab461157b565b6001600160a01b0316336001600160a01b0316145b806139c65750614ad7610e5c565b6001600160a01b0316336001600160a01b031614905090565b614af861518d565b506001600160a01b0383166000908152600a60209081526040808320815160608101835281546bffffffffffffffffffffffff80821683526c01000000000000000000000000909104811694820185905260019092015482169281019290925284519193928392614b6a921690613db6565b9050614b82670de0b6b3a764000061277083886145d8565b8351909250614b9f906bffffffffffffffffffffffff1683614110565b6bffffffffffffffffffffffff9081168452935190931660208301529094909350909150565b614bcd6151db565b506001600160a01b0387166000908152600860209081526040808320815160808101835281546bffffffffffffffffffffffff80821683526c010000000000000000000000009182900481169583019590955260019092015480851693820193909352910490911660608201529080808915614d2a5760208401518651614c65916bffffffffffffffffffffffff9182169116613db6565b91506000614c73838a6145d8565b90506000614c818d88613f3d565b90508815614ca357614c9e620186a06127708361276a868e614631565b614ca6565b60005b92506000614cb7620186a083613db6565b9050614cd4670de0b6b3a7640000612770620186a08187866145d8565b8751909650614cf1906bffffffffffffffffffffffff1685614110565b6bffffffffffffffffffffffff90811688526040880151614d13911687614110565b6bffffffffffffffffffffffff1660408801525050505b88614d36576000614d39565b85515b6bffffffffffffffffffffffff166020850152929a91995097509095509350505050565b6003546000906001600160a01b0316614d74614a95565b80613a2557506001600160a01b03811615801590613a2557506003546040517f1ee441e900000000000000000000000000000000000000000000000000000000815260206004820181815286516024840152865133946001600160a01b031693631ee441e99389939283926044019185019080838360005b83811015614e04578181015183820152602001614dec565b50505050905090810190601f168015614e315780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015614e4e57600080fd5b505afa158015614e62573d6000803e3d6000fd5b505050506040513d6020811015614e7857600080fd5b50516001600160a01b0316149392505050565b6000836bffffffffffffffffffffffff16836bffffffffffffffffffffffff1611158290614f375760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614efc578181015183820152602001614ee4565b50505050905090810190601f168015614f295780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008184841115614f375760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614efc578181015183820152602001614ee4565b6000818310614fa05781613a25565b5090919050565b614faf6151db565b600b54604080517f5f1231ea0000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152915160009384931691635f1231ea916024808301926080929190829003018186803b15801561501757600080fd5b505afa15801561502b573d6000803e3d6000fd5b505050506040513d608081101561504157600080fd5b508051602091820151600c54604080517f7c47c16d0000000000000000000000000000000000000000000000000000000081526001600160a01b03808d16600483015291519497509295506150ed948b948894859489941692637c47c16d92602480840193829003018186803b1580156150ba57600080fd5b505afa1580156150ce573d6000803e3d6000fd5b505050506040513d60208110156150e457600080fd5b50518a8a613545565b9695505050505050565b600081836151465760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614efc578181015183820152602001614ee4565b50600083858161515257fe5b0495945050505050565b60008315613a255760006151708584614566565b90506151846301e1338061277083876145d8565b95945050505050565b604080516060810182526000808252602082018190529181019190915290565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b60408051808201909152600080825260208201529056fe72657761726420646973747269627574696f6e20697320616c726561647920646561637469766174656463616c6c6572206973206e6f742074686520656c656374696f6e7320636f6e747261637452657761726420646973747269627574696f6e206d75737420626520646561637469766174656420666f72206d6967726174696f6e6d617844656c656761746f72735374616b696e675265776172647350657263656e744d696c6c65206d757374206e6f74206265206c6172676572207468616e2031303030303064656c656761746f725265776172647350657263656e744d696c6c65206d757374206e6f74206265206c6172676572207468616e206d617844656c656761746f72735374616b696e675265776172647350657263656e744d696c6c65636f6e7472616374206973206c6f636b656420666f722074686973206f7065726174696f6e73656e646572206973206e6f7420616e2061646d696e202872656769737472794d616e676572206f7220696e697469616c697a6174696f6e41646d696e296e657720636f6e7472616374207265676973747279206d7573742070726f76696465207468652070726576696f757320636f6e747261637420726567697374727961636365707452657761726442616c616e63654d6967726174696f6e3a207472616e73666572206661696c656472657761726420646973747269627574696f6e20697320616c72656164792061637469766174656443616c6c6572206973206e6f74207468652070656e64696e6720726567697374727941646d696e64656661756c7444656c656761746f72735374616b696e675265776172647350657263656e744d696c6c65206d757374206e6f74206265206c6172676572207468616e206d617844656c656761746f72735374616b696e675265776172647350657263656e744d696c6c6573656e646572206973206e6f742074686520696e697469616c697a6174696f6e2061646d696e64656c656761746f725265776172647350657263656e744d696c6c65206d75737420626520313030303030206174206d6f737473656e646572206973206e6f74207468652066756e6374696f6e616c206d616e61676572636c61696d5374616b696e67526577617264733a20617070726f7665206661696c656473656e646572206973206e6f7420746865206d6967726174696f6e206d616e61676572536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7763616c6c6572206973206e6f74207468652064656c65676174696f6e7320636f6e7472616374746f74616c416d6f756e7420646f6573206e6f74206d617463682073756d206f662072657761726473526567697374727941646d696e3a206e657720726567697374727941646d696e20697320746865207a65726f20616464726573736d6967726174655265776172647342616c616e63653a20617070726f7665206661696c656457697468436c61696d61626c6552656769737472794d616e6167656d656e743a2063616c6c6572206973206e6f742074686520726567697374727941646d696e64656661756c7444656c656761746f72735374616b696e675265776172647350657263656e744d696c6c65206d757374206e6f74206265206c6172676572207468616e203130303030305374616b696e67526577617264733a3a656d657267656e63795769746864726177202d207472616e73666572206661696c6564a26469706673582212205f96e076940b90b2d507fdaad317547c2e2bba329ec9ee9e7b228d7792d0e5f664736f6c634300060c0033

Verified Source Code Partial Match

Compiler: v0.6.12+commit.27d51765 EVM: istanbul Optimization: Yes (10000 runs)
StakingRewards.sol 2236 lines
// File: @openzeppelin/contracts/math/SafeMath.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
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;
    }
}

// File: contracts/SafeMath96.sol

pragma solidity 0.6.12;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath96 {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint96 a, uint256 b) internal pure returns (uint96) {
        require(uint256(uint96(b)) == b, "SafeMath: addition overflow");
        uint96 c = a + uint96(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(uint96 a, uint256 b) internal pure returns (uint96) {
        require(uint256(uint96(b)) == b, "SafeMath: subtraction overflow");
        return sub(a, uint96(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.
     *
     * _Available since v2.4.0._
     */
    function sub(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {
        require(b <= a, errorMessage);
        uint96 c = a - b;

        return c;
    }

}

// File: @openzeppelin/contracts/math/Math.sol

pragma solidity ^0.6.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol

pragma solidity ^0.6.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
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);
}

// File: contracts/spec_interfaces/ICommittee.sol

pragma solidity 0.6.12;

/// @title Committee contract interface
interface ICommittee {
	event CommitteeChange(address indexed addr, uint256 weight, bool certification, bool inCommittee);
	event CommitteeSnapshot(address[] addrs, uint256[] weights, bool[] certification);

	// No external functions

	/*
     * External functions
     */

    /// Notifies a weight change of a member
    /// @dev Called only by: Elections contract
    /// @param addr is the committee member address
    /// @param weight is the updated weight of the committee member
	function memberWeightChange(address addr, uint256 weight) external /* onlyElectionsContract onlyWhenActive */;

    /// Notifies a change in the certification of a member
    /// @dev Called only by: Elections contract
    /// @param addr is the committee member address
    /// @param isCertified is the updated certification state of the member
	function memberCertificationChange(address addr, bool isCertified) external /* onlyElectionsContract onlyWhenActive */;

    /// Notifies a member removal for example due to voteOut or voteUnready
    /// @dev Called only by: Elections contract
    /// @param memberRemoved is the removed committee member address
    /// @return memberRemoved indicates whether the member was removed from the committee
    /// @return removedMemberWeight indicates the removed member weight
    /// @return removedMemberCertified indicates whether the member was in the certified committee
	function removeMember(address addr) external returns (bool memberRemoved, uint removedMemberWeight, bool removedMemberCertified)/* onlyElectionContract */;

    /// Notifies a new member applicable for committee (due to registration, unbanning, certification change)
    /// The new member will be added only if it is qualified to join the committee 
    /// @dev Called only by: Elections contract
    /// @param addr is the added committee member address
    /// @param weight is the added member weight
    /// @param isCertified is the added member certification state
    /// @return memberAdded bool indicates whether the member was added
	function addMember(address addr, uint256 weight, bool isCertified) external returns (bool memberAdded)  /* onlyElectionsContract */;

    /// Checks if addMember() would add a the member to the committee (qualified to join)
    /// @param addr is the candidate committee member address
    /// @param weight is the candidate committee member weight
    /// @return wouldAddMember bool indicates whether the member will be added
	function checkAddMember(address addr, uint256 weight) external view returns (bool wouldAddMember);

    /// Returns the committee members and their weights
    /// @return addrs is the committee members list
    /// @return weights is an array of uint, indicating committee members list weight
    /// @return certification is an array of bool, indicating the committee members certification status
	function getCommittee() external view returns (address[] memory addrs, uint256[] memory weights, bool[] memory certification);

    /// Returns the currently appointed committee data
    /// @return generalCommitteeSize is the number of members in the committee
    /// @return certifiedCommitteeSize is the number of certified members in the committee
    /// @return totalWeight is the total effective stake (weight) of the committee
	function getCommitteeStats() external view returns (uint generalCommitteeSize, uint certifiedCommitteeSize, uint totalWeight);

    /// Returns a committee member data
    /// @param addr is the committee member address
    /// @return inCommittee indicates whether the queried address is a member in the committee
    /// @return weight is the committee member weight
    /// @return isCertified indicates whether the committee member is certified
    /// @return totalCommitteeWeight is the total weight of the committee.
	function getMemberInfo(address addr) external view returns (bool inCommittee, uint weight, bool isCertified, uint totalCommitteeWeight);

    /// Emits a CommitteeSnapshot events with current committee info
    /// @dev a CommitteeSnapshot is useful on contract migration or to remove the need to track past events.
	function emitCommitteeSnapshot() external;

	/*
	 * Governance functions
	 */

	event MaxCommitteeSizeChanged(uint8 newValue, uint8 oldValue);

    /// Sets the maximum number of committee members
    /// @dev governance function called only by the functional manager
    /// @dev when reducing the number of members, the bottom ones are removed from the committee
    /// @param _maxCommitteeSize is the maximum number of committee members 
	function setMaxCommitteeSize(uint8 _maxCommitteeSize) external /* onlyFunctionalManager */;

    /// Returns the maximum number of committee members
    /// @return maxCommitteeSize is the maximum number of committee members 
	function getMaxCommitteeSize() external view returns (uint8);
	
    /// Imports the committee members from a previous committee contract during migration
    /// @dev initialization function called only by the initializationManager
    /// @dev does not update the reward contract to avoid incorrect notifications 
    /// @param previousCommitteeContract is the address of the previous committee contract
	function importMembers(ICommittee previousCommitteeContract) external /* onlyInitializationAdmin */;
}

// File: contracts/spec_interfaces/IProtocolWallet.sol

pragma solidity 0.6.12;


/// @title Protocol Wallet interface
interface IProtocolWallet {
    event FundsAddedToPool(uint256 added, uint256 total);

    /*
    * External functions
    */

    /// Returns the address of the underlying staked token
    /// @return balance is the wallet balance
    function getBalance() external view returns (uint256 balance);

    /// Transfers the given amount of orbs tokens form the sender to this contract and updates the pool
    /// @dev assumes the caller approved the amount prior to calling
    /// @param amount is the amount to add to the wallet
    function topUp(uint256 amount) external;

    /// Withdraws from pool to the client address, limited by the pool's MaxRate.
    /// @dev may only be called by the wallet client
    /// @dev no more than MaxRate x time period since the last withdraw may be withdrawn
    /// @dev allocation that wasn't withdrawn can not be withdrawn in the next call
    /// @param amount is the amount to withdraw
    function withdraw(uint256 amount) external; /* onlyClient */


    /*
    * Governance functions
    */

    event ClientSet(address client);
    event MaxAnnualRateSet(uint256 maxAnnualRate);
    event EmergencyWithdrawal(address addr, address token);
    event OutstandingTokensReset(uint256 startTime);

    /// Sets a new annual withdraw rate for the pool
    /// @dev governance function called only by the migration owner
    /// @dev the rate for a duration is duration x annualRate / 1 year 
    /// @param _annualRate is the maximum annual rate that can be withdrawn
    function setMaxAnnualRate(uint256 _annualRate) external; /* onlyMigrationOwner */

    /// Returns the annual withdraw rate of the pool
    /// @return annualRate is the maximum annual rate that can be withdrawn
    function getMaxAnnualRate() external view returns (uint256);

    /// Resets the outstanding tokens to new start time
    /// @dev governance function called only by the migration owner
    /// @dev the next duration will be calculated starting from the given time
    /// @param startTime is the time to set as the last withdrawal time
    function resetOutstandingTokens(uint256 startTime) external; /* onlyMigrationOwner */

    /// Emergency withdraw the wallet funds
    /// @dev governance function called only by the migration owner
    /// @dev used in emergencies, when a migration to a new wallet is needed
    /// @param erc20 is the erc20 address of the token to withdraw
    function emergencyWithdraw(address erc20) external; /* onlyMigrationOwner */

    /// Sets the address of the client that can withdraw funds
    /// @dev governance function called only by the functional owner
    /// @param _client is the address of the new client
    function setClient(address _client) external; /* onlyFunctionalOwner */

}

// File: contracts/spec_interfaces/IStakingRewards.sol

pragma solidity 0.6.12;

/// @title Staking rewards contract interface
interface IStakingRewards {

    event DelegatorStakingRewardsAssigned(address indexed delegator, uint256 amount, uint256 totalAwarded, address guardian, uint256 delegatorRewardsPerToken, uint256 delegatorRewardsPerTokenDelta);
    event GuardianStakingRewardsAssigned(address indexed guardian, uint256 amount, uint256 totalAwarded, uint256 delegatorRewardsPerToken, uint256 delegatorRewardsPerTokenDelta, uint256 stakingRewardsPerWeight, uint256 stakingRewardsPerWeightDelta);
    event StakingRewardsClaimed(address indexed addr, uint256 claimedDelegatorRewards, uint256 claimedGuardianRewards, uint256 totalClaimedDelegatorRewards, uint256 totalClaimedGuardianRewards);
    event StakingRewardsAllocated(uint256 allocatedRewards, uint256 stakingRewardsPerWeight);
    event GuardianDelegatorsStakingRewardsPercentMilleUpdated(address indexed guardian, uint256 delegatorsStakingRewardsPercentMille);

    /*
     * External functions
     */

    /// Returns the current reward balance of the given address.
    /// @dev calculates the up to date balances (differ from the state)
    /// @param addr is the address to query
    /// @return delegatorStakingRewardsBalance the rewards awarded to the guardian role
    /// @return guardianStakingRewardsBalance the rewards awarded to the guardian role
    function getStakingRewardsBalance(address addr) external view returns (uint256 delegatorStakingRewardsBalance, uint256 guardianStakingRewardsBalance);

    /// Claims the staking rewards balance of an addr, staking the rewards
    /// @dev Claimed rewards are staked in the staking contract using the distributeRewards interface
    /// @dev includes the rewards for both the delegator and guardian roles
    /// @dev calculates the up to date rewards prior to distribute them to the staking contract
    /// @param addr is the address to claim rewards for
    function claimStakingRewards(address addr) external;

    /// Returns the current global staking rewards state
    /// @dev calculated to the latest block, may differ from the state read
    /// @return stakingRewardsPerWeight is the potential reward per 1E18 (TOKEN_BASE) committee weight assigned to a guardian was in the committee from day zero
    /// @return unclaimedStakingRewards is the of tokens that were assigned to participants and not claimed yet
    function getStakingRewardsState() external view returns (
        uint96 stakingRewardsPerWeight,
        uint96 unclaimedStakingRewards
    );

    /// Returns the current guardian staking rewards state
    /// @dev calculated to the latest block, may differ from the state read
    /// @dev notice that the guardian rewards are the rewards for the guardian role as guardian and do not include delegation rewards
    /// @dev use getDelegatorStakingRewardsData to get the guardian's rewards as delegator
    /// @param guardian is the guardian to query
    /// @return balance is the staking rewards balance for the guardian role
    /// @return claimed is the staking rewards for the guardian role that were claimed
    /// @return delegatorRewardsPerToken is the potential reward per token (1E18 units) assigned to a guardian's delegator that delegated from day zero
    /// @return delegatorRewardsPerTokenDelta is the increment in delegatorRewardsPerToken since the last guardian update
    /// @return lastStakingRewardsPerWeight is the up to date stakingRewardsPerWeight used for the guardian state calculation
    /// @return stakingRewardsPerWeightDelta is the increment in stakingRewardsPerWeight since the last guardian update
    function getGuardianStakingRewardsData(address guardian) external view returns (
        uint256 balance,
        uint256 claimed,
        uint256 delegatorRewardsPerToken,
        uint256 delegatorRewardsPerTokenDelta,
        uint256 lastStakingRewardsPerWeight,
        uint256 stakingRewardsPerWeightDelta
    );

    /// Returns the current delegator staking rewards state
    /// @dev calculated to the latest block, may differ from the state read
    /// @param delegator is the delegator to query
    /// @return balance is the staking rewards balance for the delegator role
    /// @return claimed is the staking rewards for the delegator role that were claimed
    /// @return guardian is the guardian the delegator delegated to receiving a portion of the guardian staking rewards
    /// @return lastDelegatorRewardsPerToken is the up to date delegatorRewardsPerToken used for the delegator state calculation
    /// @return delegatorRewardsPerTokenDelta is the increment in delegatorRewardsPerToken since the last delegator update
    function getDelegatorStakingRewardsData(address delegator) external view returns (
        uint256 balance,
        uint256 claimed,
        address guardian,
        uint256 lastDelegatorRewardsPerToken,
        uint256 delegatorRewardsPerTokenDelta
    );

    /// Returns an estimation for the delegator and guardian staking rewards for a given duration
    /// @dev the returned value is an estimation, assuming no change in the PoS state
    /// @dev the period calculated for start from the current block time until the current time + duration.
    /// @param addr is the address to estimate rewards for
    /// @param duration is the duration to calculate for in seconds
    /// @return estimatedDelegatorStakingRewards is the estimated reward for the delegator role
    /// @return estimatedGuardianStakingRewards is the estimated reward for the guardian role
    function estimateFutureRewards(address addr, uint256 duration) external view returns (
        uint256 estimatedDelegatorStakingRewards,
        uint256 estimatedGuardianStakingRewards
    );

    /// Sets the guardian's delegators staking reward portion
    /// @dev by default uses the defaultDelegatorsStakingRewardsPercentMille
    /// @param delegatorRewardsPercentMille is the delegators portion in percent-mille (0 - maxDelegatorsStakingRewardsPercentMille)
    function setGuardianDelegatorsStakingRewardsPercentMille(uint32 delegatorRewardsPercentMille) external;

    /// Returns a guardian's delegators staking reward portion
    /// @dev If not explicitly set, returns the defaultDelegatorsStakingRewardsPercentMille
    /// @return delegatorRewardsRatioPercentMille is the delegators portion in percent-mille
    function getGuardianDelegatorsStakingRewardsPercentMille(address guardian) external view returns (uint256 delegatorRewardsRatioPercentMille);

    /// Returns the amount of ORBS tokens in the staking rewards wallet allocated to staking rewards
    /// @dev The staking wallet balance must always larger than the allocated value
    /// @return allocated is the amount of tokens allocated in the staking rewards wallet
    function getStakingRewardsWalletAllocatedTokens() external view returns (uint256 allocated);

    /// Returns the current annual staking reward rate
    /// @dev calculated based on the current total committee weight
    /// @return annualRate is the current staking reward rate in percent-mille
    function getCurrentStakingRewardsRatePercentMille() external view returns (uint256 annualRate);

    /// Notifies an expected change in the committee membership of the guardian
    /// @dev Called only by: the Committee contract
    /// @dev called upon expected change in the committee membership of the guardian
    /// @dev triggers update of the global rewards state and the guardian rewards state
    /// @dev updates the rewards state based on the committee state prior to the change
    /// @param guardian is the guardian who's committee membership is updated
    /// @param weight is the weight of the guardian prior to the change
    /// @param totalCommitteeWeight is the total committee weight prior to the change
    /// @param inCommittee indicates whether the guardian was in the committee prior to the change
    /// @param inCommitteeAfter indicates whether the guardian is in the committee after the change
    function committeeMembershipWillChange(address guardian, uint256 weight, uint256 totalCommitteeWeight, bool inCommittee, bool inCommitteeAfter) external /* onlyCommitteeContract */;

    /// Notifies an expected change in a delegator and his guardian delegation state
    /// @dev Called only by: the Delegation contract
    /// @dev called upon expected change in a delegator's delegation state
    /// @dev triggers update of the global rewards state, the guardian rewards state and the delegator rewards state
    /// @dev on delegation change, updates also the new guardian and the delegator's lastDelegatorRewardsPerToken accordingly
    /// @param guardian is the delegator's guardian prior to the change
    /// @param guardianDelegatedStake is the delegated stake of the delegator's guardian prior to the change
    /// @param delegator is the delegator about to change delegation state
    /// @param delegatorStake is the stake of the delegator
    /// @param nextGuardian is the delegator's guardian after to the change
    /// @param nextGuardianDelegatedStake is the delegated stake of the delegator's guardian after to the change
    function delegationWillChange(address guardian, uint256 guardianDelegatedStake, address delegator, uint256 delegatorStake, address nextGuardian, uint256 nextGuardianDelegatedStake) external /* onlyDelegationsContract */;

    /*
     * Governance functions
     */

    event AnnualStakingRewardsRateChanged(uint256 annualRateInPercentMille, uint256 annualCap);
    event DefaultDelegatorsStakingRewardsChanged(uint32 defaultDelegatorsStakingRewardsPercentMille);
    event MaxDelegatorsStakingRewardsChanged(uint32 maxDelegatorsStakingRewardsPercentMille);
    event RewardDistributionActivated(uint256 startTime);
    event RewardDistributionDeactivated();
    event StakingRewardsBalanceMigrated(address indexed addr, uint256 guardianStakingRewards, uint256 delegatorStakingRewards, address toRewardsContract);
    event StakingRewardsBalanceMigrationAccepted(address from, address indexed addr, uint256 guardianStakingRewards, uint256 delegatorStakingRewards);
    event EmergencyWithdrawal(address addr, address token);

    /// Activates staking rewards allocation
    /// @dev governance function called only by the initialization admin
    /// @dev On migrations, startTime should be set to the previous contract deactivation time
    /// @param startTime sets the last assignment time
    function activateRewardDistribution(uint startTime) external /* onlyInitializationAdmin */;

    /// Deactivates fees and bootstrap allocation
    /// @dev governance function called only by the migration manager
    /// @dev guardians updates remain active based on the current perMember value
    function deactivateRewardDistribution() external /* onlyMigrationManager */;
    
    /// Sets the default delegators staking reward portion
    /// @dev governance function called only by the functional manager
    /// @param defaultDelegatorsStakingRewardsPercentMille is the default delegators portion in percent-mille(0 - maxDelegatorsStakingRewardsPercentMille)
    function setDefaultDelegatorsStakingRewardsPercentMille(uint32 defaultDelegatorsStakingRewardsPercentMille) external /* onlyFunctionalManager */;

    /// Returns the default delegators staking reward portion
    /// @return defaultDelegatorsStakingRewardsPercentMille is the default delegators portion in percent-mille
    function getDefaultDelegatorsStakingRewardsPercentMille() external view returns (uint32);

    /// Sets the maximum delegators staking reward portion
    /// @dev governance function called only by the functional manager
    /// @param maxDelegatorsStakingRewardsPercentMille is the maximum delegators portion in percent-mille(0 - 100,000)
    function setMaxDelegatorsStakingRewardsPercentMille(uint32 maxDelegatorsStakingRewardsPercentMille) external /* onlyFunctionalManager */;

    /// Returns the default delegators staking reward portion
    /// @return maxDelegatorsStakingRewardsPercentMille is the maximum delegators portion in percent-mille
    function getMaxDelegatorsStakingRewardsPercentMille() external view returns (uint32);

    /// Sets the annual rate and cap for the staking reward
    /// @dev governance function called only by the functional manager
    /// @param annualRateInPercentMille is the annual rate in percent-mille
    /// @param annualCap is the annual staking rewards cap
    function setAnnualStakingRewardsRate(uint32 annualRateInPercentMille, uint96 annualCap) external /* onlyFunctionalManager */;

    /// Returns the annual staking reward rate
    /// @return annualStakingRewardsRatePercentMille is the annual rate in percent-mille
    function getAnnualStakingRewardsRatePercentMille() external view returns (uint32);

    /// Returns the annual staking rewards cap
    /// @return annualStakingRewardsCap is the annual rate in percent-mille
    function getAnnualStakingRewardsCap() external view returns (uint256);

    /// Checks if rewards allocation is active
    /// @return rewardAllocationActive is a bool that indicates that rewards allocation is active
    function isRewardAllocationActive() external view returns (bool);

    /// Returns the contract's settings
    /// @return annualStakingRewardsCap is the annual rate in percent-mille
    /// @return annualStakingRewardsRatePercentMille is the annual rate in percent-mille
    /// @return defaultDelegatorsStakingRewardsPercentMille is the default delegators portion in percent-mille
    /// @return maxDelegatorsStakingRewardsPercentMille is the maximum delegators portion in percent-mille
    /// @return rewardAllocationActive is a bool that indicates that rewards allocation is active
    function getSettings() external view returns (
        uint annualStakingRewardsCap,
        uint32 annualStakingRewardsRatePercentMille,
        uint32 defaultDelegatorsStakingRewardsPercentMille,
        uint32 maxDelegatorsStakingRewardsPercentMille,
        bool rewardAllocationActive
    );

    /// Migrates the staking rewards balance of the given addresses to a new staking rewards contract
    /// @dev The new rewards contract is determined according to the contracts registry
    /// @dev No impact of the calling contract if the currently configured contract in the registry
    /// @dev may be called also while the contract is locked
    /// @param addrs is the list of addresses to migrate
    function migrateRewardsBalance(address[] calldata addrs) external;

    /// Accepts addresses balance migration from a previous rewards contract
    /// @dev the function may be called by any caller that approves the amounts provided for transfer
    /// @param addrs is the list migrated addresses
    /// @param migratedGuardianStakingRewards is the list of received guardian rewards balance for each address
    /// @param migratedDelegatorStakingRewards is the list of received delegator rewards balance for each address
    /// @param totalAmount is the total amount of staking rewards migrated for all addresses in the list. Must match the sum of migratedGuardianStakingRewards and migratedDelegatorStakingRewards lists.
    function acceptRewardsBalanceMigration(address[] calldata addrs, uint256[] calldata migratedGuardianStakingRewards, uint256[] calldata migratedDelegatorStakingRewards, uint256 totalAmount) external;

    /// Performs emergency withdrawal of the contract balance
    /// @dev called with a token to withdraw, should be called twice with the fees and bootstrap tokens
    /// @dev governance function called only by the migration manager
    /// @param erc20 is the ERC20 token to withdraw
    function emergencyWithdraw(address erc20) external /* onlyMigrationManager */;
}

// File: contracts/spec_interfaces/IDelegations.sol

pragma solidity 0.6.12;

/// @title Delegations contract interface
interface IDelegations /* is IStakeChangeNotifier */ {

    // Delegation state change events
	event DelegatedStakeChanged(address indexed addr, uint256 selfDelegatedStake, uint256 delegatedStake, address indexed delegator, uint256 delegatorContributedStake);

    // Function calls
	event Delegated(address indexed from, address indexed to);

	/*
     * External functions
     */

    /// Delegate your stake
    /// @dev updates the election contract on the changes in the delegated stake
    /// @dev updates the rewards contract on the upcoming change in the delegator's delegation state
    /// @param to is the address to delegate to
	function delegate(address to) external /* onlyWhenActive */;

    /// Refresh the address stake for delegation power based on the staking contract
    /// @dev Disabled stake change update notifications from the staking contract may create mismatches
    /// @dev refreshStake re-syncs the stake data with the staking contract
    /// @param addr is the address to refresh its stake
	function refreshStake(address addr) external /* onlyWhenActive */;

    /// Refresh the addresses stake for delegation power based on the staking contract
    /// @dev Batched version of refreshStake
    /// @dev Disabled stake change update notifications from the staking contract may create mismatches
    /// @dev refreshStakeBatch re-syncs the stake data with the staking contract
    /// @param addrs is the list of addresses to refresh their stake
	function refreshStakeBatch(address[] calldata addrs) external /* onlyWhenActive */;

    /// Returns the delegate address of the given address
    /// @param addr is the address to query
    /// @return delegation is the address the addr delegated to
	function getDelegation(address addr) external view returns (address);

    /// Returns a delegator info
    /// @param addr is the address to query
    /// @return delegation is the address the addr delegated to
    /// @return delegatorStake is the stake of the delegator as reflected in the delegation contract
	function getDelegationInfo(address addr) external view returns (address delegation, uint256 delegatorStake);
	
    /// Returns the delegated stake of an addr 
    /// @dev an address that is not self delegating has a 0 delegated stake
    /// @param addr is the address to query
    /// @return delegatedStake is the address delegated stake
	function getDelegatedStake(address addr) external view returns (uint256);

    /// Returns the total delegated stake
    /// @dev delegatedStake - the total stake delegated to an address that is self delegating
    /// @dev the delegated stake of a non self-delegated address is 0
    /// @return totalDelegatedStake is the total delegatedStake of all the addresses
	function getTotalDelegatedStake() external view returns (uint256) ;

	/*
	 * Governance functions
	 */

	event DelegationsImported(address[] from, address indexed to);

	event DelegationInitialized(address indexed from, address indexed to);

    /// Imports delegations during initial migration
    /// @dev initialization function called only by the initializationManager
    /// @dev Does not update the Rewards or Election contracts
    /// @dev assumes deactivated Rewards
    /// @param from is a list of delegator addresses
    /// @param to is the address the delegators delegate to
	function importDelegations(address[] calldata from, address to) external /* onlyMigrationManager onlyDuringDelegationImport */;

    /// Initializes the delegation of an address during initial migration 
    /// @dev initialization function called only by the initializationManager
    /// @dev behaves identically to a delegate transaction sent by the delegator
    /// @param from is the delegator addresses
    /// @param to is the delegator delegates to
	function initDelegation(address from, address to) external /* onlyInitializationAdmin */;
}

// File: contracts/IMigratableStakingContract.sol

pragma solidity 0.6.12;


/// @title An interface for staking contracts which support stake migration.
interface IMigratableStakingContract {
    /// @dev Returns the address of the underlying staked token.
    /// @return IERC20 The address of the token.
    function getToken() external view returns (IERC20);

    /// @dev Stakes ORBS tokens on behalf of msg.sender. This method assumes that the user has already approved at least
    /// the required amount using ERC20 approve.
    /// @param _stakeOwner address The specified stake owner.
    /// @param _amount uint256 The number of tokens to stake.
    function acceptMigration(address _stakeOwner, uint256 _amount) external;

    event AcceptedMigration(address indexed stakeOwner, uint256 amount, uint256 totalStakedAmount);
}

// File: contracts/IStakingContract.sol

pragma solidity 0.6.12;


/// @title An interface for staking contracts.
interface IStakingContract {
    /// @dev Stakes ORBS tokens on behalf of msg.sender. This method assumes that the user has already approved at least
    /// the required amount using ERC20 approve.
    /// @param _amount uint256 The amount of tokens to stake.
    function stake(uint256 _amount) external;

    /// @dev Unstakes ORBS tokens from msg.sender. If successful, this will start the cooldown period, after which
    /// msg.sender would be able to withdraw all of his tokens.
    /// @param _amount uint256 The amount of tokens to unstake.
    function unstake(uint256 _amount) external;

    /// @dev Requests to withdraw all of staked ORBS tokens back to msg.sender. Stake owners can withdraw their ORBS
    /// tokens only after previously unstaking them and after the cooldown period has passed (unless the contract was
    /// requested to release all stakes).
    function withdraw() external;

    /// @dev Restakes unstaked ORBS tokens (in or after cooldown) for msg.sender.
    function restake() external;

    /// @dev Distributes staking rewards to a list of addresses by directly adding rewards to their stakes. This method
    /// assumes that the user has already approved at least the required amount using ERC20 approve. Since this is a
    /// convenience method, we aren't concerned about reaching block gas limit by using large lists. We assume that
    /// callers will be able to properly batch/paginate their requests.
    /// @param _totalAmount uint256 The total amount of rewards to distribute.
    /// @param _stakeOwners address[] The addresses of the stake owners.
    /// @param _amounts uint256[] The amounts of the rewards.
    function distributeRewards(uint256 _totalAmount, address[] calldata _stakeOwners, uint256[] calldata _amounts) external;

    /// @dev Returns the stake of the specified stake owner (excluding unstaked tokens).
    /// @param _stakeOwner address The address to check.
    /// @return uint256 The total stake.
    function getStakeBalanceOf(address _stakeOwner) external view returns (uint256);

    /// @dev Returns the total amount staked tokens (excluding unstaked tokens).
    /// @return uint256 The total staked tokens of all stake owners.
    function getTotalStakedTokens() external view returns (uint256);

    /// @dev Returns the time that the cooldown period ends (or ended) and the amount of tokens to be released.
    /// @param _stakeOwner address The address to check.
    /// @return cooldownAmount uint256 The total tokens in cooldown.
    /// @return cooldownEndTime uint256 The time when the cooldown period ends (in seconds).
    function getUnstakeStatus(address _stakeOwner) external view returns (uint256 cooldownAmount,
        uint256 cooldownEndTime);

    /// @dev Migrates the stake of msg.sender from this staking contract to a new approved staking contract.
    /// @param _newStakingContract IMigratableStakingContract The new staking contract which supports stake migration.
    /// @param _amount uint256 The amount of tokens to migrate.
    function migrateStakedTokens(IMigratableStakingContract _newStakingContract, uint256 _amount) external;

    event Staked(address indexed stakeOwner, uint256 amount, uint256 totalStakedAmount);
    event Unstaked(address indexed stakeOwner, uint256 amount, uint256 totalStakedAmount);
    event Withdrew(address indexed stakeOwner, uint256 amount, uint256 totalStakedAmount);
    event Restaked(address indexed stakeOwner, uint256 amount, uint256 totalStakedAmount);
    event MigratedStake(address indexed stakeOwner, uint256 amount, uint256 totalStakedAmount);
}

// File: contracts/spec_interfaces/IManagedContract.sol

pragma solidity 0.6.12;

/// @title managed contract interface, used by the contracts registry to notify the contract on updates
interface IManagedContract /* is ILockable, IContractRegistryAccessor, Initializable */ {

    /// Refreshes the address of the other contracts the contract interacts with
    /// @dev called by the registry contract upon an update of a contract in the registry
    function refreshContracts() external;

}

// File: contracts/spec_interfaces/IContractRegistry.sol

pragma solidity 0.6.12;

/// @title Contract registry contract interface
/// @dev The contract registry holds Orbs PoS contracts and managers lists
/// @dev The contract registry updates the managed contracts on changes in the contract list
/// @dev Governance functions restricted to managers access the registry to retrieve the manager address 
/// @dev The contract registry represents the source of truth for Orbs Ethereum contracts 
/// @dev By tracking the registry events or query before interaction, one can access the up to date contracts 
interface IContractRegistry {

	event ContractAddressUpdated(string contractName, address addr, bool managedContract);
	event ManagerChanged(string role, address newManager);
	event ContractRegistryUpdated(address newContractRegistry);

	/*
	* External functions
	*/

    /// Updates the contracts address and emits a corresponding event
    /// @dev governance function called only by the migrationManager or registryAdmin
    /// @param contractName is the contract name, used to identify it
    /// @param addr is the contract updated address
    /// @param managedContract indicates whether the contract is managed by the registry and notified on changes
	function setContract(string calldata contractName, address addr, bool managedContract) external /* onlyAdminOrMigrationManager */;

    /// Returns the current address of the given contracts
    /// @param contractName is the contract name, used to identify it
    /// @return addr is the contract updated address
	function getContract(string calldata contractName) external view returns (address);

    /// Returns the list of contract addresses managed by the registry
    /// @dev Managed contracts are updated on changes in the registry contracts addresses 
    /// @return addrs is the list of managed contracts
	function getManagedContracts() external view returns (address[] memory);

    /// Locks all the managed contracts 
    /// @dev governance function called only by the migrationManager or registryAdmin
    /// @dev When set all onlyWhenActive functions will revert
	function lockContracts() external /* onlyAdminOrMigrationManager */;

    /// Unlocks all the managed contracts 
    /// @dev governance function called only by the migrationManager or registryAdmin
	function unlockContracts() external /* onlyAdminOrMigrationManager */;
	
    /// Updates a manager address and emits a corresponding event
    /// @dev governance function called only by the registryAdmin
    /// @dev the managers list is a flexible list of role to the manager's address
    /// @param role is the managers' role name, for example "functionalManager"
    /// @param manager is the manager updated address
	function setManager(string calldata role, address manager) external /* onlyAdmin */;

    /// Returns the current address of the given manager
    /// @param role is the manager name, used to identify it
    /// @return addr is the manager updated address
	function getManager(string calldata role) external view returns (address);

    /// Sets a new contract registry to migrate to
    /// @dev governance function called only by the registryAdmin
    /// @dev updates the registry address record in all the managed contracts
    /// @dev by tracking the emitted ContractRegistryUpdated, tools can track the up to date contracts
    /// @param newRegistry is the new registry contract 
	function setNewContractRegistry(IContractRegistry newRegistry) external /* onlyAdmin */;

    /// Returns the previous contract registry address 
    /// @dev used when the setting the contract as a new registry to assure a valid registry
    /// @return previousContractRegistry is the previous contract registry
	function getPreviousContractRegistry() external view returns (address);
}

// File: contracts/spec_interfaces/IContractRegistryAccessor.sol

pragma solidity 0.6.12;


interface IContractRegistryAccessor {

    /// Sets the contract registry address
    /// @dev governance function called only by an admin
    /// @param newRegistry is the new registry contract 
    function setContractRegistry(IContractRegistry newRegistry) external /* onlyAdmin */;

    /// Returns the contract registry address
    /// @return contractRegistry is the contract registry address
    function getContractRegistry() external view returns (IContractRegistry contractRegistry);

    function setRegistryAdmin(address _registryAdmin) external /* onlyInitializationAdmin */;

}

// File: @openzeppelin/contracts/GSN/Context.sol

pragma solidity ^0.6.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg....

// [truncated — 116611 bytes total]

Read Contract

delegatorsStakingRewards 0xd78cd307 → uint96, uint96, uint96
estimateFutureRewards 0x5dd189ff → uint256, uint256
getAnnualStakingRewardsCap 0x82d716c5 → uint256
getAnnualStakingRewardsRatePercentMille 0x7ffdd081 → uint32
getContractRegistry 0xe4e99222 → address
getCurrentStakingRewardsRatePercentMille 0xc7b60862 → uint256
getDefaultDelegatorsStakingRewardsPercentMille 0xdd571949 → uint32
getDelegatorStakingRewardsData 0x1c7bbde5 → uint256, uint256, address, uint256, uint256
getGuardianDelegatorsStakingRewardsPercentMille 0x959a4ba2 → uint256
getGuardianStakingRewardsData 0x62d7c7c5 → uint256, uint256, uint256, uint256, uint256, uint256
getMaxDelegatorsStakingRewardsPercentMille 0xcdee9fbb → uint32
getSettings 0x85b4bb53 → uint256, uint32, uint32, uint32, bool
getStakingRewardsBalance 0x46edd016 → uint256, uint256
getStakingRewardsState 0xcfbe49f2 → uint96, uint96
getStakingRewardsWalletAllocatedTokens 0x83c3774e → uint256
guardiansRewardSettings 0x37cedbeb → uint32, bool
guardiansStakingRewards 0xfccf8940 → uint96, uint96, uint96, uint96
initializationAdmin 0x333df154 → address
isInitializationComplete 0x48106fe3 → bool
isLocked 0xa4e2d634 → bool
isRegistryAdmin 0x1a0b2c4f → bool
isRewardAllocationActive 0x1479d34d → bool
locked 0xcf309012 → bool
pendingRegistryAdmin 0x5f94cd9c → address
registryAdmin 0x74c16b23 → address
stakingRewardsContractBalance 0x13e9728f → uint256
stakingRewardsState 0x5d6e9e5e → uint96, uint96, uint32
token 0xfc0c546a → address

Write Contract 21 functions

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

acceptRewardsBalanceMigration 0xb84a2075
address[] addrs
uint256[] migratedGuardianStakingRewards
uint256[] migratedDelegatorStakingRewards
uint256 totalAmount
activateRewardDistribution 0xe7ca4ef3
uint256 startTime
claimRegistryManagement 0xd2523526
No parameters
claimStakingRewards 0x96bb1fef
address addr
committeeMembershipWillChange 0x32f98629
address guardian
uint256 weight
uint256 totalCommitteeWeight
bool inCommittee
bool inCommitteeAfter
deactivateRewardDistribution 0xadbe95b1
No parameters
delegationWillChange 0x8a1f3c02
address guardian
uint256 guardianDelegatedStake
address delegator
uint256 delegatorStake
address nextGuardian
uint256 nextGuardianDelegatedStake
emergencyWithdraw 0x6ff1c9bc
address erc20
initializationComplete 0x2a1fac72
No parameters
lock 0xf83d08ba
No parameters
migrateRewardsBalance 0xe3270e3b
address[] addrs
refreshContracts 0xeec0701f
No parameters
renounceRegistryManagement 0xacdb8e04
No parameters
setAnnualStakingRewardsRate 0x616281ff
uint32 annualRateInPercentMille
uint96 annualCap
setContractRegistry 0xfcd13d65
address newContractRegistry
setDefaultDelegatorsStakingRewardsPercentMille 0x60416b7a
uint32 defaultDelegatorsStakingRewardsPercentMille
setGuardianDelegatorsStakingRewardsPercentMille 0xa948bd31
uint32 delegatorRewardsPercentMille
setMaxDelegatorsStakingRewardsPercentMille 0x5797f7c1
uint32 maxDelegatorsStakingRewardsPercentMille
setRegistryAdmin 0x39069d8c
address _registryAdmin
transferRegistryManagement 0x2987cea0
address newRegistryAdmin
unlock 0xa69df4b5
No parameters

Recent Transactions

No transactions found for this address