Address Contract Partially Verified
Address
0x47cE21BF9a4dC3CE3645C18c38A00D9DAc0Db136
Balance
0.018146 ETH ($35.99)
Nonce
1
Code Size
15803 bytes
Creator
0x53038604...6545 at tx 0xf273982a...011d0a
Indexed Transactions
0
Contract Bytecode
15803 bytes
0x6080604052600436106102085760003560e01c8063a969b18611610118578063c92d7169116100a0578063de37b7a11161006f578063de37b7a114610608578063dec3655414610637578063e25208e314610657578063f0359d1b14610677578063f2fde38b1461068c57610263565b8063c92d716914610588578063d172d3a3146105a8578063d2f31c39146105c8578063d4b94901146105e857610263565b8063b8a4aeaf116100e7578063b8a4aeaf14610509578063ba2d373c14610529578063c08da7a11461053e578063c5e6e35714610553578063c5f0a58f1461057357610263565b8063a969b1861461047c578063b0cd498b1461049c578063b384abef146104bc578063b3e9ba27146104dc57610263565b80634edd0d671161019b5780638769e3241161016a5780638769e324146103e75780638da5cb5b146104075780639d21ce9c1461041c5780639e3853ec1461043c5780639faf1d511461045c57610263565b80634edd0d6714610388578063715018a61461039d5780637ee1506d146103b2578063811c7fe2146103d257610263565b806335f8aa9b116101d757806335f8aa9b1461030f578063413f92c01461032457806341682744146103515780634d8f51051461037357610263565b8063026625851461026857806309f67b3a1461028857806322b143fb146102be57806329f6ff41146102e057610263565b3661026357336000908152600560205260409020546001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146102615760405162461bcd60e51b8152600401610258906136b4565b60405180910390fd5b005b600080fd5b34801561027457600080fd5b50610261610283366004613478565b6106ac565b34801561029457600080fd5b506102a86102a33660046131e0565b610901565b6040516102b59190613630565b60405180910390f35b3480156102ca57600080fd5b506102d3610916565b6040516102b591906135c0565b3480156102ec57600080fd5b506103006102fb366004613478565b610ae4565b6040516102b593929190613c93565b34801561031b57600080fd5b50610261610b17565b34801561033057600080fd5b5061034461033f3660046131e0565b610bfd565b6040516102b5919061356f565b34801561035d57600080fd5b50610366610c18565b6040516102b59190613c7c565b34801561037f57600080fd5b50610344610c3c565b34801561039457600080fd5b50610366610c60565b3480156103a957600080fd5b50610261610c66565b3480156103be57600080fd5b506102616103cd3660046132bb565b610ce5565b3480156103de57600080fd5b50610344610e10565b3480156103f357600080fd5b50610261610402366004613402565b610e34565b34801561041357600080fd5b506103446111fa565b34801561042857600080fd5b50610261610437366004613478565b611209565b34801561044857600080fd5b506103666104573660046132f3565b61139b565b34801561046857600080fd5b50610261610477366004613478565b61154d565b34801561048857600080fd5b506102616104973660046133d0565b6117c4565b3480156104a857600080fd5b506103446104b7366004613478565b611828565b3480156104c857600080fd5b506102616104d7366004613502565b61184f565b3480156104e857600080fd5b506104fc6104f7366004613478565b611900565b6040516102b59190613c59565b34801561051557600080fd5b506102d3610524366004613334565b611964565b34801561053557600080fd5b50610366611979565b34801561054a57600080fd5b5061036661199d565b34801561055f57600080fd5b506102d361056e3660046131e0565b6119a3565b34801561057f57600080fd5b506104fc611a65565b34801561059457600080fd5b506102a86105a33660046134cc565b611b11565b3480156105b457600080fd5b506102616105c3366004613249565b611b37565b3480156105d457600080fd5b506102616105e33660046131e0565b611b47565b3480156105f457600080fd5b506102616106033660046131fc565b611d53565b34801561061457600080fd5b506106286106233660046134a8565b611db8565b6040516102b59392919061363b565b34801561064357600080fd5b506103666106523660046134a8565b611de6565b34801561066357600080fd5b506102d3610672366004613368565b611f8f565b34801561068357600080fd5b50610344612007565b34801561069857600080fd5b506102616106a73660046131e0565b61202b565b6106b46120e1565b6000546001600160a01b039081169116146106e15760405162461bcd60e51b815260040161025890613b00565b600081116107015760405162461bcd60e51b815260040161025890613a6a565b6040516323b872dd60e01b81526001600160a01b037f000000000000000000000000dd974d5c2e2928dea5f71b9825b8b646686bd20016906323b872dd9061075190339030908690600401613583565b602060405180830381600087803b15801561076b57600080fd5b505af115801561077f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a39190613458565b6107bf5760405162461bcd60e51b815260040161025890613b35565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000dd974d5c2e2928dea5f71b9825b8b646686bd200169063095ea7b39061082d907f000000000000000000000000ecf0bdb7b3f349abfd68c3563678124c5e8aaea39085906004016135a7565b602060405180830381600087803b15801561084757600080fd5b505af115801561085b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087f9190613458565b5060405163b6b55f2560e01b81526001600160a01b037f000000000000000000000000ecf0bdb7b3f349abfd68c3563678124c5e8aaea3169063b6b55f25906108cc908490600401613c7c565b600060405180830381600087803b1580156108e657600080fd5b505af11580156108fa573d6000803e3d6000fd5b5050505050565b60066020526000908152604090205460ff1681565b606060007f00000000000000000000000049bdd8854481005bba4acebabf6e06cd5f6312e96001600160a01b0316634408d2ba6040518163ffffffff1660e01b815260040160206040518083038186803b15801561097357600080fd5b505afa158015610987573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ab9190613490565b905060006109df827f000000000000000000000000000000000000000000000000000000000000000363ffffffff6120e516565b90506060816001600160401b03811180156109f957600080fd5b50604051908082528060200260200182016040528015610a23578160200160208202803683370190505b50905060007f00000000000000000000000000000000000000000000000000000000000000035b84811015610a765780838381518110610a5f57fe5b602090810291909101015260019182019101610a4a565b50610adb826004805480602002602001604051908101604052809291908181526020018280548015610ad157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ab3575b5050505050612127565b94505050505090565b60038181548110610af157fe5b600091825260209091206003909102018054600182015460029092015490925060ff1683565b60038054600091906000198101908110610b2d57fe5b9060005260206000209060030201905060007f00000000000000000000000049bdd8854481005bba4acebabf6e06cd5f6312e96001600160a01b0316634408d2ba6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b9857600080fd5b505afa158015610bac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd09190613490565b905080826000015411158015610beb5750600282015460ff16155b15610bf957610bf98261233a565b5050565b6005602052600090815260409020546001600160a01b031681565b7f000000000000000000000000000000000000000000000000000000000000000381565b7f00000000000000000000000049bdd8854481005bba4acebabf6e06cd5f6312e981565b60045490565b610c6e6120e1565b6000546001600160a01b03908116911614610c9b5760405162461bcd60e51b815260040161025890613b00565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b610ced6120e1565b6000546001600160a01b03908116911614610d1a5760405162461bcd60e51b815260040161025890613b00565b6001600160a01b038216610d405760405162461bcd60e51b81526004016102589061392f565b6001600160a01b038281166000908152600560205260409020541615610d785760405162461bcd60e51b8152600401610258906138aa565b60048054600181019091557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b038085166001600160a01b03199283168117909355600083815260056020526040808220805487851695169490941793849055519290911692917fff2847fd2ae19fe4c306a71befdc972f378c04028957c133235dd59d325e23669190a35050565b7f000000000000000000000000dd974d5c2e2928dea5f71b9825b8b646686bd20081565b6000825111610e555760405162461bcd60e51b815260040161025890613b6a565b610e5e8261238d565b610e7a5760405162461bcd60e51b815260040161025890613974565b6000815111610e9b5760405162461bcd60e51b815260040161025890613867565b606081516001600160401b0381118015610eb457600080fd5b50604051908082528060200260200182016040528015610ede578160200160208202803683370190505b5090506000805b845181101561114f576000858281518110610efc57fe5b60200260200101519050610f1081846123f5565b9250600060038481548110610f2157fe5b60009182526020909120600390910201600281015490915060ff16610f4957610f498161233a565b6000807f000000000000000000000000ecf0bdb7b3f349abfd68c3563678124c5e8aaea36001600160a01b03166316554d6230866040518363ffffffff1660e01b8152600401610f9a9291906135a7565b60606040518083038186803b158015610fb257600080fd5b505afa158015610fc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fea9190613523565b50909250905060005b885181101561113e57611004612ff4565b611050868b848151811061101457fe5b602090810291909101810151604080516060810182528a54815260018b01549381019390935260028a015460ff16151590830152908787612490565b90508060400151600014156110655750611136565b61108f8160c001518a848151811061107957fe5b60200260200101516126c990919063ffffffff16565b89838151811061109b57fe5b602002602001018181525050600660008b84815181106110b757fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16611134576001600660008c85815181106110f457fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055505b505b600101610ff3565b505060019093019250610ee5915050565b50600061115a6111fa565b905060005b83518110156111f2576111ea6005600087848151811061117b57fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316838684815181106111c457fe5b60200260200101516040518060600160405280602a8152602001613d32602a91396126ee565b60010161115f565b505050505050565b6000546001600160a01b031690565b6112116120e1565b6000546001600160a01b0390811691161461123e5760405162461bcd60e51b815260040161025890613b00565b6000811161125e5760405162461bcd60e51b8152600401610258906139f2565b604051632e1a7d4d60e01b81526001600160a01b037f000000000000000000000000ecf0bdb7b3f349abfd68c3563678124c5e8aaea31690632e1a7d4d906112aa908490600401613c7c565b600060405180830381600087803b1580156112c457600080fd5b505af11580156112d8573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000dd974d5c2e2928dea5f71b9825b8b646686bd20016925063a9059cbb915061132a90339085906004016135a7565b602060405180830381600087803b15801561134457600080fd5b505af1158015611358573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137c9190613458565b6113985760405162461bcd60e51b8152600401610258906137ac565b50565b60008281526002602090815260408083206001600160a01b038516845290915281205460ff166113cd57506000611546565b60008381526001602090815260408083206001600160a01b038089168552908352818420908616845290915290205460ff161561140c57506000611546565b6000807f000000000000000000000000ecf0bdb7b3f349abfd68c3563678124c5e8aaea36001600160a01b03166342ce39cb87876040518363ffffffff1660e01b815260040161145d9291906135a7565b60606040518083038186803b15801561147557600080fd5b505afa158015611489573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ad9190613523565b925050915081600014156114c657600092505050611546565b6001600160a01b03811630146114e157600092505050611546565b6114e9613043565b5060008581526002602081815260408084206001600160a01b03891685528252928390208351606081018552815460ff161515815260018201549281018390529201549282018390529091611540918591906127b4565b93505050505b9392505050565b6115556120e1565b6000546001600160a01b039081169116146115825760405162461bcd60e51b815260040161025890613b00565b6127108111156115a45760405162461bcd60e51b8152600401610258906138e1565b60007f00000000000000000000000049bdd8854481005bba4acebabf6e06cd5f6312e96001600160a01b0316634408d2ba6040518163ffffffff1660e01b815260040160206040518083038186803b1580156115ff57600080fd5b505afa158015611613573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116379190613490565b9050600061166b827f000000000000000000000000000000000000000000000000000000000000000263ffffffff6126c916565b60038054919250600091600019810190811061168357fe5b9060005260206000209060030201905082816000015411156116ae5781815560018101849055611775565b600281015460ff166116c3576116c38161233a565b60408051606081018252838152602081018681526000928201838152600380546001810182559481905292517fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b9490930293840192909255517fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c830155517fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85d909101805460ff19169115159190911790555b7f2803ffe778731e96b0cb4ffdea51f618e2dc70ed59841f65fb6a92296b3960686117a783600163ffffffff6120e516565b856040516117b6929190613c85565b60405180910390a150505050565b61139881600480548060200260200160405190810160405280929190818152602001828054801561181e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611800575b5050505050610e34565b6004818154811061183557fe5b6000918252602090912001546001600160a01b0316905081565b6118576120e1565b6000546001600160a01b039081169116146118845760405162461bcd60e51b815260040161025890613b00565b60405163b384abef60e01b81526001600160a01b037f00000000000000000000000049bdd8854481005bba4acebabf6e06cd5f6312e9169063b384abef906118d29085908590600401613c85565b600060405180830381600087803b1580156118ec57600080fd5b505af11580156111f2573d6000803e3d6000fd5b611908613066565b60036119158360006123f5565b8154811061191f57fe5b60009182526020918290206040805160608101825260039093029091018054835260018101549383019390935260029092015460ff1615159181019190915292915050565b60606119718484846127ca565b949350505050565b7f000000000000000000000000000000000000000000000000000000000000000281565b60035490565b606060007f00000000000000000000000049bdd8854481005bba4acebabf6e06cd5f6312e96001600160a01b0316634408d2ba6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a0057600080fd5b505afa158015611a14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a389190613490565b9050611546837f0000000000000000000000000000000000000000000000000000000000000003836127ca565b611a6d613066565b60007f00000000000000000000000049bdd8854481005bba4acebabf6e06cd5f6312e96001600160a01b0316634408d2ba6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ac857600080fd5b505afa158015611adc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b009190613490565b9050611b0b81611900565b91505090565b600160209081526000938452604080852082529284528284209052825290205460ff1681565b611b428383836128cb565b505050565b611b4f6120e1565b6000546001600160a01b03908116911614611b7c5760405162461bcd60e51b815260040161025890613b00565b6001600160a01b0381811660009081526005602052604090205416611bb35760405162461bcd60e51b8152600401610258906139bb565b6001600160a01b03811660009081526006602052604090205460ff1615611bec5760405162461bcd60e51b815260040161025890613809565b600480546001600160a01b03831691906000198101908110611c0a57fe5b6000918252602090912001546001600160a01b031614611cd85760005b600454811015611cd657816001600160a01b031660048281548110611c4857fe5b6000918252602090912001546001600160a01b03161415611cce57600480546000198101908110611c7557fe5b600091825260209091200154600480546001600160a01b039092169183908110611c9b57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550611cd6565b600101611c27565b505b6004805480611ce357fe5b60008281526020808220830160001990810180546001600160a01b031990811690915593019093556001600160a01b03841680825260059093526040808220805490931690925590517fe5b28609ccc5cc2a3e4736068efad3e54a27ff556e326920df4213a66efbf5ab9190a250565b610bf982826004805480602002602001604051908101604052809291908181526020018280548015611dae57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611d90575b50505050506128cb565b6002602081815260009384526040808520909152918352912080546001820154919092015460ff9092169183565b60008281526002602090815260408083206001600160a01b038516845290915281205460ff1615611e1957506000611f89565b60405163133c617560e31b81526000906001600160a01b037f00000000000000000000000049bdd8854481005bba4acebabf6e06cd5f6312e916906399e30ba890611e6a90309088906004016135a7565b60206040518083038186803b158015611e8257600080fd5b505afa158015611e96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eba9190613490565b905080611ecb576000915050611f89565b6040516394cee7b360e01b81526000906001600160a01b038516906394cee7b390611efa908890600401613c7c565b60206040518083038186803b158015611f1257600080fd5b505afa158015611f26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4a9190613490565b905080611f5c57600092505050611f89565b611f84670de0b6b3a7640000611f78838563ffffffff612b9916565b9063ffffffff612bd316565b925050505b92915050565b6060611ffe8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080890282810182019093528882529093508892508791829185019084908082843760009201919091525061212792505050565b95945050505050565b7f000000000000000000000000ecf0bdb7b3f349abfd68c3563678124c5e8aaea381565b6120336120e1565b6000546001600160a01b039081169116146120605760405162461bcd60e51b815260040161025890613b00565b6001600160a01b0381166120865760405162461bcd60e51b8152600401610258906136fa565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b600061154683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612c15565b60608061213f83518551612b9990919063ffffffff16565b6001600160401b038111801561215457600080fd5b5060405190808252806020026020018201604052801561218e57816020015b61217b613089565b8152602001906001900390816121735790505b5090506000805b855181101561229c5760005b85518110156122935760006121dc8884815181106121bb57fe5b60200260200101518884815181106121cf57fe5b6020026020010151611de6565b9050801561228a5760405180608001604052808985815181106121fb57fe5b6020026020010151815260200188848151811061221457fe5b60200260200101516001600160a01b03168152602001828152602001600560008a868151811061224057fe5b6020908102919091018101516001600160a01b0390811683529082019290925260400160002054169052855186908690811061227857fe5b60209081029190910101526001909301925b506001016121a1565b50600101612195565b506060816001600160401b03811180156122b557600080fd5b506040519080825280602002602001820160405280156122ef57816020015b6122dc613089565b8152602001906001900390816122d45790505b50905060005b828110156123305783818151811061230957fe5b602002602001015182828151811061231d57fe5b60209081029190910101526001016122f5565b5095945050505050565b60028101805460ff191660019081179091558154908201546040517f0aaa05fba10caab20c7dfcd757223e489dbd2313a5e1add54bca74aceaf1781992612382929091613c85565b60405180910390a150565b60008060019050600183511115611f895760005b60018451038110156123ee578381600101815181106123bc57fe5b60200260200101518482815181106123d057fe5b6020026020010151106123e657600091506123ee565b6001016123a1565b5092915050565b6000826003838154811061240557fe5b9060005260206000209060030201600001541115612424575080611f89565b60035482905b80821015612484576000612447838301600263ffffffff612bd316565b9050856003828154811061245757fe5b90600052602060002090600302016000015411156124775780915061247e565b8060010192505b5061242a565b60001901949350505050565b612498612ff4565b6001600160a01b0385168082526000906124b3908890611de6565b90508015612330576001600160a01b0380871660009081526005602090815260409182902054831690850152835190516353fa2eb760e01b81529116906353fa2eb7906125069030908b906004016135a7565b602060405180830381600087803b15801561252057600080fd5b505af1158015612534573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125589190613490565b5060408201819052602085015161257e9061271090611f7890849063ffffffff612b9916565b6060830181905260408301516125999163ffffffff6120e516565b60808301526125bc836125b2868263ffffffff6126c916565b84608001516127b4565b60a0830181905260408301516125d79163ffffffff6120e516565b60c083015260408051606081018252600180825260a0850151602080840191825283850188815260008d815260028084528782206001600160a01b038f168352909352959095209351845460ff191690151517845590519183019190915591519101556126426111fa565b6001600160a01b0316866001600160a01b0316887f42d462aded8303289cfe9efdb997119f4921308595d9db5dd7d500236d523d21856020015186604001518a6020015188606001516126a68a606001518b60c001516120e590919063ffffffff16565b6040516126b7959493929190613653565b60405180910390a45095945050505050565b6000828201838110156115465760405162461bcd60e51b815260040161025890613740565b816126f8576127ae565b6001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156127a3576000836001600160a01b0316836040516127369061356c565b60006040518083038185875af1925050503d8060008114612773576040519150601f19603f3d011682016040523d82523d6000602084013e612778565b606091505b5050905080829061279c5760405162461bcd60e51b81526004016102589190613681565b50506127ae565b6127ae848484612c41565b50505050565b600061197183611f78868563ffffffff612b9916565b606060006127ef60016127e3858763ffffffff6120e516565b9063ffffffff6126c916565b90506060816001600160401b038111801561280957600080fd5b50604051908082528060200260200182016040528015612833578160200160208202803683370190505b5090506000855b858111612865578083838151811061284e57fe5b60209081029190910101526001918201910161283a565b50611540878360048054806020026020016040519081016040528092919081815260200182805480156128c157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116128a3575b5050505050612c97565b60008251116128ec5760405162461bcd60e51b815260040161025890613ba1565b600081511161290d5760405162461bcd60e51b815260040161025890613abd565b606081516001600160401b038111801561292657600080fd5b50604051908082528060200260200182016040528015612950578160200160208202803683370190505b50905060005b8351811015612b0257600084828151811061296d57fe5b6020026020010151905060008090505b8451811015612af85760006129a6888488858151811061299957fe5b602002602001015161139b565b90506000600560008885815181106129ba57fe5b6020908102919091018101516001600160a01b0390811683529082019290925260400160002054169050816129f0575050612af0565b612a008287858151811061107957fe5b868481518110612a0c57fe5b6020908102919091018101919091526000858152600180835260408083206001600160a01b038e16845290935291812089519091908a9087908110612a4d57fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550868381518110612a9857fe5b60200260200101516001600160a01b0316896001600160a01b0316857fd2bf01930193426d917e596a306efa79f82bfc800d1edfa31468cf0a2a7454e78486604051612ae59291906135a7565b60405180910390a450505b60010161297d565b5050600101612956565b5060005b81518110156108fa57612b9160056000858481518110612b2257fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b031686848481518110612b6b57fe5b60200260200101516040518060600160405280602a8152602001613d5c602a91396126ee565b600101612b06565b600082612ba857506000611f89565b82820282848281612bb557fe5b04146115465760405162461bcd60e51b815260040161025890613a29565b600061154683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612e9f565b60008184841115612c395760405162461bcd60e51b81526004016102589190613681565b505050900390565b611b428363a9059cbb60e01b8484604051602401612c609291906135a7565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612ed6565b606080612caf83518551612b9990919063ffffffff16565b6001600160401b0381118015612cc457600080fd5b50604051908082528060200260200182016040528015612cfe57816020015b612ceb613089565b815260200190600190039081612ce35790505b5090506000805b8551811015612e005760005b8551811015612df7576000612d4089898581518110612d2c57fe5b602002602001015189858151811061299957fe5b90508015612dee576040518060800160405280898581518110612d5f57fe5b60200260200101518152602001888481518110612d7857fe5b60200260200101516001600160a01b03168152602001828152602001600560008a8681518110612da457fe5b6020908102919091018101516001600160a01b03908116835290820192909252604001600020541690528551869086908110612ddc57fe5b60209081029190910101526001909301925b50600101612d11565b50600101612d05565b506060816001600160401b0381118015612e1957600080fd5b50604051908082528060200260200182016040528015612e5357816020015b612e40613089565b815260200190600190039081612e385790505b50905060005b82811015612e9457838181518110612e6d57fe5b6020026020010151828281518110612e8157fe5b6020908102919091010152600101612e59565b509695505050505050565b60008183612ec05760405162461bcd60e51b81526004016102589190613681565b506000838581612ecc57fe5b0495945050505050565b612ee8826001600160a01b0316612fbb565b612f045760405162461bcd60e51b815260040161025890613c22565b60006060836001600160a01b031683604051612f209190613550565b6000604051808303816000865af19150503d8060008114612f5d576040519150601f19603f3d011682016040523d82523d6000602084013e612f62565b606091505b509150915081612f845760405162461bcd60e51b815260040161025890613777565b8051156127ae5780806020019051810190612f9f9190613458565b6127ae5760405162461bcd60e51b815260040161025890613bd8565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590611971575050151592915050565b6040518060e0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b604051806060016040528060001515815260200160008152602001600081525090565b604051806060016040528060008152602001600081526020016000151581525090565b60405180608001604052806000815260200160006001600160a01b031681526020016000815260200160006001600160a01b031681525090565b60008083601f8401126130d4578182fd5b5081356001600160401b038111156130ea578182fd5b602083019150836020808302850101111561310457600080fd5b9250929050565b600082601f83011261311b578081fd5b813561312e61312982613cd1565b613cab565b81815291506020808301908481018184028601820187101561314f57600080fd5b60005b8481101561317757813561316581613d1c565b84529282019290820190600101613152565b505050505092915050565b600082601f830112613192578081fd5b81356131a061312982613cd1565b8181529150602080830190848101818402860182018710156131c157600080fd5b60005b84811015613177578135845292820192908201906001016131c4565b6000602082840312156131f1578081fd5b813561154681613d1c565b6000806040838503121561320e578081fd5b823561321981613d1c565b915060208301356001600160401b03811115613233578182fd5b61323f85828601613182565b9150509250929050565b60008060006060848603121561325d578081fd5b833561326881613d1c565b925060208401356001600160401b0380821115613283578283fd5b61328f87838801613182565b935060408601359150808211156132a4578283fd5b506132b18682870161310b565b9150509250925092565b600080604083850312156132cd578182fd5b82356132d881613d1c565b915060208301356132e881613d1c565b809150509250929050565b600080600060608486031215613307578283fd5b833561331281613d1c565b925060208401359150604084013561332981613d1c565b809150509250925092565b600080600060608486031215613348578283fd5b833561335381613d1c565b95602085013595506040909401359392505050565b6000806000806040858703121561337d578081fd5b84356001600160401b0380821115613393578283fd5b61339f888389016130c3565b909650945060208701359150808211156133b7578283fd5b506133c4878288016130c3565b95989497509550505050565b6000602082840312156133e1578081fd5b81356001600160401b038111156133f6578182fd5b61197184828501613182565b60008060408385031215613414578182fd5b82356001600160401b038082111561342a578384fd5b61343686838701613182565b9350602085013591508082111561344b578283fd5b5061323f8582860161310b565b600060208284031215613469578081fd5b81518015158114611546578182fd5b600060208284031215613489578081fd5b5035919050565b6000602082840312156134a1578081fd5b5051919050565b600080604083850312156134ba578182fd5b8235915060208301356132e881613d1c565b6000806000606084860312156134e0578081fd5b8335925060208401356134f281613d1c565b9150604084013561332981613d1c565b60008060408385031215613514578182fd5b50508035926020909101359150565b600080600060608486031215613537578081fd5b8351925060208401519150604084015161332981613d1c565b60008251613562818460208701613cf0565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b602080825282518282018190526000919060409081850190868401855b8281101561362357815180518552868101516001600160a01b039081168887015286820151878701526060918201511690850152608090930192908501906001016135dd565b5091979650505050505050565b901515815260200190565b92151583526020830191909152604082015260600190565b6001600160a01b03959095168552602085019390935260408401919091526060830152608082015260a00190565b60006020825282518060208401526136a0816040850160208701613cf0565b601f01601f19169190910160400192915050565b60208082526026908201527f6f6e6c7920616363657074204554482066726f6d2061204b796265724665654860408201526530b7323632b960d11b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b60208082526037908201527f6d617374657257697468647261773a2063616e206e6f74207472616e7366657260408201527f206b6e6320746f2074686520706f6f6c206d6173746572000000000000000000606082015260800190565b602080825260409082018190527f72656d6f766546656548616e646c65723a2063616e206e6f742072656d6f7665908201527f2046656548616e646c6572207375636365737366756c6c7920636c61696d6564606082015260800190565b60208082526023908201527f63524d61737465723a205f66656548616e646c657247726f75702072657175696040820152621c995960ea1b606082015260800190565b6020808252601c908201527f61646446656548616e646c65723a20616c726561647920616464656400000000604082015260600190565b6020808252602e908201527f636f6d6d69744e65774665653a2044656c65676174696f6e204665652067726560408201526d61746572207468616e203130302560901b606082015260800190565b60208082526025908201527f61646446656548616e646c65723a205f66656548616e646c6572206973206d696040820152647373696e6760d81b606082015260800190565b60208082526027908201527f63524d61737465723a206f7264657220616e6420756e697175656e6573732072604082015266195c5d5a5c995960ca1b606082015260800190565b6020808252601b908201527f72656d6f766546656548616e646c65723a206e6f742061646465640000000000604082015260600190565b6020808252601b908201527f6d617374657257697468647261773a20616d6f756e7420697320300000000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526033908201527f6d61737465724465706f7369743a20616d6f756e7420746f206465706f7369746040820152722073686f756c6420626520706f73697469766560681b606082015260800190565b60208082526023908201527f63524d656d6265723a205f66656548616e646c657247726f75702072657175696040820152621c995960ea1b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252818101527f6d61737465724465706f7369743a2063616e206e6f742067657420746f6b656e604082015260600190565b6020808252601e908201527f63524d61737465723a205f65706f636847726f75702072657175697265640000604082015260600190565b6020808252601e908201527f63524d656d6265723a205f65706f636847726f75702072657175697265640000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601f908201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604082015260600190565b815181526020808301519082015260409182015115159181019190915260600190565b90815260200190565b918252602082015260400190565b92835260208301919091521515604082015260600190565b6040518181016001600160401b0381118282101715613cc957600080fd5b604052919050565b60006001600160401b03821115613ce6578081fd5b5060209081020190565b60005b83811015613d0b578181015183820152602001613cf3565b838111156127ae5750506000910152565b6001600160a01b038116811461139857600080fdfe63524d61737465723a20706f6f6c4d6173746572207368617265207472616e73666572206661696c656463524d656d6265723a20706f6f6c4d656d626572207368617265207472616e73666572206661696c6564a264697066735822122064a8ca2ec5b6b3488c9c7dd1d5256f4571d7600191dc525e4b07dc15d4290cb664736f6c63430006060033
Verified Source Code Partial Match
Compiler: v0.6.6+commit.6c089d02
EVM: istanbul
Optimization: Yes (200 runs)
KyberPoolMaster.sol 1629 lines
// 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: @openzeppelin/contracts/math/SafeMath.sol
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) {
// Solidity only automatically asserts when dividing by 0
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: @openzeppelin/contracts/utils/Address.sol
pragma solidity ^0.6.2;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
}
// File: @openzeppelin/contracts/token/ERC20/SafeERC20.sol
pragma solidity ^0.6.0;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves.
// A Solidity high level call has three parts:
// 1. The target address is checked to verify it contains contract code
// 2. The call itself is made, and success asserted
// 3. The return value is decoded, which in turn checks the size of the returned data.
// solhint-disable-next-line max-line-length
require(address(token).isContract(), "SafeERC20: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = address(token).call(data);
require(success, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
// 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.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor () internal { }
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
pragma solidity ^0.6.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
// File: contracts/interfaces/IEpochUtils.sol
pragma solidity 0.6.6;
interface IEpochUtils {
function epochPeriodInSeconds() external view returns (uint256);
function firstEpochStartTimestamp() external view returns (uint256);
function getCurrentEpochNumber() external view returns (uint256);
function getEpochNumber(uint256 timestamp) external view returns (uint256);
}
// File: contracts/interfaces/IKyberDao.sol
pragma solidity 0.6.6;
interface IKyberDao is IEpochUtils {
event Voted(
address indexed staker,
uint256 indexed epoch,
uint256 indexed campaignID,
uint256 option
);
function getLatestNetworkFeeDataWithCache()
external
returns (uint256 feeInBps, uint256 expiryTimestamp);
function getLatestBRRDataWithCache()
external
returns (
uint256 burnInBps,
uint256 rewardInBps,
uint256 rebateInBps,
uint256 epoch,
uint256 expiryTimestamp
);
function handleWithdrawal(address staker, uint256 penaltyAmount) external;
function vote(uint256 campaignID, uint256 option) external;
function getLatestNetworkFeeData()
external
view
returns (uint256 feeInBps, uint256 expiryTimestamp);
function shouldBurnRewardForEpoch(uint256 epoch)
external
view
returns (bool);
/**
* @dev return staker's reward percentage in precision for a past epoch only
* fee handler should call this function when a staker wants to claim reward
* return 0 if staker has no votes or stakes
*/
function getPastEpochRewardPercentageInPrecision(
address staker,
uint256 epoch
) external view returns (uint256);
/**
* @dev return staker's reward percentage in precision for the current epoch
* reward percentage is not finalized until the current epoch is ended
*/
function getCurrentEpochRewardPercentageInPrecision(address staker)
external
view
returns (uint256);
}
// File: contracts/interfaces/IExtendedKyberDao.sol
pragma solidity 0.6.6;
interface IExtendedKyberDao is IKyberDao {
function kncToken() external view returns (address);
function staking() external view returns (address);
function feeHandler() external view returns (address);
}
// File: contracts/interfaces/IKyberFeeHandler.sol
pragma solidity 0.6.6;
interface IKyberFeeHandler {
event RewardPaid(
address indexed staker,
uint256 indexed epoch,
IERC20 indexed token,
uint256 amount
);
event RebatePaid(
address indexed rebateWallet,
IERC20 indexed token,
uint256 amount
);
event PlatformFeePaid(
address indexed platformWallet,
IERC20 indexed token,
uint256 amount
);
event KncBurned(uint256 kncTWei, IERC20 indexed token, uint256 amount);
function handleFees(
IERC20 token,
address[] calldata eligibleWallets,
uint256[] calldata rebatePercentages,
address platformWallet,
uint256 platformFee,
uint256 networkFee
) external payable;
function claimReserveRebate(address rebateWallet)
external
returns (uint256);
function claimPlatformFee(address platformWallet)
external
returns (uint256);
function claimStakerReward(address staker, uint256 epoch)
external
returns (uint256 amount);
}
// File: contracts/interfaces/IExtendedKyberFeeHandler.sol
pragma solidity 0.6.6;
interface IExtendedKyberFeeHandler is IKyberFeeHandler {
function rewardsPerEpoch(uint256) external view returns (uint256);
}
// File: contracts/interfaces/IKyberStaking.sol
pragma solidity 0.6.6;
interface IKyberStaking is IEpochUtils {
event Delegated(
address indexed staker,
address indexed representative,
uint256 indexed epoch,
bool isDelegated
);
event Deposited(uint256 curEpoch, address indexed staker, uint256 amount);
event Withdraw(
uint256 indexed curEpoch,
address indexed staker,
uint256 amount
);
function initAndReturnStakerDataForCurrentEpoch(address staker)
external
returns (
uint256 stake,
uint256 delegatedStake,
address representative
);
function deposit(uint256 amount) external;
function delegate(address dAddr) external;
function withdraw(uint256 amount) external;
/**
* @notice return combine data (stake, delegatedStake, representative) of a staker
* @dev allow to get staker data up to current epoch + 1
*/
function getStakerData(address staker, uint256 epoch)
external
view
returns (
uint256 stake,
uint256 delegatedStake,
address representative
);
function getLatestStakerData(address staker)
external
view
returns (
uint256 stake,
uint256 delegatedStake,
address representative
);
/**
* @notice return raw data of a staker for an epoch
* WARN: should be used only for initialized data
* if data has not been initialized, it will return all 0
* pool master shouldn't use this function to compute/distribute rewards of pool members
*/
function getStakerRawData(address staker, uint256 epoch)
external
view
returns (
uint256 stake,
uint256 delegatedStake,
address representative
);
}
// File: contracts/KyberPoolMaster.sol
pragma solidity 0.6.6;
pragma experimental ABIEncoderV2;
/**
* @title Kyber PoolMaster contract
* @author Protofire
* @dev Contract that allows pool masters to let pool members claim their designated rewards trustlessly and update fees
* with sufficient notice times while maintaining full trustlessness.
*/
contract KyberPoolMaster is Ownable {
using SafeMath for uint256;
uint256 internal constant MINIMUM_EPOCH_NOTICE = 1;
uint256 internal constant MAX_DELEGATION_FEE = 10000;
uint256 internal constant PRECISION = (10**18);
IERC20 internal constant ETH_TOKEN_ADDRESS = IERC20(
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
);
// Number of epochs after which a change on delegationFee will be applied
uint256 public immutable epochNotice;
// Mapping of if staker has claimed reward for Epoch in a feeHandler
// epoch -> member -> feeHandler -> true | false
mapping(uint256 => mapping(address => mapping(address => bool)))
public claimedDelegateReward;
struct Claim {
bool claimedByPool;
uint256 totalRewards;
uint256 totalStaked;
}
//epoch -> feeHandler -> Claim
mapping(uint256 => mapping(address => Claim)) public epochFeeHandlerClaims;
// Fee charged by poolMasters to poolMembers for services
// Denominated in 1e4 units
// 100 = 1%
struct DFeeData {
uint256 fromEpoch;
uint256 fee;
bool applied;
}
DFeeData[] public delegationFees;
IERC20 public immutable kncToken;
IExtendedKyberDao public immutable kyberDao;
IKyberStaking public immutable kyberStaking;
address[] public feeHandlersList;
mapping(address => IERC20) public rewardTokenByFeeHandler;
uint256 public immutable firstEpoch;
mapping(address => bool) public successfulClaimByFeeHandler;
struct RewardInfo {
IExtendedKyberFeeHandler kyberFeeHandler;
IERC20 rewardToken;
uint256 totalRewards;
uint256 totalFee;
uint256 rewardsAfterFee;
uint256 poolMembersShare;
uint256 poolMasterShare;
}
struct UnclaimedRewardData {
uint256 epoch;
address feeHandler;
uint256 rewards;
IERC20 rewardToken;
}
/*** Events ***/
event CommitNewFees(uint256 deadline, uint256 feeRate);
event NewFees(uint256 fromEpoch, uint256 feeRate);
event MemberClaimReward(
uint256 indexed epoch,
address indexed poolMember,
address indexed feeHandler,
IERC20 rewardToken,
uint256 reward
);
event MasterClaimReward(
uint256 indexed epoch,
address indexed feeHandler,
address indexed poolMaster,
IERC20 rewardToken,
uint256 totalRewards,
uint256 feeApplied,
uint256 feeAmount,
uint256 poolMasterShare
);
event AddFeeHandler(address indexed feeHandler, IERC20 indexed rewardToken);
event RemoveFeeHandler(address indexed feeHandler);
/**
* @notice Address deploying this contract should be able to receive ETH, owner can be changed using transferOwnership method
* @param _kyberDao KyberDao contract address
* @param _epochNotice Number of epochs after which a change on deledatioFee is will be applied
* @param _delegationFee Fee charged by poolMasters to poolMembers for services - Denominated in 1e4 units - 100 = 1%
* @param _kyberFeeHandlers Array of FeeHandlers
* @param _rewardTokens Array of ERC20 tokens used by FeeHandlers to pay reward. Use zero address if FeeHandler pays ETH
*/
constructor(
address _kyberDao,
uint256 _epochNotice,
uint256 _delegationFee,
address[] memory _kyberFeeHandlers,
IERC20[] memory _rewardTokens
) public {
require(_kyberDao != address(0), "ctor: kyberDao is missing");
require(
_epochNotice >= MINIMUM_EPOCH_NOTICE,
"ctor: Epoch Notice too low"
);
require(
_delegationFee <= MAX_DELEGATION_FEE,
"ctor: Delegation Fee greater than 100%"
);
require(
_kyberFeeHandlers.length > 0,
"ctor: at least one _kyberFeeHandlers required"
);
require(
_kyberFeeHandlers.length == _rewardTokens.length,
"ctor: _kyberFeeHandlers and _rewardTokens uneven"
);
IExtendedKyberDao _kyberDaoContract = IExtendedKyberDao(_kyberDao);
kyberDao = _kyberDaoContract;
kncToken = IERC20(_kyberDaoContract.kncToken());
kyberStaking = IKyberStaking(_kyberDaoContract.staking());
epochNotice = _epochNotice;
uint256 _firstEpoch = _kyberDaoContract.getCurrentEpochNumber();
firstEpoch = _firstEpoch;
delegationFees.push(DFeeData(_firstEpoch, _delegationFee, true));
for (uint256 i = 0; i < _kyberFeeHandlers.length; i++) {
require(
_kyberFeeHandlers[i] != address(0),
"ctor: feeHandler is missing"
);
require(
rewardTokenByFeeHandler[_kyberFeeHandlers[i]] ==
IERC20(address(0)),
"ctor: repeated feeHandler"
);
feeHandlersList.push(_kyberFeeHandlers[i]);
rewardTokenByFeeHandler[_kyberFeeHandlers[i]] = _rewardTokens[i];
emit AddFeeHandler(
_kyberFeeHandlers[i],
rewardTokenByFeeHandler[_kyberFeeHandlers[i]]
);
}
emit CommitNewFees(_firstEpoch, _delegationFee);
emit NewFees(_firstEpoch, _delegationFee);
}
/**
* @dev adds a new FeeHandler
* @param _feeHandler FeeHandler address
* @param _rewardToken Rewards Token address
*/
function addFeeHandler(address _feeHandler, IERC20 _rewardToken)
external
onlyOwner
{
require(
_feeHandler != address(0),
"addFeeHandler: _feeHandler is missing"
);
require(
rewardTokenByFeeHandler[_feeHandler] == IERC20(address(0)),
"addFeeHandler: already added"
);
feeHandlersList.push(_feeHandler);
rewardTokenByFeeHandler[_feeHandler] = _rewardToken;
emit AddFeeHandler(_feeHandler, rewardTokenByFeeHandler[_feeHandler]);
}
/**
* @dev removes a FeeHandler
* @param _feeHandler FeeHandler address
*/
function removeFeeHandler(address _feeHandler) external onlyOwner {
require(
rewardTokenByFeeHandler[_feeHandler] != IERC20(address(0)),
"removeFeeHandler: not added"
);
require(
!successfulClaimByFeeHandler[_feeHandler],
"removeFeeHandler: can not remove FeeHandler successfully claimed"
);
if (feeHandlersList[feeHandlersList.length - 1] != _feeHandler) {
for (uint256 i = 0; i < feeHandlersList.length; i++) {
if (feeHandlersList[i] == _feeHandler) {
feeHandlersList[i] = feeHandlersList[feeHandlersList
.length - 1];
break;
}
}
}
feeHandlersList.pop();
delete rewardTokenByFeeHandler[_feeHandler];
emit RemoveFeeHandler(_feeHandler);
}
/**
* @dev call to stake more KNC for poolMaster
* @param amount amount of KNC to stake
*/
function masterDeposit(uint256 amount) external onlyOwner {
require(
amount > 0,
"masterDeposit: amount to deposit should be positive"
);
require(
kncToken.transferFrom(msg.sender, address(this), amount),
"masterDeposit: can not get token"
);
// approve
kncToken.approve(address(kyberStaking), amount);
// deposit in KyberStaking
kyberStaking.deposit(amount);
}
/**
* @dev call to withdraw KNC from staking
* @param amount amount of KNC to withdraw
*/
function masterWithdraw(uint256 amount) external onlyOwner {
require(amount > 0, "masterWithdraw: amount is 0");
// withdraw from KyberStaking
kyberStaking.withdraw(amount);
// transfer KNC back to pool master
require(
kncToken.transfer(msg.sender, amount),
"masterWithdraw: can not transfer knc to the pool master"
);
}
/**
* @dev vote for an option of a campaign
* options are indexed from 1 to number of options
* @param campaignID id of campaign to vote for
* @param option id of options to vote for
*/
function vote(uint256 campaignID, uint256 option) external onlyOwner {
kyberDao.vote(campaignID, option);
}
/**
* @dev set a new delegation fee to be applied in current epoch + epochNotice
* @param _fee new fee
*/
function commitNewFee(uint256 _fee) external onlyOwner {
require(
_fee <= MAX_DELEGATION_FEE,
"commitNewFee: Delegation Fee greater than 100%"
);
uint256 curEpoch = kyberDao.getCurrentEpochNumber();
uint256 fromEpoch = curEpoch.add(epochNotice);
DFeeData storage lastFee = delegationFees[delegationFees.length - 1];
if (lastFee.fromEpoch > curEpoch) {
lastFee.fromEpoch = fromEpoch;
lastFee.fee = _fee;
} else {
if (!lastFee.applied) {
applyFee(lastFee);
}
delegationFees.push(DFeeData(fromEpoch, _fee, false));
}
emit CommitNewFees(fromEpoch.sub(1), _fee);
}
/**
* @dev Applies the pending new fee
*/
function applyPendingFee() public {
DFeeData storage lastFee = delegationFees[delegationFees.length - 1];
uint256 curEpoch = kyberDao.getCurrentEpochNumber();
if (lastFee.fromEpoch <= curEpoch && !lastFee.applied) {
applyFee(lastFee);
}
}
/**
* @dev Applies a pending fee
* @param fee to be applied
*/
function applyFee(DFeeData storage fee) internal {
fee.applied = true;
emit NewFees(fee.fromEpoch, fee.fee);
}
/**
* @dev Gets the id of the delegation fee corresponding to the given epoch
* @param _epoch for which epoch is querying delegation fee
* @param _from delegationFees starting index
*/
function getEpochDFeeDataId(uint256 _epoch, uint256 _from)
internal
view
returns (uint256)
{
if (delegationFees[_from].fromEpoch > _epoch) {
return _from;
}
uint256 left = _from;
uint256 right = delegationFees.length;
while (left < right) {
uint256 m = (left + right).div(2);
if (delegationFees[m].fromEpoch > _epoch) {
right = m;
} else {
left = m + 1;
}
}
return right - 1;
}
/**
* @dev Gets the the delegation fee data corresponding to the given epoch
* @param epoch for which epoch is querying delegation fee
*/
function getEpochDFeeData(uint256 epoch)
public
view
returns (DFeeData memory epochDFee)
{
epochDFee = delegationFees[getEpochDFeeDataId(epoch, 0)];
}
/**
* @dev Gets the the delegation fee data corresponding to the current epoch
*/
function delegationFee() public view returns (DFeeData memory) {
uint256 curEpoch = kyberDao.getCurrentEpochNumber();
return getEpochDFeeData(curEpoch);
}
/**
* @dev Queries the amount of unclaimed rewards for the pool in a given epoch and feeHandler
* return 0 if PoolMaster has calledRewardMaster
* return 0 if staker's reward percentage in precision for the epoch is 0
* return 0 if total reward for the epoch is 0
* @param _epoch for which epoch is querying unclaimed reward
* @param _feeHandler FeeHandler address
*/
function getUnclaimedRewards(
uint256 _epoch,
IExtendedKyberFeeHandler _feeHandler
) public view returns (uint256) {
if (epochFeeHandlerClaims[_epoch][address(_feeHandler)].claimedByPool) {
return 0;
}
uint256 perInPrecision = kyberDao
.getPastEpochRewardPercentageInPrecision(address(this), _epoch);
if (perInPrecision == 0) {
return 0;
}
uint256 rewardsPerEpoch = _feeHandler.rewardsPerEpoch(_epoch);
if (rewardsPerEpoch == 0) {
return 0;
}
return rewardsPerEpoch.mul(perInPrecision).div(PRECISION);
}
/**
* @dev Returns data related to all epochs and feeHandlers with unclaimed rewards, for the pool.
*/
function getUnclaimedRewardsData()
external
view
returns (UnclaimedRewardData[] memory)
{
uint256 currentEpoch = kyberDao.getCurrentEpochNumber();
uint256 maxEpochNumber = currentEpoch.sub(firstEpoch);
uint256[] memory epochGroup = new uint256[](maxEpochNumber);
uint256 e = 0;
for (uint256 epoch = firstEpoch; epoch < currentEpoch; epoch++) {
epochGroup[e] = epoch;
e++;
}
return _getUnclaimedRewardsData(epochGroup, feeHandlersList);
}
/**
* @dev Returns data related to all epochs and feeHandlers, from the given groups, with unclaimed rewards, for the pool.
*/
function getUnclaimedRewardsData(
uint256[] calldata _epochGroup,
address[] calldata _feeHandlerGroup
) external view returns (UnclaimedRewardData[] memory) {
return _getUnclaimedRewardsData(_epochGroup, _feeHandlerGroup);
}
function _getUnclaimedRewardsData(
uint256[] memory _epochGroup,
address[] memory _feeHandlerGroup
) internal view returns (UnclaimedRewardData[] memory) {
UnclaimedRewardData[] memory epochFeeHanlderRewards
= new UnclaimedRewardData[](
_epochGroup.length.mul(_feeHandlerGroup.length)
);
uint256 rewardsCounter = 0;
for (uint256 e = 0; e < _epochGroup.length; e++) {
for (uint256 f = 0; f < _feeHandlerGroup.length; f++) {
uint256 unclaimed = getUnclaimedRewards(
_epochGroup[e],
IExtendedKyberFeeHandler(_feeHandlerGroup[f])
);
if (unclaimed > 0) {
epochFeeHanlderRewards[rewardsCounter] = UnclaimedRewardData(
_epochGroup[e],
_feeHandlerGroup[f],
unclaimed,
rewardTokenByFeeHandler[_feeHandlerGroup[f]]
);
rewardsCounter++;
}
}
}
UnclaimedRewardData[] memory result = new UnclaimedRewardData[](
rewardsCounter
);
for (uint256 i = 0; i < (rewardsCounter); i++) {
result[i] = epochFeeHanlderRewards[i];
}
return result;
}
/**
* @dev Claims rewards for a given group of epochs in all feeHandlers, distribute fees and its share to poolMaster
* @param _epochGroup An array of epochs for which rewards are being claimed. Asc order and uniqueness is required.
*/
function claimRewardsMaster(uint256[] memory _epochGroup) public {
claimRewardsMaster(_epochGroup, feeHandlersList);
}
/**
* @dev Claims rewards for a given group of epochs and a given group of feeHandlers, distribute fees and its share to poolMaster
* @param _epochGroup An array of epochs for which rewards are being claimed. Asc order and uniqueness is required.
* @param _feeHandlerGroup An array of FeeHandlers for which rewards are being claimed.
*/
function claimRewardsMaster(
uint256[] memory _epochGroup,
address[] memory _feeHandlerGroup
) public {
require(_epochGroup.length > 0, "cRMaster: _epochGroup required");
require(
isOrderedSet(_epochGroup),
"cRMaster: order and uniqueness required"
);
require(
_feeHandlerGroup.length > 0,
"cRMaster: _feeHandlerGroup required"
);
uint256[] memory accruedByFeeHandler = new uint256[](
_feeHandlerGroup.length
);
uint256 feeId = 0;
for (uint256 j = 0; j < _epochGroup.length; j++) {
uint256 _epoch = _epochGroup[j];
feeId = getEpochDFeeDataId(_epoch, feeId);
DFeeData storage epochDFee = delegationFees[feeId];
if (!epochDFee.applied) {
applyFee(epochDFee);
}
(uint256 stake, uint256 delegatedStake, ) = kyberStaking
.getStakerRawData(address(this), _epoch);
for (uint256 i = 0; i < _feeHandlerGroup.length; i++) {
RewardInfo memory rewardInfo = _claimRewardsFromKyber(
_epoch,
_feeHandlerGroup[i],
epochDFee,
stake,
delegatedStake
);
if (rewardInfo.totalRewards == 0) {
continue;
}
accruedByFeeHandler[i] = accruedByFeeHandler[i].add(
rewardInfo.poolMasterShare
);
if (!successfulClaimByFeeHandler[_feeHandlerGroup[i]]) {
successfulClaimByFeeHandler[_feeHandlerGroup[i]] = true;
}
}
}
address poolMaster = owner();
for (uint256 k = 0; k < accruedByFeeHandler.length; k++) {
_sendTokens(
rewardTokenByFeeHandler[_feeHandlerGroup[k]],
poolMaster,
accruedByFeeHandler[k],
"cRMaster: poolMaster share transfer failed"
);
}
}
function _claimRewardsFromKyber(
uint256 _epoch,
address _feeHandlerAddress,
DFeeData memory epochDFee,
uint256 stake,
uint256 delegatedStake
) internal returns (RewardInfo memory rewardInfo) {
rewardInfo.kyberFeeHandler = IExtendedKyberFeeHandler(
_feeHandlerAddress
);
uint256 unclaimed = getUnclaimedRewards(
_epoch,
rewardInfo.kyberFeeHandler
);
if (unclaimed > 0) {
rewardInfo
.rewardToken = rewardTokenByFeeHandler[_feeHandlerAddress];
rewardInfo.kyberFeeHandler.claimStakerReward(address(this), _epoch);
rewardInfo.totalRewards = unclaimed;
rewardInfo.totalFee = rewardInfo
.totalRewards
.mul(epochDFee.fee)
.div(MAX_DELEGATION_FEE);
rewardInfo.rewardsAfterFee = rewardInfo.totalRewards.sub(
rewardInfo.totalFee
);
rewardInfo.poolMembersShare = calculateRewardsShare(
delegatedStake,
stake.add(delegatedStake),
rewardInfo.rewardsAfterFee
);
rewardInfo.poolMasterShare = rewardInfo.totalRewards.sub(
rewardInfo.poolMembersShare
); // fee + poolMaster stake share
epochFeeHandlerClaims[_epoch][_feeHandlerAddress] = Claim(
true,
rewardInfo.poolMembersShare,
delegatedStake
);
emit MasterClaimReward(
_epoch,
_feeHandlerAddress,
payable(owner()),
rewardInfo.rewardToken,
rewardInfo.totalRewards,
epochDFee.fee,
rewardInfo.totalFee,
rewardInfo.poolMasterShare.sub(rewardInfo.totalFee)
);
}
}
/**
* @dev Helper method to transfer tokens
* @param _token address of the token
* @param _receiver account that will receive the transfer
* @param _value the amount of tokens to transfer
* @param _errorMsg error msg in case transfer of native tokens fails
*/
function _sendTokens(
IERC20 _token,
address _receiver,
uint256 _value,
string memory _errorMsg
) internal {
if (_value == 0) {
return;
}
if (_token == ETH_TOKEN_ADDRESS) {
(bool success, ) = _receiver.call{value: _value}("");
require(success, _errorMsg);
} else {
SafeERC20.safeTransfer(_token, _receiver, _value);
}
}
/**
* @dev Queries the amount of unclaimed rewards for the pool member in a given epoch and feeHandler
* return 0 if PoolMaster has not called claimRewardMaster
* return 0 if PoolMember has previously claimed reward for the epoch
* return 0 if PoolMember has not stake for the epoch
* return 0 if PoolMember has not delegated it stake to this contract for the epoch
* @param _poolMember address of pool member
* @param _epoch for which epoch the member is querying unclaimed reward
* @param _feeHandler FeeHandler address
*/
function getUnclaimedRewardsMember(
address _poolMember,
uint256 _epoch,
address _feeHandler
) public view returns (uint256) {
if (
!epochFeeHandlerClaims[_epoch][address(_feeHandler)].claimedByPool
) {
return 0;
}
if (claimedDelegateReward[_epoch][_poolMember][_feeHandler]) {
return 0;
}
(uint256 stake, , address representative) = kyberStaking.getStakerData(
_poolMember,
_epoch
);
if (stake == 0) {
return 0;
}
if (representative != address(this)) {
return 0;
}
Claim memory rewardForEpoch
= epochFeeHandlerClaims[_epoch][_feeHandler];
return
calculateRewardsShare(
stake,
rewardForEpoch.totalStaked,
rewardForEpoch.totalRewards
);
}
/**
* @dev Returns data related to all epochs and feeHandlers with unclaimed rewards, for a the poolMember. From initial to current epoch.
* @param _poolMember address of pool member
*/
function getAllUnclaimedRewardsDataMember(address _poolMember)
external
view
returns (UnclaimedRewardData[] memory)
{
uint256 currentEpoch = kyberDao.getCurrentEpochNumber();
return
_getAllUnclaimedRewardsDataMember(
_poolMember,
firstEpoch,
currentEpoch
);
}
/**
* @dev Returns data related to all epochs and feeHandlers with unclaimed rewards, for a the poolMember.
* @param _poolMember address of pool member
* @param _fromEpoch initial epoch parameter
* @param _toEpoch end epoch parameter
*/
function getAllUnclaimedRewardsDataMember(
address _poolMember,
uint256 _fromEpoch,
uint256 _toEpoch
) external view returns (UnclaimedRewardData[] memory) {
return
_getAllUnclaimedRewardsDataMember(
_poolMember,
_fromEpoch,
_toEpoch
);
}
/**
* @dev Queries data related to epochs and feeHandlers with unclaimed rewards, for a the poolMember
* @param _poolMember address of pool member
* @param _fromEpoch initial epoch parameter
* @param _toEpoch end epoch parameter
*/
function _getAllUnclaimedRewardsDataMember(
address _poolMember,
uint256 _fromEpoch,
uint256 _toEpoch
) internal view returns (UnclaimedRewardData[] memory) {
uint256 maxEpochNumber = _toEpoch.sub(_fromEpoch).add(1);
uint256[] memory epochGroup = new uint256[](maxEpochNumber);
uint256 e = 0;
for (uint256 epoch = _fromEpoch; epoch <= _toEpoch; epoch++) {
epochGroup[e] = epoch;
e++;
}
return
_getUnclaimedRewardsDataMember(
_poolMember,
epochGroup,
feeHandlersList
);
}
function _getUnclaimedRewardsDataMember(
address _poolMember,
uint256[] memory _epochGroup,
address[] memory _feeHandlerGroup
) internal view returns (UnclaimedRewardData[] memory) {
UnclaimedRewardData[] memory epochFeeHanlderRewards
= new UnclaimedRewardData[](
_epochGroup.length.mul(_feeHandlerGroup.length)
);
uint256 rewardsCounter = 0;
for (uint256 e = 0; e < _epochGroup.length; e++) {
for (uint256 f = 0; f < _feeHandlerGroup.length; f++) {
uint256 unclaimed = getUnclaimedRewardsMember(
_poolMember,
_epochGroup[e],
...
// [truncated — 55767 bytes total]
Read Contract
claimedDelegateReward 0xc92d7169 → bool
delegationFee 0xc5f0a58f → tuple
delegationFees 0x29f6ff41 → uint256, uint256, bool
delegationFeesLength 0xc08da7a1 → uint256
epochFeeHandlerClaims 0xde37b7a1 → bool, uint256, uint256
epochNotice 0xba2d373c → uint256
feeHandlersList 0xb0cd498b → address
feeHandlersListLength 0x4edd0d67 → uint256
firstEpoch 0x41682744 → uint256
getAllUnclaimedRewardsDataMember 0xb8a4aeaf → tuple[]
getAllUnclaimedRewardsDataMember 0xc5e6e357 → tuple[]
getEpochDFeeData 0xb3e9ba27 → tuple
getUnclaimedRewards 0xdec36554 → uint256
getUnclaimedRewardsData 0x22b143fb → tuple[]
getUnclaimedRewardsData 0xe25208e3 → tuple[]
getUnclaimedRewardsMember 0x9e3853ec → uint256
kncToken 0x811c7fe2 → address
kyberDao 0x4d8f5105 → address
kyberStaking 0xf0359d1b → address
owner 0x8da5cb5b → address
rewardTokenByFeeHandler 0x413f92c0 → address
successfulClaimByFeeHandler 0x09f67b3a → bool
Write Contract 13 functions
These functions modify contract state and require a wallet transaction to execute.
addFeeHandler 0x7ee1506d
address _feeHandler
address _rewardToken
applyPendingFee 0x35f8aa9b
No parameters
claimRewardsMaster 0x8769e324
uint256[] _epochGroup
address[] _feeHandlerGroup
claimRewardsMaster 0xa969b186
uint256[] _epochGroup
claimRewardsMember 0xd172d3a3
address _poolMember
uint256[] _epochGroup
address[] _feeHandlerGroup
claimRewardsMember 0xd4b94901
address _poolMember
uint256[] _epochGroup
commitNewFee 0x9faf1d51
uint256 _fee
masterDeposit 0x02662585
uint256 amount
masterWithdraw 0x9d21ce9c
uint256 amount
removeFeeHandler 0xd2f31c39
address _feeHandler
renounceOwnership 0x715018a6
No parameters
transferOwnership 0xf2fde38b
address newOwner
vote 0xb384abef
uint256 campaignID
uint256 option
Recent Transactions
No transactions found for this address