Address Contract Partially Verified
Address
0xF18Dc176C10Ff6D8b5A17974126D43301F8EEB95
Balance
0 ETH
Nonce
1
Code Size
18041 bytes
Creator
0x27e80dB1...603D at tx 0x541d837b...fbcb9b
Indexed Transactions
0
Contract Bytecode
18041 bytes
0x608060405234801561001057600080fd5b50600436106101a35760003560e01c8063641a24d2116100ee578063a493e6a211610097578063cb1c832111610071578063cb1c83211461035d578063e5e82b7c14610370578063f0d19b8914610383578063f3512f841461039657600080fd5b8063a493e6a214610324578063c0d05dd814610337578063c601bf781461034a57600080fd5b80639961cee4116100c85780639961cee4146102f65780639a206c8e14610309578063a39e96c31461031157600080fd5b8063641a24d2146102ad5780636b088d5c146102d057806397be2143146102e357600080fd5b80632c177a531161015057806348aeedf51161012a57806348aeedf5146102685780634e58ff6e1461027b57806354fd4d501461028e57600080fd5b80632c177a531461022f5780633d65c1fa146102425780633e200d4b1461025557600080fd5b8063194c63d811610181578063194c63d8146101f657806321f3da4414610209578063245395a61461021c57600080fd5b806303fa87b4146101a8578063088903a4146101ce57806310b63749146101e3575b600080fd5b6101bb6101b63660046142be565b6103a9565b6040519081526020015b60405180910390f35b6101e16101dc3660046142e9565b610521565b005b6101e16101f1366004614322565b610530565b6101e16102043660046142e9565b610828565b6101e1610217366004614363565b610bb9565b6101e161022a366004614363565b61139a565b6101e161023d366004614363565b6117d1565b6101e161025036600461438f565b611a4a565b6101e16102633660046143da565b611dd2565b6101bb6102763660046142be565b611ddf565b6101bb6102893660046142be565b611f84565b60005461029b9060ff1681565b60405160ff90911681526020016101c5565b6102c06102bb3660046142be565b61207a565b60405190151581526020016101c5565b6101e16102de3660046143da565b6120d1565b6101bb6102f13660046142be565b6120db565b6101bb6103043660046142be565b61229f565b6101bb6123e9565b6101e161031f366004614363565b612419565b6101bb6103323660046142be565b612850565b6101bb6103453660046142be565b612a9a565b6101e1610358366004614363565b612b02565b6101e161036b366004614363565b612e27565b6101bb61037e3660046142be565b6132ba565b6101bb6103913660046142be565b61344e565b6101bb6103a43660046142be565b61369d565b6000806103ea6040518060400160405280601381526020017f726f636b65744e6574776f726b507269636573000000000000000000000000008152506136ee565b9050600061042c6040518060400160405280601d81526020017f726f636b657444414f50726f746f636f6c53657474696e67734e6f64650000008152506136ee565b90506000816001600160a01b0316636fdbe57b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561046e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049291906143f3565b9050600061049f86612850565b9050836001600160a01b031663724d4a096040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050391906143f3565b61050d838361443b565b6105179190614452565b9695505050505050565b61052c338383611a4a565b5050565b6040518060400160405280601181526020017f726f636b65744e6f64655374616b696e67000000000000000000000000000000815250306105968260405160200161057b919061448d565b6040516020818303038152906040528051906020012061375d565b6001600160a01b0316816001600160a01b0316146105fb5760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064015b60405180910390fd5b6040517f636f6e74726163742e657869737473000000000000000000000000000000000060208201526bffffffffffffffffffffffff193360601b16602f82015261065f906043015b604051602081830303815290604052805190602001206137e8565b6106d05760405162461bcd60e51b8152602060048201526024808201527f496e76616c6964206f72206f75746461746564206e6574776f726b20636f6e7460448201527f726163740000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606087901b16602b820152859061072090603f01610644565b61076c5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016105f2565b836107768761229f565b10156107c45760405162461bcd60e51b815260206004820152601b60248201527f53656e6465722068617320696e73756666696369656e742052504c000000000060448201526064016105f2565b6107ce8685613873565b6107d88585613a4c565b604080518581524260208201526001600160a01b0380881692908916917f3bf4a4ef95ccf3119f6977afa759933d4edd361281f5c3b91203f43104fa3432910160405180910390a3505050505050565b6040518060400160405280601181526020017f726f636b65744e6f64655374616b696e67000000000000000000000000000000815250306108738260405160200161057b919061448d565b6001600160a01b0316816001600160a01b0316146108d35760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016105f2565b8360006109146040518060400160405280601181526020017f726f636b65744e6f64654d616e616765720000000000000000000000000000008152506136ee565b6040517fe667d8280000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301529192509082169063e667d82890602401602060405180830381865afa158015610977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099b91906144e5565b15610aad576040517fb71f0c7c0000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301526000919083169063b71f0c7c90602401602060405180830381865afa158015610a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a279190614502565b9050336001600160a01b03821614610aa75760405162461bcd60e51b815260206004820152602a60248201527f4d7573742062652063616c6c65642066726f6d2052504c20776974686472617760448201527f616c20616464726573730000000000000000000000000000000000000000000060648201526084016105f2565b50610b05565b336001600160a01b03831614610b055760405162461bcd60e51b815260206004820181905260248201527f4d7573742062652063616c6c65642066726f6d206e6f6465206164647265737360448201526064016105f2565b6040517f72706c2e6c6f636b696e672e616c6c6f7765640000000000000000000000000060208201526bffffffffffffffffffffffff19606088901b166033820152610b6b906047015b6040516020818303038152906040528051906020012086613b91565b6040805186151581524260208201526001600160a01b038816917f6b33e987d80ef301261d0265922ffe70da2b332f0e097034ce01dbb998cbd01391015b60405180910390a2505050505050565b6040518060400160405280601181526020017f726f636b65744e6f64655374616b696e6700000000000000000000000000000081525030610c048260405160200161057b919061448d565b6001600160a01b0316816001600160a01b031614610c645760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016105f2565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606086901b16602b820152610cb290603f01610644565b610cfe5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016105f2565b6000610d3e6040518060400160405280601181526020017f726f636b65744e6f64654d616e616765720000000000000000000000000000008152506136ee565b6040517fb71f0c7c0000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015291925060009183169063b71f0c7c90602401602060405180830381865afa158015610da3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc79190614502565b6040517fe667d8280000000000000000000000000000000000000000000000000000000081526001600160a01b0388811660048301529192509083169063e667d82890602401602060405180830381865afa158015610e2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4e91906144e5565b15610eb057336001600160a01b03821614610eab5760405162461bcd60e51b815260206004820152600e60248201527f496e76616c69642063616c6c657200000000000000000000000000000000000060448201526064016105f2565b610fad565b600080546040517f5b49ff620000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015261010090920490911690635b49ff6290602401602060405180830381865afa158015610f1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3e9190614502565b9050336001600160a01b0388161480610f5f5750336001600160a01b038216145b610fab5760405162461bcd60e51b815260206004820152600e60248201527f496e76616c69642063616c6c657200000000000000000000000000000000000060448201526064016105f2565b505b6000610fed6040518060400160405280602081526020017f726f636b657444414f50726f746f636f6c53657474696e6773526577617264738152506136ee565b9050600061102f6040518060400160405280600b81526020017f726f636b65745661756c740000000000000000000000000000000000000000008152506136ee565b9050816001600160a01b03166394e5d5126040518163ffffffff1660e01b8152600401602060405180830381865afa15801561106f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109391906143f3565b61109c89612a9a565b6110a6904261451f565b101561111a5760405162461bcd60e51b815260206004820152602d60248201527f546865207769746864726177616c20636f6f6c646f776e20706572696f64206860448201527f6173206e6f74207061737365640000000000000000000000000000000000000060648201526084016105f2565b60006111258961229f565b905060006111328a61369d565b90508861113f828461451f565b10156111b35760405162461bcd60e51b815260206004820152603360248201527f5769746864726177616c20616d6f756e742065786365656473206e6f6465277360448201527f207374616b65642052504c2062616c616e63650000000000000000000000000060648201526084016105f2565b806111bd8b611f84565b6111c79190614532565b6111d18a8461451f565b101561126b5760405162461bcd60e51b815260206004820152604860248201527f4e6f64652773207374616b65642052504c2062616c616e63652061667465722060448201527f7769746864726177616c206973206c657373207468616e20726571756972656460648201527f2062616c616e6365000000000000000000000000000000000000000000000000608482015260a4016105f2565b61127489613c19565b61127e8a8a613873565b826001600160a01b03166301e33667866112cc6040518060400160405280600e81526020017f726f636b6574546f6b656e52504c0000000000000000000000000000000000008152506136ee565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03928316600482015291166024820152604481018c9052606401600060405180830381600087803b15801561133357600080fd5b505af1158015611347573d6000803e3d6000fd5b5050604080518c81524260208201526001600160a01b038e1693507f9947063f70b076145616018b82ed1dd5585e15b7ae0a0b17a8b06bec4c4c31e292500160405180910390a250505050505050505050565b6040518060400160405280601181526020017f726f636b65744e6f64655374616b696e67000000000000000000000000000000815250306113e58260405160200161057b919061448d565b6001600160a01b0316816001600160a01b0316146114455760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016105f2565b336114988160405160200161064491907f6d696e69706f6f6c2e6578697374730000000000000000000000000000000000815260609190911b6bffffffffffffffffffffffff1916600f82015260230190565b6114e45760405162461bcd60e51b815260206004820152601060248201527f496e76616c6964206d696e69706f6f6c0000000000000000000000000000000060448201526064016105f2565b60006115246040518060400160405280601381526020017f726f636b65744e6574776f726b507269636573000000000000000000000000008152506136ee565b905060006115666040518060400160405280600b81526020017f726f636b65745661756c740000000000000000000000000000000000000000008152506136ee565b90506000826001600160a01b031663724d4a096040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115cc91906143f3565b6115de88670de0b6b3a764000061443b565b6115e89190614452565b905060006115f58961229f565b905080821115611603578091505b811561170357826001600160a01b031663ee91035e6116566040518060400160405280600e81526020017f726f636b6574546f6b656e52504c0000000000000000000000000000000000008152506136ee565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815260606004820152601460648201527f726f636b657441756374696f6e4d616e6167657200000000000000000000000060848201526001600160a01b0390911660248201526044810185905260a401600060405180830381600087803b1580156116ea57600080fd5b505af11580156116fe573d6000803e3d6000fd5b505050505b61170c82613c19565b6117168983613873565b6040517f6d696e69706f6f6c2e72706c2e736c617368656400000000000000000000000060208201526bffffffffffffffffffffffff193360601b16603482015261177b90604801604051602081830303815290604052805190602001206001613b91565b60408051838152602081018a9052428183015290516001600160a01b038b16917f38a2777b6a84fdb3fc375fe8ade69fdad1afdcdd93c79e7ae2319b806a626c4d919081900360600190a2505050505050505050565b6040518060400160405280601181526020017f726f636b65744e6f64655374616b696e670000000000000000000000000000008152503061181c8260405160200161057b919061448d565b6001600160a01b0316816001600160a01b03161461187c5760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016105f2565b6040517f636f6e74726163742e657869737473000000000000000000000000000000000060208201526bffffffffffffffffffffffff193360601b16602f8201526118c990604301610644565b61193a5760405162461bcd60e51b8152602060048201526024808201527f496e76616c6964206f72206f75746461746564206e6574776f726b20636f6e7460448201527f726163740000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6040517f72706c2e6c6f636b65642e6e6f64652e616d6f756e740000000000000000000060208201526bffffffffffffffffffffffff19606086901b166036820152600090604a0160405160208183030381529060405280519060200120905060006119a582613c43565b9050808511156119f75760405162461bcd60e51b815260206004820152601560248201527f4e6f7420656e6f756768206c6f636b65642052504c000000000000000000000060448201526064016105f2565b611a0a82611a05878461451f565b613cce565b604080518681524260208201526001600160a01b038816917f95f42213e171837caaa6cc7f589ef03a30179b7b85e386dfb146a30c5b10cfa99101610ba9565b6040518060400160405280601181526020017f726f636b65744e6f64655374616b696e6700000000000000000000000000000081525030611a958260405160200161057b919061448d565b6001600160a01b0316816001600160a01b031614611af55760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016105f2565b846000611b366040518060400160405280601181526020017f726f636b65744e6f64654d616e616765720000000000000000000000000000008152506136ee565b6040517fe667d8280000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301529192509082169063e667d82890602401602060405180830381865afa158015611b99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bbd91906144e5565b15611ccf576040517fb71f0c7c0000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301526000919083169063b71f0c7c90602401602060405180830381865afa158015611c25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c499190614502565b9050336001600160a01b03821614611cc95760405162461bcd60e51b815260206004820152602a60248201527f4d7573742062652063616c6c65642066726f6d2052504c20776974686472617760448201527f616c20616464726573730000000000000000000000000000000000000000000060648201526084016105f2565b50611d27565b336001600160a01b03831614611d275760405162461bcd60e51b815260206004820181905260248201527f4d7573742062652063616c6c65642066726f6d206e6f6465206164647265737360448201526064016105f2565b6040517f6e6f64652e7374616b652e666f722e616c6c6f7765640000000000000000000060208201526bffffffffffffffffffffffff19606089811b8216603684015288901b16604a820152611d7f90605e01610b4f565b6040805186151581524260208201526001600160a01b0380891692908a16917fb8502fe170368d1312ca3c9feac7aba9cd92406753d7eca9f11df9757081aec5910160405180910390a350505050505050565b611ddc3382612e27565b50565b600080611e206040518060400160405280601d81526020017f726f636b657444414f50726f746f636f6c53657474696e67734e6f64650000008152506136ee565b90506000816001600160a01b0316636fdbe57b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e8691906143f3565b905080600003611eb957507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9392505050565b6000611ef96040518060400160405280601381526020017f726f636b65744e6574776f726b507269636573000000000000000000000000008152506136ee565b905081816001600160a01b031663724d4a096040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5e91906143f3565b611f678761229f565b611f71919061443b565b611f7b9190614452565b95945050505050565b600080611fc56040518060400160405280601381526020017f726f636b65744e6574776f726b507269636573000000000000000000000000008152506136ee565b905060006120076040518060400160405280601d81526020017f726f636b657444414f50726f746f636f6c53657474696e67734e6f64650000008152506136ee565b90506000816001600160a01b0316631e72ba866040518163ffffffff1660e01b8152600401602060405180830381865afa158015612049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061206d91906143f3565b9050600061049f866132ba565b6040517f72706c2e6c6f636b696e672e616c6c6f7765640000000000000000000000000060208201526bffffffffffffffffffffffff19606083901b1660338201526000906120cb90604701610644565b92915050565b611ddc3382610bb9565b6000806120e783612850565b90508060000361210b57612104670de0b6b3a7640000600261443b565b9392505050565b600061212e604051806060016040528060218152602001614623602191396136ee565b90506000816001600160a01b03166308e50d386040518163ffffffff1660e01b8152600401602060405180830381865afa158015612170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061219491906143f3565b905060006121d66040518060400160405280601581526020017f726f636b65744d696e69706f6f6c4d616e6167657200000000000000000000008152506136ee565b6040517f1844ec010000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152919250600091849190841690631844ec0190602401602060405180830381865afa15801561223e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226291906143f3565b61226c919061443b565b9050612278858261451f565b61228a670de0b6b3a76400008361443b565b6122949190614452565b979650505050505050565b6040517f72706c2e7374616b65642e6e6f64652e616d6f756e740000000000000000000060208201526bffffffffffffffffffffffff19606083901b1660368201526000908190604a0160405160208183030381529060405280519060200120905060006123416040518060400160405280601681526020017f726f636b65744e6574776f726b536e617073686f7473000000000000000000008152506136ee565b9050600080826001600160a01b03166379feb107856040518263ffffffff1660e01b815260040161237491815260200190565b606060405180830381865afa158015612391573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b59190614545565b919350909150507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116826105175761229485613c43565b60006124147fe9120b7223ae2a37e3e3d2dfb439c54ebbdeabe89bce6d355f59122854c4a306613c43565b905090565b6040518060400160405280601181526020017f726f636b65744e6f64655374616b696e67000000000000000000000000000000815250306124648260405160200161057b919061448d565b6001600160a01b0316816001600160a01b0316146124c45760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016105f2565b6040517f636f6e74726163742e657869737473000000000000000000000000000000000060208201526bffffffffffffffffffffffff193360601b16602f82015261251190604301610644565b6125825760405162461bcd60e51b8152602060048201526024808201527f496e76616c6964206f72206f75746461746564206e6574776f726b20636f6e7460448201527f726163740000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606086901b16602b82015284906125d290603f01610644565b61261e5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016105f2565b836126288661229f565b10156126765760405162461bcd60e51b815260206004820152601960248201527f4e6f64652068617320696e73756666696369656e742052504c0000000000000060448201526064016105f2565b61267f84613c19565b6126898585613873565b60006126c96040518060400160405280600e81526020017f726f636b6574546f6b656e52504c0000000000000000000000000000000000008152506136ee565b9050600061270b6040518060400160405280600b81526020017f726f636b65745661756c740000000000000000000000000000000000000000008152506136ee565b6040517f01e336670000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03848116602483015260448201899052919250908216906301e3366790606401600060405180830381600087803b15801561277857600080fd5b505af115801561278c573d6000803e3d6000fd5b50506040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018990526001600160a01b03851692506342966c689150602401600060405180830381600087803b1580156127eb57600080fd5b505af11580156127ff573d6000803e3d6000fd5b5050604080518981524260208201526001600160a01b038b1693507f7a3b7812b93ab45ed01ea9fc22b37301461966d61ca09bc0859a84ca07298b129250015b60405180910390a250505050505050565b6000806128916040518060400160405280601681526020017f726f636b65744e6574776f726b536e617073686f7473000000000000000000008152506136ee565b6040517f6574682e6d6174636865642e6e6f64652e616d6f756e7400000000000000000060208201526bffffffffffffffffffffffff19606086901b166037820152909150600090604b01604051602081830303815290604052805190602001209050600080836001600160a01b03166379feb107846040518263ffffffff1660e01b815260040161292591815260200190565b606060405180830381865afa158015612942573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129669190614545565b92505091508115612998577bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1695945050505050565b60006129a384613c43565b905080156129b5579695505050505050565b60006129f56040518060400160405280601581526020017f726f636b65744d696e69706f6f6c4d616e6167657200000000000000000000008152506136ee565b6040517f1844ec010000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015291925090821690631844ec0190602401602060405180830381865afa158015612a58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7c91906143f3565b612a8e9067de0b6b3a7640000061443b565b98975050505050505050565b6040517f72706c2e7374616b65642e6e6f64652e74696d6500000000000000000000000060208201526bffffffffffffffffffffffff19606083901b1660348201526000906120cb906048015b60405160208183030381529060405280519060200120613c43565b6040518060400160405280601181526020017f726f636b65744e6f64655374616b696e6700000000000000000000000000000081525030612b4d8260405160200161057b919061448d565b6001600160a01b0316816001600160a01b031614612bad5760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016105f2565b6040517f636f6e74726163742e657869737473000000000000000000000000000000000060208201526bffffffffffffffffffffffff193360601b16602f820152612bfa90604301610644565b612c6b5760405162461bcd60e51b8152602060048201526024808201527f496e76616c6964206f72206f75746461746564206e6574776f726b20636f6e7460448201527f726163740000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6040517f72706c2e6c6f636b696e672e616c6c6f7765640000000000000000000000000060208201526bffffffffffffffffffffffff19606086901b166033820152612cb990604701610644565b612d055760405162461bcd60e51b815260206004820152601f60248201527f4e6f6465206973206e6f7420616c6c6f77656420746f206c6f636b2052504c0060448201526064016105f2565b6000612d108561229f565b6040517f72706c2e6c6f636b65642e6e6f64652e616d6f756e740000000000000000000060208201526bffffffffffffffffffffffff19606088901b166036820152909150600090604a016040516020818303038152906040528051906020012090506000612d7e82613c43565b905085612d8b828561451f565b1015612dd95760405162461bcd60e51b815260206004820152601560248201527f4e6f7420656e6f756768207374616b65642052504c000000000000000000000060448201526064016105f2565b612de782611a058884614532565b604080518781524260208201526001600160a01b038916917fce4a5a05852c75132c79a7a41af76ced563f8391e69eea41a0b38214c4e847cf910161283f565b6040518060400160405280601181526020017f726f636b65744e6f64655374616b696e6700000000000000000000000000000081525030612e728260405160200161057b919061448d565b6001600160a01b0316816001600160a01b031614612ed25760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016105f2565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606086901b16602b8201528490612f2290603f01610644565b612f6e5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016105f2565b6040517f636f6e74726163742e616464726573730000000000000000000000000000000060208201527f726f636b65744d65726b6c654469737472696275746f724d61696e6e657400006030820152612fc990604e0161057b565b6001600160a01b0316336001600160a01b0316146132a95760006130216040518060400160405280601181526020017f726f636b65744e6f64654d616e616765720000000000000000000000000000008152506136ee565b6040517fe667d8280000000000000000000000000000000000000000000000000000000081526001600160a01b03888116600483015291925060009183169063e667d82890602401602060405180830381865afa158015613086573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130aa91906144e5565b1561314a576040517fb71f0c7c0000000000000000000000000000000000000000000000000000000081526001600160a01b0388811660048301526000919084169063b71f0c7c90602401602060405180830381865afa158015613112573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131369190614502565b6001600160a01b0316331491506131fd9050565b600080546040517f5b49ff620000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015261010090920490911690635b49ff6290602401602060405180830381865afa1580156131b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131d89190614502565b9050336001600160a01b03891614806131f95750336001600160a01b038216145b9150505b806132a6576040517f6e6f64652e7374616b652e666f722e616c6c6f7765640000000000000000000060208201526bffffffffffffffffffffffff19606089811b8216603684015233901b16604a82015261325a90605e01610644565b6132a65760405162461bcd60e51b815260206004820152601860248201527f4e6f7420616c6c6f77656420746f207374616b6520666f72000000000000000060448201526064016105f2565b50505b6132b38585613d23565b5050505050565b6000806132fb6040518060400160405280601581526020017f726f636b65744d696e69706f6f6c4d616e6167657200000000000000000000008152506136ee565b6040517f1844ec010000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152919250600091831690631844ec0190602401602060405180830381865afa158015613360573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338491906143f3565b9050600061339185612850565b9050801561343c5760006133bc604051806060016040528060218152602001614623602191396136ee565b90506000816001600160a01b03166308e50d386040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342291906143f3565b90506000613430828661443b565b9050612a8e848261451f565b611f7b8267de0b6b3a7640000061443b565b60008061348f6040518060400160405280601381526020017f726f636b65744e6574776f726b507269636573000000000000000000000000008152506136ee565b905060006134d16040518060400160405280601d81526020017f726f636b657444414f50726f746f636f6c53657474696e67734e6f64650000008152506136ee565b905060006134de8561229f565b905060006134eb86612850565b905060006134f8876132ba565b90506000856001600160a01b031663724d4a096040518163ffffffff1660e01b8152600401602060405180830381865afa15801561353a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061355e91906143f3565b90506000856001600160a01b0316631e72ba866040518163ffffffff1660e01b8152600401602060405180830381865afa1580156135a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135c491906143f3565b90506000826135d3838661443b565b6135dd9190614452565b9050808611156135f4579998505050505050505050565b6000876001600160a01b0316636fdbe57b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613634573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061365891906143f3565b9050600084613667838961443b565b6136719190614452565b90508088101561368d575060009b9a5050505050505050505050565b50959a9950505050505050505050565b6040517f72706c2e6c6f636b65642e6e6f64652e616d6f756e740000000000000000000060208201526bffffffffffffffffffffffff19606083901b1660368201526000906120cb90604a01612ae7565b6000806137058360405160200161057b919061448d565b90506001600160a01b0381166120cb5760405162461bcd60e51b815260206004820152601260248201527f436f6e7472616374206e6f7420666f756e64000000000000000000000000000060448201526064016105f2565b600080546040517f21f8a721000000000000000000000000000000000000000000000000000000008152600481018490526101009091046001600160a01b0316906321f8a72190602401602060405180830381865afa1580156137c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120cb9190614502565b600080546040517f7ae1cfca000000000000000000000000000000000000000000000000000000008152600481018490526101009091046001600160a01b031690637ae1cfca90602401602060405180830381865afa15801561384f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120cb91906144e5565b60006138b36040518060400160405280601681526020017f726f636b65744e6574776f726b536e617073686f7473000000000000000000008152506136ee565b6040517f72706c2e7374616b65642e6e6f64652e616d6f756e740000000000000000000060208201526bffffffffffffffffffffffff19606086901b166036820152909150600090604a01604051602081830303815290604052805190602001209050600080836001600160a01b03166379feb107846040518263ffffffff1660e01b815260040161394791815260200190565b606060405180830381865afa158015613964573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139889190614545565b92505091508161399e5761399b83613c43565b90505b6001600160a01b038416635ba59649846139b888856145b1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166024820152604401600060405180830381600087803b158015613a2c57600080fd5b505af1158015613a40573d6000803e3d6000fd5b50505050505050505050565b6000613a8c6040518060400160405280601681526020017f726f636b65744e6574776f726b536e617073686f7473000000000000000000008152506136ee565b6040517f72706c2e7374616b65642e6e6f64652e616d6f756e740000000000000000000060208201526bffffffffffffffffffffffff19606086901b166036820152909150600090604a01604051602081830303815290604052805190602001209050600080836001600160a01b03166379feb107846040518263ffffffff1660e01b8152600401613b2091815260200190565b606060405180830381865afa158015613b3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b619190614545565b925050915081613b7757613b7483613c43565b90505b6001600160a01b038416635ba59649846139b888856145ed565b6000546040517fabfdcced0000000000000000000000000000000000000000000000000000000081526004810184905282151560248201526101009091046001600160a01b03169063abfdcced906044015b600060405180830381600087803b158015613bfd57600080fd5b505af1158015613c11573d6000803e3d6000fd5b505050505050565b611ddc7fe9120b7223ae2a37e3e3d2dfb439c54ebbdeabe89bce6d355f59122854c4a30682614170565b600080546040517fbd02d0f5000000000000000000000000000000000000000000000000000000008152600481018490526101009091046001600160a01b03169063bd02d0f590602401602060405180830381865afa158015613caa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120cb91906143f3565b6000546040517fe2a4853a00000000000000000000000000000000000000000000000000000000815260048101849052602481018390526101009091046001600160a01b03169063e2a4853a90604401613be3565b6000613d636040518060400160405280601381526020017f726f636b65744e6574776f726b566f74696e67000000000000000000000000008152506136ee565b6040517fbdbc6d420000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301529192509082169063bdbc6d4290602401600060405180830381600087803b158015613dc357600080fd5b505af1158015613dd7573d6000803e3d6000fd5b505050506000613e1b6040518060400160405280600e81526020017f726f636b6574546f6b656e52504c0000000000000000000000000000000000008152506136ee565b90506000613e5d6040518060400160405280600b81526020017f726f636b65745661756c740000000000000000000000000000000000000000008152506136ee565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101869052909150829082906001600160a01b038316906323b872dd906064016020604051808303816000875af1158015613ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ef491906144e5565b613f665760405162461bcd60e51b815260206004820152602a60248201527f436f756c64206e6f74207472616e736665722052504c20746f207374616b696e60448201527f6720636f6e74726163740000000000000000000000000000000000000000000060648201526084016105f2565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301526024820188905283169063095ea7b3906044016020604051808303816000875af1158015613fce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ff291906144e5565b6140645760405162461bcd60e51b815260206004820152602360248201527f436f756c64206e6f7420617070726f7665207661756c742052504c206465706f60448201527f736974000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6040517ff444295800000000000000000000000000000000000000000000000000000000815260606004820152601160648201527f726f636b65744e6f64655374616b696e6700000000000000000000000000000060848201526001600160a01b0383811660248301526044820188905282169063f44429589060a401600060405180830381600087803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b5050505061411c866141c5565b6141268787613a4c565b61413087426141ef565b604080518781524260208201526001600160a01b038916917f4e3bcb61bb8e63cb9ed2c46d47eeb6ae847c629e909fbb32b9d17874affb4a89910161283f565b6000546040517febb9d8c900000000000000000000000000000000000000000000000000000000815260048101849052602481018390526101009091046001600160a01b03169063ebb9d8c990604401613be3565b611ddc7fe9120b7223ae2a37e3e3d2dfb439c54ebbdeabe89bce6d355f59122854c4a30682614254565b6040517f72706c2e7374616b65642e6e6f64652e74696d6500000000000000000000000060208201526bffffffffffffffffffffffff19606084901b16603482015261052c906048016040516020818303038152906040528051906020012082613cce565b6000546040517fadb353dc00000000000000000000000000000000000000000000000000000000815260048101849052602481018390526101009091046001600160a01b03169063adb353dc90604401613be3565b6001600160a01b0381168114611ddc57600080fd5b6000602082840312156142d057600080fd5b8135612104816142a9565b8015158114611ddc57600080fd5b600080604083850312156142fc57600080fd5b8235614307816142a9565b91506020830135614317816142db565b809150509250929050565b60008060006060848603121561433757600080fd5b8335614342816142a9565b92506020840135614352816142a9565b929592945050506040919091013590565b6000806040838503121561437657600080fd5b8235614381816142a9565b946020939093013593505050565b6000806000606084860312156143a457600080fd5b83356143af816142a9565b925060208401356143bf816142a9565b915060408401356143cf816142db565b809150509250925092565b6000602082840312156143ec57600080fd5b5035919050565b60006020828403121561440557600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176120cb576120cb61440c565b600082614488577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f636f6e74726163742e616464726573730000000000000000000000000000000081526000825160005b818110156144d457602081860181015160108684010152016144b7565b506000920160100191825250919050565b6000602082840312156144f757600080fd5b8151612104816142db565b60006020828403121561451457600080fd5b8151612104816142a9565b818103818111156120cb576120cb61440c565b808201808211156120cb576120cb61440c565b60008060006060848603121561455a57600080fd5b8351614565816142db565b602085015190935063ffffffff8116811461457f57600080fd5b60408501519092507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146143cf57600080fd5b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8281168282160390808211156145e6576145e661440c565b5092915050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8181168382160190808211156145e6576145e661440c56fe726f636b657444414f50726f746f636f6c53657474696e67734d696e69706f6f6ca26469706673582212201d3ffa5fe5954fb80cb77aa8a195a8c6957efcc8474d1c37fcbcb600b8cb831364736f6c63430008120033
Verified Source Code Partial Match
Compiler: v0.8.18+commit.87f61d96
EVM: paris
Optimization: Yes (15000 runs)
NodeDetails.sol 61 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
// A struct containing all the information on-chain about a specific node
struct NodeDetails {
bool exists;
uint256 registrationTime;
string timezoneLocation;
bool feeDistributorInitialised;
address feeDistributorAddress;
uint256 rewardNetwork;
uint256 rplStake;
uint256 effectiveRPLStake;
uint256 minimumRPLStake;
uint256 maximumRPLStake;
uint256 ethMatched;
uint256 ethMatchedLimit;
uint256 minipoolCount;
uint256 balanceETH;
uint256 balanceRETH;
uint256 balanceRPL;
uint256 balanceOldRPL;
uint256 depositCreditBalance;
uint256 distributorBalanceUserETH;
uint256 distributorBalanceNodeETH;
address withdrawalAddress;
address pendingWithdrawalAddress;
bool smoothingPoolRegistrationState;
uint256 smoothingPoolRegistrationChanged;
address nodeAddress;
}
RocketBase.sol 190 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
import "../interface/RocketStorageInterface.sol";
/// @title Base settings / modifiers for each contract in Rocket Pool
/// @author David Rugendyke
abstract contract RocketBase {
// Calculate using this as the base
uint256 constant calcBase = 1 ether;
// Version of the contract
uint8 public version;
// The main storage contract where primary persistant storage is maintained
RocketStorageInterface rocketStorage = RocketStorageInterface(address(0));
/*** Modifiers **********************************************************/
/**
* @dev Throws if called by any sender that doesn't match a Rocket Pool network contract
*/
modifier onlyLatestNetworkContract() {
require(getBool(keccak256(abi.encodePacked("contract.exists", msg.sender))), "Invalid or outdated network contract");
_;
}
/**
* @dev Throws if called by any sender that doesn't match one of the supplied contract or is the latest version of that contract
*/
modifier onlyLatestContract(string memory _contractName, address _contractAddress) {
require(_contractAddress == getAddress(keccak256(abi.encodePacked("contract.address", _contractName))), "Invalid or outdated contract");
_;
}
/**
* @dev Throws if called by any sender that isn't a registered node
*/
modifier onlyRegisteredNode(address _nodeAddress) {
require(getBool(keccak256(abi.encodePacked("node.exists", _nodeAddress))), "Invalid node");
_;
}
/**
* @dev Throws if called by any sender that isn't a trusted node DAO member
*/
modifier onlyTrustedNode(address _nodeAddress) {
require(getBool(keccak256(abi.encodePacked("dao.trustednodes.", "member", _nodeAddress))), "Invalid trusted node");
_;
}
/**
* @dev Throws if called by any sender that isn't a registered minipool
*/
modifier onlyRegisteredMinipool(address _minipoolAddress) {
require(getBool(keccak256(abi.encodePacked("minipool.exists", _minipoolAddress))), "Invalid minipool");
_;
}
/**
* @dev Throws if called by any account other than a guardian account (temporary account allowed access to settings before DAO is fully enabled)
*/
modifier onlyGuardian() {
require(msg.sender == rocketStorage.getGuardian(), "Account is not a temporary guardian");
_;
}
/*** Methods **********************************************************/
/// @dev Set the main Rocket Storage address
constructor(RocketStorageInterface _rocketStorageAddress) {
// Update the contract address
rocketStorage = RocketStorageInterface(_rocketStorageAddress);
}
/// @dev Get the address of a network contract by name
function getContractAddress(string memory _contractName) internal view returns (address) {
// Get the current contract address
address contractAddress = getAddress(keccak256(abi.encodePacked("contract.address", _contractName)));
// Check it
require(contractAddress != address(0x0), "Contract not found");
// Return
return contractAddress;
}
/// @dev Get the address of a network contract by name (returns address(0x0) instead of reverting if contract does not exist)
function getContractAddressUnsafe(string memory _contractName) internal view returns (address) {
// Get the current contract address
address contractAddress = getAddress(keccak256(abi.encodePacked("contract.address", _contractName)));
// Return
return contractAddress;
}
/// @dev Get the name of a network contract by address
function getContractName(address _contractAddress) internal view returns (string memory) {
// Get the contract name
string memory contractName = getString(keccak256(abi.encodePacked("contract.name", _contractAddress)));
// Check it
require(bytes(contractName).length > 0, "Contract not found");
// Return
return contractName;
}
/// @dev Get revert error message from a .call method
function getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {
// If the _res length is less than 68, then the transaction failed silently (without a revert message)
if (_returnData.length < 68) return "Transaction reverted silently";
assembly {
// Slice the sighash.
_returnData := add(_returnData, 0x04)
}
return abi.decode(_returnData, (string)); // All that remains is the revert string
}
/*** Rocket Storage Methods ****************************************/
// Note: Unused helpers have been removed to keep contract sizes down
/// @dev Storage get methods
function getAddress(bytes32 _key) internal view returns (address) { return rocketStorage.getAddress(_key); }
function getUint(bytes32 _key) internal view returns (uint) { return rocketStorage.getUint(_key); }
function getString(bytes32 _key) internal view returns (string memory) { return rocketStorage.getString(_key); }
function getBytes(bytes32 _key) internal view returns (bytes memory) { return rocketStorage.getBytes(_key); }
function getBool(bytes32 _key) internal view returns (bool) { return rocketStorage.getBool(_key); }
function getInt(bytes32 _key) internal view returns (int) { return rocketStorage.getInt(_key); }
function getBytes32(bytes32 _key) internal view returns (bytes32) { return rocketStorage.getBytes32(_key); }
/// @dev Storage set methods
function setAddress(bytes32 _key, address _value) internal { rocketStorage.setAddress(_key, _value); }
function setUint(bytes32 _key, uint _value) internal { rocketStorage.setUint(_key, _value); }
function setString(bytes32 _key, string memory _value) internal { rocketStorage.setString(_key, _value); }
function setBytes(bytes32 _key, bytes memory _value) internal { rocketStorage.setBytes(_key, _value); }
function setBool(bytes32 _key, bool _value) internal { rocketStorage.setBool(_key, _value); }
function setInt(bytes32 _key, int _value) internal { rocketStorage.setInt(_key, _value); }
function setBytes32(bytes32 _key, bytes32 _value) internal { rocketStorage.setBytes32(_key, _value); }
/// @dev Storage delete methods
function deleteAddress(bytes32 _key) internal { rocketStorage.deleteAddress(_key); }
function deleteUint(bytes32 _key) internal { rocketStorage.deleteUint(_key); }
function deleteString(bytes32 _key) internal { rocketStorage.deleteString(_key); }
function deleteBytes(bytes32 _key) internal { rocketStorage.deleteBytes(_key); }
function deleteBool(bytes32 _key) internal { rocketStorage.deleteBool(_key); }
function deleteInt(bytes32 _key) internal { rocketStorage.deleteInt(_key); }
function deleteBytes32(bytes32 _key) internal { rocketStorage.deleteBytes32(_key); }
/// @dev Storage arithmetic methods
function addUint(bytes32 _key, uint256 _amount) internal { rocketStorage.addUint(_key, _amount); }
function subUint(bytes32 _key, uint256 _amount) internal { rocketStorage.subUint(_key, _amount); }
}
MinipoolStatus.sol 41 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
// Represents a minipool's status within the network
enum MinipoolStatus {
Initialised, // The minipool has been initialised and is awaiting a deposit of user ETH
Prelaunch, // The minipool has enough ETH to begin staking and is awaiting launch by the node operator
Staking, // The minipool is currently staking
Withdrawable, // NO LONGER USED
Dissolved // The minipool has been dissolved and its user deposited ETH has been returned to the deposit pool
}
IERC20.sol 106 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity >0.5.0 <0.9.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);
}
MinipoolDeposit.sol 41 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
// Represents the type of deposits required by a minipool
enum MinipoolDeposit {
None, // Marks an invalid deposit type
Full, // The minipool requires 32 ETH from the node operator, 16 ETH of which will be refinanced from user deposits
Half, // The minipool required 16 ETH from the node operator to be matched with 16 ETH from user deposits
Empty, // The minipool requires 0 ETH from the node operator to be matched with 32 ETH from user deposits (trusted nodes only)
Variable // Indicates this minipool is of the new generation that supports a variable deposit amount
}
MinipoolDetails.sol 60 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
import "./MinipoolDeposit.sol";
import "./MinipoolStatus.sol";
// A struct containing all the information on-chain about a specific minipool
struct MinipoolDetails {
bool exists;
address minipoolAddress;
bytes pubkey;
MinipoolStatus status;
uint256 statusBlock;
uint256 statusTime;
bool finalised;
MinipoolDeposit depositType;
uint256 nodeFee;
uint256 nodeDepositBalance;
bool nodeDepositAssigned;
uint256 userDepositBalance;
bool userDepositAssigned;
uint256 userDepositAssignedTime;
bool useLatestDelegate;
address delegate;
address previousDelegate;
address effectiveDelegate;
uint256 penaltyCount;
uint256 penaltyRate;
address nodeAddress;
}
IERC20Burnable.sol 39 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
import "./IERC20.sol";
pragma solidity >0.5.0 <0.9.0;
interface IERC20Burnable is IERC20 {
function burn(uint256 amount) external;
function burnFrom(address account, uint256 amount) external;
}
Math.sol 339 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @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.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
RocketVaultInterface.sol 43 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
import "./util/IERC20Burnable.sol";
interface RocketVaultInterface {
function balanceOf(string memory _networkContractName) external view returns (uint256);
function depositEther() external payable;
function withdrawEther(uint256 _amount) external;
function depositToken(string memory _networkContractName, IERC20 _tokenAddress, uint256 _amount) external;
function withdrawToken(address _withdrawalAddress, IERC20 _tokenAddress, uint256 _amount) external;
function balanceOfToken(string memory _networkContractName, IERC20 _tokenAddress) external view returns (uint256);
function transferToken(string memory _networkContractName, IERC20 _tokenAddress, uint256 _amount) external;
function burnToken(IERC20Burnable _tokenAddress, uint256 _amount) external;
}
RocketNodeStaking.sol 510 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.18;
import "../../interface/util/IERC20.sol";
import "../RocketBase.sol";
import "../../interface/minipool/RocketMinipoolManagerInterface.sol";
import "../../interface/network/RocketNetworkPricesInterface.sol";
import "../../interface/node/RocketNodeStakingInterface.sol";
import "../../interface/dao/protocol/settings/RocketDAOProtocolSettingsRewardsInterface.sol";
import "../../interface/dao/protocol/settings/RocketDAOProtocolSettingsMinipoolInterface.sol";
import "../../interface/dao/protocol/settings/RocketDAOProtocolSettingsNodeInterface.sol";
import "../../interface/RocketVaultInterface.sol";
import "../../interface/util/AddressSetStorageInterface.sol";
import "../../interface/network/RocketNetworkSnapshotsInterface.sol";
import "../network/RocketNetworkSnapshots.sol";
import "../../interface/node/RocketNodeManagerInterface.sol";
import "../../interface/network/RocketNetworkVotingInterface.sol";
/// @notice Handles node deposits and minipool creation
contract RocketNodeStaking is RocketBase, RocketNodeStakingInterface {
// Constants
bytes32 immutable internal totalKey;
// Events
event RPLStaked(address indexed from, uint256 amount, uint256 time);
event RPLWithdrawn(address indexed to, uint256 amount, uint256 time);
event RPLSlashed(address indexed node, uint256 amount, uint256 ethValue, uint256 time);
event StakeRPLForAllowed(address indexed node, address indexed caller, bool allowed, uint256 time);
event RPLLockingAllowed(address indexed node, bool allowed, uint256 time);
event RPLLocked(address indexed from, uint256 amount, uint256 time);
event RPLUnlocked(address indexed from, uint256 amount, uint256 time);
event RPLTransferred(address indexed from, address indexed to, uint256 amount, uint256 time);
event RPLBurned(address indexed from, uint256 amount, uint256 time);
modifier onlyRPLWithdrawalAddressOrNode(address _nodeAddress) {
// Check that the call is coming from RPL withdrawal address (or node if unset)
RocketNodeManagerInterface rocketNodeManager = RocketNodeManagerInterface(getContractAddress("rocketNodeManager"));
if (rocketNodeManager.getNodeRPLWithdrawalAddressIsSet(_nodeAddress)) {
address rplWithdrawalAddress = rocketNodeManager.getNodeRPLWithdrawalAddress(_nodeAddress);
require(msg.sender == rplWithdrawalAddress, "Must be called from RPL withdrawal address");
} else {
require(msg.sender == _nodeAddress, "Must be called from node address");
}
_;
}
constructor(RocketStorageInterface _rocketStorageAddress) RocketBase(_rocketStorageAddress) {
version = 6;
// Precompute keys
totalKey = keccak256(abi.encodePacked("rpl.staked.total.amount"));
}
/// @notice Returns the total quantity of RPL staked on the network
function getTotalRPLStake() override external view returns (uint256) {
return getUint(totalKey);
}
/// @dev Increases the total network RPL stake
/// @param _amount How much to increase by
function increaseTotalRPLStake(uint256 _amount) private {
addUint(totalKey, _amount);
}
/// @dev Decrease the total network RPL stake
/// @param _amount How much to decrease by
function decreaseTotalRPLStake(uint256 _amount) private {
subUint(totalKey, _amount);
}
/// @notice Returns the amount a given node operator has staked
/// @param _nodeAddress The address of the node operator to query
function getNodeRPLStake(address _nodeAddress) override public view returns (uint256) {
bytes32 key = keccak256(abi.encodePacked("rpl.staked.node.amount", _nodeAddress));
RocketNetworkSnapshotsInterface rocketNetworkSnapshots = RocketNetworkSnapshotsInterface(getContractAddress("rocketNetworkSnapshots"));
(bool exists,, uint224 value) = rocketNetworkSnapshots.latest(key);
uint256 stake = uint256(value);
if (!exists){
// Fallback to old value
stake = getUint(key);
}
return stake;
}
/// @dev Increases a node operator's RPL stake
/// @param _amount How much to increase by
function increaseNodeRPLStake(address _nodeAddress, uint256 _amount) private {
RocketNetworkSnapshotsInterface rocketNetworkSnapshots = RocketNetworkSnapshotsInterface(getContractAddress("rocketNetworkSnapshots"));
bytes32 key = keccak256(abi.encodePacked("rpl.staked.node.amount", _nodeAddress));
(bool exists,, uint224 value) = rocketNetworkSnapshots.latest(key);
if (!exists){
value = uint224(getUint(key));
}
rocketNetworkSnapshots.push(key, value + uint224(_amount));
}
/// @dev Decrease a node operator's RPL stake
/// @param _amount How much to decrease by
function decreaseNodeRPLStake(address _nodeAddress, uint256 _amount) private {
RocketNetworkSnapshotsInterface rocketNetworkSnapshots = RocketNetworkSnapshotsInterface(getContractAddress("rocketNetworkSnapshots"));
bytes32 key = keccak256(abi.encodePacked("rpl.staked.node.amount", _nodeAddress));
(bool exists,, uint224 value) = rocketNetworkSnapshots.latest(key);
if (!exists){
value = uint224(getUint(key));
}
rocketNetworkSnapshots.push(key, value - uint224(_amount));
}
/// @notice Returns a node's matched ETH amount (amount taken from protocol to stake)
/// @param _nodeAddress The address of the node operator to query
function getNodeETHMatched(address _nodeAddress) override public view returns (uint256) {
RocketNetworkSnapshotsInterface rocketNetworkSnapshots = RocketNetworkSnapshotsInterface(getContractAddress("rocketNetworkSnapshots"));
bytes32 key = keccak256(abi.encodePacked("eth.matched.node.amount", _nodeAddress));
(bool exists, , uint224 value) = rocketNetworkSnapshots.latest(key);
if (exists) {
// Value was previously set in a snapshot so return that
return value;
} else {
// Fallback to old method
uint256 ethMatched = getUint(key);
if (ethMatched > 0) {
// Value was previously calculated and stored so return that
return ethMatched;
} else {
// Fallback for backwards compatibility before ETH matched was recorded (all legacy minipools matched 16 ETH from protocol)
RocketMinipoolManagerInterface rocketMinipoolManager = RocketMinipoolManagerInterface(getContractAddress("rocketMinipoolManager"));
return rocketMinipoolManager.getNodeActiveMinipoolCount(_nodeAddress) * 16 ether;
}
}
}
/// @notice Returns a node's provided ETH amount (amount supplied to create minipools)
/// @param _nodeAddress The address of the node operator to query
function getNodeETHProvided(address _nodeAddress) override public view returns (uint256) {
// Get contracts
RocketMinipoolManagerInterface rocketMinipoolManager = RocketMinipoolManagerInterface(getContractAddress("rocketMinipoolManager"));
uint256 activeMinipoolCount = rocketMinipoolManager.getNodeActiveMinipoolCount(_nodeAddress);
// Retrieve stored ETH matched value
uint256 ethMatched = getNodeETHMatched(_nodeAddress);
if (ethMatched > 0) {
RocketDAOProtocolSettingsMinipoolInterface rocketDAOProtocolSettingsMinipool = RocketDAOProtocolSettingsMinipoolInterface(getContractAddress("rocketDAOProtocolSettingsMinipool"));
uint256 launchAmount = rocketDAOProtocolSettingsMinipool.getLaunchBalance();
// ETH provided is number of staking minipools * 32 - eth matched
uint256 totalEthStaked = activeMinipoolCount * launchAmount;
return totalEthStaked - ethMatched;
} else {
// Fallback for legacy minipools is number of staking minipools * 16
return activeMinipoolCount * 16 ether;
}
}
/// @notice Returns the ratio between capital taken from users and provided by a node operator.
/// The value is a 1e18 precision fixed point integer value of (node capital + user capital) / node capital.
/// @param _nodeAddress The address of the node operator to query
function getNodeETHCollateralisationRatio(address _nodeAddress) override public view returns (uint256) {
uint256 ethMatched = getNodeETHMatched(_nodeAddress);
if (ethMatched == 0) {
// Node operator only has legacy minipools and all legacy minipools had a 1:1 ratio
return calcBase * 2;
} else {
RocketDAOProtocolSettingsMinipoolInterface rocketDAOProtocolSettingsMinipool = RocketDAOProtocolSettingsMinipoolInterface(getContractAddress("rocketDAOProtocolSettingsMinipool"));
uint256 launchAmount = rocketDAOProtocolSettingsMinipool.getLaunchBalance();
RocketMinipoolManagerInterface rocketMinipoolManager = RocketMinipoolManagerInterface(getContractAddress("rocketMinipoolManager"));
uint256 totalEthStaked = rocketMinipoolManager.getNodeActiveMinipoolCount(_nodeAddress) * launchAmount;
return (totalEthStaked * calcBase) / (totalEthStaked - ethMatched);
}
}
/// @notice Returns the timestamp at which a node last staked RPL
function getNodeRPLStakedTime(address _nodeAddress) override public view returns (uint256) {
return getUint(keccak256(abi.encodePacked("rpl.staked.node.time", _nodeAddress)));
}
/// @dev Sets the timestamp at which a node last staked RPL
/// @param _nodeAddress The address of the node operator to set the value for
/// @param _time The timestamp to set
function setNodeRPLStakedTime(address _nodeAddress, uint256 _time) private {
setUint(keccak256(abi.encodePacked("rpl.staked.node.time", _nodeAddress)), _time);
}
/// @notice Calculate and return a node's effective RPL stake amount
/// @param _nodeAddress The address of the node operator to calculate for
function getNodeEffectiveRPLStake(address _nodeAddress) override public view returns (uint256) {
// Load contracts
RocketNetworkPricesInterface rocketNetworkPrices = RocketNetworkPricesInterface(getContractAddress("rocketNetworkPrices"));
RocketDAOProtocolSettingsNodeInterface rocketDAOProtocolSettingsNode = RocketDAOProtocolSettingsNodeInterface(getContractAddress("rocketDAOProtocolSettingsNode"));
// Get node's current RPL stake
uint256 rplStake = getNodeRPLStake(_nodeAddress);
// Retrieve variables for calculations
uint256 matchedETH = getNodeETHMatched(_nodeAddress);
uint256 providedETH = getNodeETHProvided(_nodeAddress);
uint256 rplPrice = rocketNetworkPrices.getRPLPrice();
// RPL stake cannot exceed maximum
uint256 maximumStakePercent = rocketDAOProtocolSettingsNode.getMaximumPerMinipoolStake();
uint256 maximumStake = providedETH * maximumStakePercent / rplPrice;
if (rplStake > maximumStake) {
return maximumStake;
}
// If RPL stake is lower than minimum, node has no effective stake
uint256 minimumStakePercent = rocketDAOProtocolSettingsNode.getMinimumPerMinipoolStake();
uint256 minimumStake = matchedETH * minimumStakePercent / rplPrice;
if (rplStake < minimumStake) {
return 0;
}
// Otherwise, return the actual stake
return rplStake;
}
/// @notice Calculate and return a node's minimum RPL stake to collateralize their minipools
/// @param _nodeAddress The address of the node operator to calculate for
function getNodeMinimumRPLStake(address _nodeAddress) override external view returns (uint256) {
// Load contracts
RocketNetworkPricesInterface rocketNetworkPrices = RocketNetworkPricesInterface(getContractAddress("rocketNetworkPrices"));
RocketDAOProtocolSettingsNodeInterface rocketDAOProtocolSettingsNode = RocketDAOProtocolSettingsNodeInterface(getContractAddress("rocketDAOProtocolSettingsNode"));
// Retrieve variables
uint256 minimumStakePercent = rocketDAOProtocolSettingsNode.getMinimumPerMinipoolStake();
uint256 matchedETH = getNodeETHMatched(_nodeAddress);
return matchedETH * minimumStakePercent / rocketNetworkPrices.getRPLPrice();
}
/// @notice Calculate and return a node's maximum RPL stake to fully collateralise their minipools
/// @param _nodeAddress The address of the node operator to calculate for
function getNodeMaximumRPLStake(address _nodeAddress) override public view returns (uint256) {
// Load contracts
RocketNetworkPricesInterface rocketNetworkPrices = RocketNetworkPricesInterface(getContractAddress("rocketNetworkPrices"));
RocketDAOProtocolSettingsNodeInterface rocketDAOProtocolSettingsNode = RocketDAOProtocolSettingsNodeInterface(getContractAddress("rocketDAOProtocolSettingsNode"));
// Retrieve variables
uint256 maximumStakePercent = rocketDAOProtocolSettingsNode.getMaximumPerMinipoolStake();
uint256 providedETH = getNodeETHProvided(_nodeAddress);
return providedETH * maximumStakePercent / rocketNetworkPrices.getRPLPrice();
}
/// @notice Calculate and return a node's limit of how much user ETH they can use based on RPL stake
/// @param _nodeAddress The address of the node operator to calculate for
function getNodeETHMatchedLimit(address _nodeAddress) override external view returns (uint256) {
// Load contracts
RocketDAOProtocolSettingsNodeInterface rocketDAOProtocolSettingsNode = RocketDAOProtocolSettingsNodeInterface(getContractAddress("rocketDAOProtocolSettingsNode"));
// Retrieve minimum stake parameter
uint256 minimumStakePercent = rocketDAOProtocolSettingsNode.getMinimumPerMinipoolStake();
// When minimum stake is zero, allow unlimited amount of matched ETH
if (minimumStakePercent == 0) {
return type(uint256).max;
}
// Calculate and return limit
RocketNetworkPricesInterface rocketNetworkPrices = RocketNetworkPricesInterface(getContractAddress("rocketNetworkPrices"));
return getNodeRPLStake(_nodeAddress) *rocketNetworkPrices.getRPLPrice() / minimumStakePercent;
}
/// @notice Returns whether this node allows RPL locking or not
/// @param _nodeAddress The address of the node operator to query for
function getRPLLockingAllowed(address _nodeAddress) external view returns (bool) {
return getBool(keccak256(abi.encodePacked("rpl.locking.allowed", _nodeAddress)));
}
/// @notice Accept an RPL stake from the node operator's own address
/// Requires the node's RPL withdrawal address to be unset
/// @param _amount The amount of RPL to stake
function stakeRPL(uint256 _amount) override external {
stakeRPLFor(msg.sender, _amount);
}
/// @notice Accept an RPL stake from any address for a specified node
/// Requires caller to have approved this contract to spend RPL
/// Requires caller to be on the node operator's allow list (see `setStakeForAllowed`)
/// @param _nodeAddress The address of the node operator to stake on behalf of
/// @param _amount The amount of RPL to stake
function stakeRPLFor(address _nodeAddress, uint256 _amount) override public onlyLatestContract("rocketNodeStaking", address(this)) onlyRegisteredNode(_nodeAddress) {
// Must be node's RPL withdrawal address if set or the node's address or an allow listed address or rocketMerkleDistributorMainnet
if (msg.sender != getAddress(keccak256(abi.encodePacked("contract.address", "rocketMerkleDistributorMainnet")))) {
RocketNodeManagerInterface rocketNodeManager = RocketNodeManagerInterface(getContractAddress("rocketNodeManager"));
bool fromNode = false;
if (rocketNodeManager.getNodeRPLWithdrawalAddressIsSet(_nodeAddress)) {
address rplWithdrawalAddress = rocketNodeManager.getNodeRPLWithdrawalAddress(_nodeAddress);
fromNode = msg.sender == rplWithdrawalAddress;
} else {
address withdrawalAddress = rocketStorage.getNodeWithdrawalAddress(_nodeAddress);
fromNode = (msg.sender == _nodeAddress) || (msg.sender == withdrawalAddress);
}
if (!fromNode) {
require(getBool(keccak256(abi.encodePacked("node.stake.for.allowed", _nodeAddress, msg.sender))), "Not allowed to stake for");
}
}
_stakeRPL(_nodeAddress, _amount);
}
/// @notice Sets the allow state for this node to perform functions that require locking RPL
/// @param _nodeAddress The address of the node operator to change the state for
/// @param _allowed Whether locking is allowed or not
function setRPLLockingAllowed(address _nodeAddress, bool _allowed) override external onlyLatestContract("rocketNodeStaking", address(this)) onlyRPLWithdrawalAddressOrNode(_nodeAddress) {
// Set the value
setBool(keccak256(abi.encodePacked("rpl.locking.allowed", _nodeAddress)), _allowed);
// Log it
emit RPLLockingAllowed(_nodeAddress, _allowed, block.timestamp);
}
/// @notice Explicitly allow or remove allowance of an address to be able to stake on behalf of a node
/// @dev The node operator is determined by the address calling this method, it is here for backwards compatibility
/// @param _caller The address you wish to allow
/// @param _allowed Whether the address is allowed or denied
function setStakeRPLForAllowed(address _caller, bool _allowed) override external {
setStakeRPLForAllowed(msg.sender, _caller, _allowed);
}
/// @notice Explicitly allow or remove allowance of an address to be able to stake on behalf of a node
/// @param _nodeAddress The address of the node operator allowing the caller
/// @param _caller The address you wish to allow
/// @param _allowed Whether the address is allowed or denied
function setStakeRPLForAllowed(address _nodeAddress, address _caller, bool _allowed) override public onlyLatestContract("rocketNodeStaking", address(this)) onlyRPLWithdrawalAddressOrNode(_nodeAddress) {
// Set the value
setBool(keccak256(abi.encodePacked("node.stake.for.allowed", _nodeAddress, _caller)), _allowed);
// Log it
emit StakeRPLForAllowed(_nodeAddress, _caller, _allowed, block.timestamp);
}
/// @dev Internal logic for staking RPL
/// @param _nodeAddress The address to increase the RPL stake of
/// @param _amount The amount of RPL to stake
function _stakeRPL(address _nodeAddress, uint256 _amount) internal {
// Ensure voting has been initialised for this node
RocketNetworkVotingInterface rocketNetworkVoting = RocketNetworkVotingInterface(getContractAddress("rocketNetworkVoting"));
rocketNetworkVoting.initialiseVotingFor(_nodeAddress);
// Load contracts
address rplTokenAddress = getContractAddress("rocketTokenRPL");
address rocketVaultAddress = getContractAddress("rocketVault");
IERC20 rplToken = IERC20(rplTokenAddress);
RocketVaultInterface rocketVault = RocketVaultInterface(rocketVaultAddress);
// Transfer RPL tokens
require(rplToken.transferFrom(msg.sender, address(this), _amount), "Could not transfer RPL to staking contract");
// Deposit RPL tokens to vault
require(rplToken.approve(rocketVaultAddress, _amount), "Could not approve vault RPL deposit");
rocketVault.depositToken("rocketNodeStaking", rplToken, _amount);
// Update RPL stake amounts & node RPL staked block
increaseTotalRPLStake(_amount);
increaseNodeRPLStake(_nodeAddress, _amount);
setNodeRPLStakedTime(_nodeAddress, block.timestamp);
// Emit RPL staked event
emit RPLStaked(_nodeAddress, _amount, block.timestamp);
}
/// @notice Returns the amount of RPL that is locked for a given node
/// @param _nodeAddress The address of the node operator to query for
function getNodeRPLLocked(address _nodeAddress) override public view returns (uint256) {
return getUint(keccak256(abi.encodePacked("rpl.locked.node.amount", _nodeAddress)));
}
/// @notice Locks an amount of RPL from being withdrawn even if the node operator is over capitalised
/// @param _nodeAddress The address of the node operator
/// @param _amount The amount of RPL to lock
function lockRPL(address _nodeAddress, uint256 _amount) override external onlyLatestContract("rocketNodeStaking", address(this)) onlyLatestNetworkContract() {
// Check status
require(getBool(keccak256(abi.encodePacked("rpl.locking.allowed", _nodeAddress))), "Node is not allowed to lock RPL");
// The node must have unlocked stake equaling or greater than the amount
uint256 rplStake = getNodeRPLStake(_nodeAddress);
bytes32 lockedStakeKey = keccak256(abi.encodePacked("rpl.locked.node.amount", _nodeAddress));
uint256 lockedStake = getUint(lockedStakeKey);
require(rplStake - lockedStake >= _amount, "Not enough staked RPL");
// Increase locked RPL
setUint(lockedStakeKey, lockedStake + _amount);
// Emit event
emit RPLLocked(_nodeAddress, _amount, block.timestamp);
}
/// @notice Unlocks an amount of RPL making it possible to withdraw if the nod is over capitalised
/// @param _nodeAddress The address of the node operator
/// @param _amount The amount of RPL to unlock
function unlockRPL(address _nodeAddress, uint256 _amount) override external onlyLatestContract("rocketNodeStaking", address(this)) onlyLatestNetworkContract() {
// The node must have locked stake equaling or greater than the amount
bytes32 lockedStakeKey = keccak256(abi.encodePacked("rpl.locked.node.amount", _nodeAddress));
uint256 lockedStake = getUint(lockedStakeKey);
require(_amount <= lockedStake, "Not enough locked RPL");
// Decrease locked RPL
setUint(lockedStakeKey, lockedStake - _amount);
// Emit event
emit RPLUnlocked(_nodeAddress, _amount, block.timestamp);
}
/// @notice Transfers RPL from one node to another
/// @param _from The node to transfer from
/// @param _to The node to transfer to
/// @param _amount The amount of RPL to transfer
function transferRPL(address _from, address _to, uint256 _amount) override external onlyLatestContract("rocketNodeStaking", address(this)) onlyLatestNetworkContract() onlyRegisteredNode(_from) {
// Check sender has enough RPL
require(getNodeRPLStake(_from) >= _amount, "Sender has insufficient RPL");
// Transfer the stake
decreaseNodeRPLStake(_from, _amount);
increaseNodeRPLStake(_to, _amount);
// Emit event
emit RPLTransferred(_from, _to, _amount, block.timestamp);
}
/// @notice Burns an amount of RPL staked by a given node operator
/// @param _from The node to burn from
/// @param _amount The amount of RPL to burn
function burnRPL(address _from, uint256 _amount) override external onlyLatestContract("rocketNodeStaking", address(this)) onlyLatestNetworkContract() onlyRegisteredNode(_from) {
// Check sender has enough RPL
require(getNodeRPLStake(_from) >= _amount, "Node has insufficient RPL");
// Decrease the stake amount
decreaseTotalRPLStake(_amount);
decreaseNodeRPLStake(_from, _amount);
// Withdraw the RPL to this contract
IERC20Burnable rplToken = IERC20Burnable(getContractAddress("rocketTokenRPL"));
RocketVaultInterface rocketVault = RocketVaultInterface(getContractAddress("rocketVault"));
rocketVault.withdrawToken(address(this), rplToken, _amount);
// Execute the token burn
rplToken.burn(_amount);
// Emit event
emit RPLBurned(_from, _amount, block.timestamp);
}
/// @notice Withdraw staked RPL back to the node account or withdraw RPL address
/// Can only be called by a node if they have not set their RPL withdrawal address
/// @param _amount The amount of RPL to withdraw
function withdrawRPL(uint256 _amount) override external {
withdrawRPL(msg.sender, _amount);
}
/// @notice Withdraw staked RPL back to the node account or withdraw RPL address
/// If RPL withdrawal address has been set, must be called from it. Otherwise, must be called from
/// node's primary withdrawal address or their node address.
/// @param _nodeAddress The address of the node withdrawing
/// @param _amount The amount of RPL to withdraw
function withdrawRPL(address _nodeAddress, uint256 _amount) override public onlyLatestContract("rocketNodeStaking", address(this)) {
// Check valid node
require(getBool(keccak256(abi.encodePacked("node.exists", _nodeAddress))), "Invalid node");
// Check address is permitted to withdraw
RocketNodeManagerInterface rocketNodeManager = RocketNodeManagerInterface(getContractAddress("rocketNodeManager"));
address rplWithdrawalAddress = rocketNodeManager.getNodeRPLWithdrawalAddress(_nodeAddress);
if (rocketNodeManager.getNodeRPLWithdrawalAddressIsSet(_nodeAddress)) {
// If RPL withdrawal address is set, must be called from it
require(msg.sender == rplWithdrawalAddress, "Invalid caller");
} else {
// Otherwise, must be called from node address or withdrawal address
address withdrawalAddress = rocketStorage.getNodeWithdrawalAddress(_nodeAddress);
require(msg.sender == _nodeAddress || msg.sender == withdrawalAddress, "Invalid caller");
}
// Load contracts
RocketDAOProtocolSettingsRewardsInterface rocketDAOProtocolSettingsRewards = RocketDAOProtocolSettingsRewardsInterface(getContractAddress("rocketDAOProtocolSettingsRewards"));
RocketVaultInterface rocketVault = RocketVaultInterface(getContractAddress("rocketVault"));
// Check cooldown period (one claim period) has passed since RPL last staked
require(block.timestamp - getNodeRPLStakedTime(_nodeAddress) >= rocketDAOProtocolSettingsRewards.getRewardsClaimIntervalTime(), "The withdrawal cooldown period has not passed");
// Get & check node's current RPL stake
uint256 rplStake = getNodeRPLStake(_nodeAddress);
uint256 lockedStake = getNodeRPLLocked(_nodeAddress);
require(rplStake - lockedStake >= _amount, "Withdrawal amount exceeds node's staked RPL balance");
// Check withdrawal would not under collateralise node
require(rplStake - _amount >= getNodeMaximumRPLStake(_nodeAddress) + lockedStake, "Node's staked RPL balance after withdrawal is less than required balance");
// Update RPL stake amounts
decreaseTotalRPLStake(_amount);
decreaseNodeRPLStake(_nodeAddress, _amount);
// Transfer RPL tokens to node's RPL withdrawal address (if unset, defaults to primary withdrawal address)
rocketVault.withdrawToken(rplWithdrawalAddress, IERC20(getContractAddress("rocketTokenRPL")), _amount);
// Emit RPL withdrawn event
emit RPLWithdrawn(_nodeAddress, _amount, block.timestamp);
}
/// @notice Slash a node's RPL by an ETH amount
/// Only accepts calls from registered minipools
/// @param _nodeAddress The address to slash RPL from
/// @param _ethSlashAmount The amount of RPL to slash denominated in ETH value
function slashRPL(address _nodeAddress, uint256 _ethSlashAmount) override external onlyLatestContract("rocketNodeStaking", address(this)) onlyRegisteredMinipool(msg.sender) {
// Load contracts
RocketNetworkPricesInterface rocketNetworkPrices = RocketNetworkPricesInterface(getContractAddress("rocketNetworkPrices"));
RocketVaultInterface rocketVault = RocketVaultInterface(getContractAddress("rocketVault"));
// Calculate RPL amount to slash
uint256 rplSlashAmount = calcBase * _ethSlashAmount / rocketNetworkPrices.getRPLPrice();
// Cap slashed amount to node's RPL stake
uint256 rplStake = getNodeRPLStake(_nodeAddress);
if (rplSlashAmount > rplStake) { rplSlashAmount = rplStake; }
// Transfer slashed amount to auction contract
if(rplSlashAmount > 0) rocketVault.transferToken("rocketAuctionManager", IERC20(getContractAddress("rocketTokenRPL")), rplSlashAmount);
// Update RPL stake amounts
decreaseTotalRPLStake(rplSlashAmount);
decreaseNodeRPLStake(_nodeAddress, rplSlashAmount);
// Mark minipool as slashed
setBool(keccak256(abi.encodePacked("minipool.rpl.slashed", msg.sender)), true);
// Emit RPL slashed event
emit RPLSlashed(_nodeAddress, rplSlashAmount, _ethSlashAmount, block.timestamp);
}
}
RocketStorageInterface.sol 79 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
interface RocketStorageInterface {
// Deploy status
function getDeployedStatus() external view returns (bool);
// Guardian
function getGuardian() external view returns(address);
function setGuardian(address _newAddress) external;
function confirmGuardian() external;
// Getters
function getAddress(bytes32 _key) external view returns (address);
function getUint(bytes32 _key) external view returns (uint);
function getString(bytes32 _key) external view returns (string memory);
function getBytes(bytes32 _key) external view returns (bytes memory);
function getBool(bytes32 _key) external view returns (bool);
function getInt(bytes32 _key) external view returns (int);
function getBytes32(bytes32 _key) external view returns (bytes32);
// Setters
function setAddress(bytes32 _key, address _value) external;
function setUint(bytes32 _key, uint _value) external;
function setString(bytes32 _key, string calldata _value) external;
function setBytes(bytes32 _key, bytes calldata _value) external;
function setBool(bytes32 _key, bool _value) external;
function setInt(bytes32 _key, int _value) external;
function setBytes32(bytes32 _key, bytes32 _value) external;
// Deleters
function deleteAddress(bytes32 _key) external;
function deleteUint(bytes32 _key) external;
function deleteString(bytes32 _key) external;
function deleteBytes(bytes32 _key) external;
function deleteBool(bytes32 _key) external;
function deleteInt(bytes32 _key) external;
function deleteBytes32(bytes32 _key) external;
// Arithmetic
function addUint(bytes32 _key, uint256 _amount) external;
function subUint(bytes32 _key, uint256 _amount) external;
// Protected storage
function getNodeWithdrawalAddress(address _nodeAddress) external view returns (address);
function getNodePendingWithdrawalAddress(address _nodeAddress) external view returns (address);
function setWithdrawalAddress(address _nodeAddress, address _newWithdrawalAddress, bool _confirm) external;
function confirmWithdrawalAddress(address _nodeAddress) external;
}
RocketNetworkSnapshots.sol 184 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: MIT
// Copyright (c) 2016-2023 zOS Global Limited and contributors
// Adapted from OpenZeppelin `Checkpoints` contract
pragma solidity 0.8.18;
import "@openzeppelin4/contracts/utils/math/Math.sol";
import "../RocketBase.sol";
import "../../interface/network/RocketNetworkSnapshotsInterface.sol";
/// @notice Accounting for snapshotting of values based on block numbers
contract RocketNetworkSnapshots is RocketBase, RocketNetworkSnapshotsInterface {
constructor(RocketStorageInterface _rocketStorageAddress) RocketBase(_rocketStorageAddress) {
// Set contract version
version = 1;
// Setup for if this contract is being deployed as part of a new instance deployment
if (!rocketStorage.getDeployedStatus()) {
_insert(keccak256("network.prices.rpl"), 0.01 ether);
_insert(keccak256("node.voting.power.stake.maximum"), 1.5 ether);
}
}
function push(bytes32 _key, uint224 _value) onlyLatestContract("rocketNetworkSnapshots", address(this)) onlyLatestNetworkContract external {
_insert(_key, _value);
}
function length(bytes32 _key) public view returns (uint256) {
return rocketStorage.getUint(keccak256(abi.encodePacked("snapshot.length", _key)));
}
function latest(bytes32 _key) external view returns (bool, uint32, uint224) {
uint256 len = length(_key);
if (len == 0) {
return (false, 0, 0);
}
Checkpoint224 memory checkpoint = _load(_key, len - 1);
return (true, checkpoint._block, checkpoint._value);
}
function latestBlock(bytes32 _key) external view returns (uint32) {
uint256 len = length(_key);
return len == 0 ? 0 : _blockAt(_key, len - 1);
}
function latestValue(bytes32 _key) external view returns (uint224) {
uint256 len = length(_key);
return len == 0 ? 0 : _valueAt(_key, len - 1);
}
function lookup(bytes32 _key, uint32 _block) external view returns (uint224) {
uint256 len = length(_key);
uint256 pos = _binaryLookup(_key, _block, 0, len);
return pos == 0 ? 0 : _valueAt(_key, pos - 1);
}
function lookupRecent(bytes32 _key, uint32 _block, uint256 _recency) external view returns (uint224) {
uint256 len = length(_key);
uint256 low = 0;
uint256 high = len;
if (len > 5 && len > _recency) {
uint256 mid = len - _recency;
if (_block < _blockAt(_key, mid)) {
high = mid;
} else {
low = mid + 1;
}
}
uint256 pos = _binaryLookup(_key, _block, low, high);
return pos == 0 ? 0 : _valueAt(_key, pos - 1);
}
function _insert(bytes32 _key, uint224 _value) private {
uint32 blockNumber = uint32(block.number);
uint256 pos = length(_key);
if (pos > 0) {
Checkpoint224 memory last = _load(_key, pos - 1);
// Checkpoint keys must be non-decreasing.
require (last._block <= blockNumber, "Unordered snapshot insertion");
// Update or push new checkpoint
if (last._block == blockNumber) {
last._value = _value;
_set(_key, pos - 1, last);
} else {
_push(_key, Checkpoint224({_block: blockNumber, _value: _value}));
}
} else {
_push(_key, Checkpoint224({_block: blockNumber, _value: _value}));
}
}
function _binaryLookup(
bytes32 _key,
uint32 _block,
uint256 _low,
uint256 _high
) private view returns (uint256) {
while (_low < _high) {
uint256 mid = Math.average(_low, _high);
if (_blockAt(_key, mid) > _block) {
_high = mid;
} else {
_low = mid + 1;
}
}
return _high;
}
function _load(bytes32 _key, uint256 _pos) private view returns (Checkpoint224 memory) {
bytes32 key = bytes32(uint256(_key) + _pos);
bytes32 raw = rocketStorage.getBytes32(key);
Checkpoint224 memory result;
result._block = uint32(uint256(raw) >> 224);
result._value = uint224(uint256(raw));
return result;
}
function _blockAt(bytes32 _key, uint256 _pos) private view returns (uint32) {
bytes32 key = bytes32(uint256(_key) + _pos);
bytes32 raw = rocketStorage.getBytes32(key);
return uint32(uint256(raw) >> 224);
}
function _valueAt(bytes32 _key, uint256 _pos) private view returns (uint224) {
bytes32 key = bytes32(uint256(_key) + _pos);
bytes32 raw = rocketStorage.getBytes32(key);
return uint224(uint256(raw));
}
function _push(bytes32 _key, Checkpoint224 memory _item) private {
bytes32 lengthKey = keccak256(abi.encodePacked("snapshot.length", _key));
uint256 snapshotLength = rocketStorage.getUint(lengthKey);
bytes32 key = bytes32(uint256(_key) + snapshotLength);
rocketStorage.setUint(lengthKey, snapshotLength + 1);
rocketStorage.setBytes32(key, _encode(_item));
}
function _set(bytes32 _key, uint256 _pos, Checkpoint224 memory _item) private {
bytes32 key = bytes32(uint256(_key) + _pos);
rocketStorage.setBytes32(key, _encode(_item));
}
function _encode(Checkpoint224 memory _item) private pure returns (bytes32) {
return bytes32(
uint256(_item._block) << 224 | uint256(_item._value)
);
}
}
RocketNodeManagerInterface.sol 70 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
pragma abicoder v2;
import "../../types/NodeDetails.sol";
interface RocketNodeManagerInterface {
// Structs
struct TimezoneCount {
string timezone;
uint256 count;
}
function getNodeCount() external view returns (uint256);
function getNodeCountPerTimezone(uint256 offset, uint256 limit) external view returns (TimezoneCount[] memory);
function getNodeAt(uint256 _index) external view returns (address);
function getNodeExists(address _nodeAddress) external view returns (bool);
function getNodeWithdrawalAddress(address _nodeAddress) external view returns (address);
function getNodePendingWithdrawalAddress(address _nodeAddress) external view returns (address);
function getNodeRPLWithdrawalAddress(address _nodeAddress) external view returns (address);
function getNodeRPLWithdrawalAddressIsSet(address _nodeAddress) external view returns (bool);
function unsetRPLWithdrawalAddress(address _nodeAddress) external;
function setRPLWithdrawalAddress(address _nodeAddress, address _newRPLWithdrawalAddress, bool _confirm) external;
function confirmRPLWithdrawalAddress(address _nodeAddress) external;
function getNodePendingRPLWithdrawalAddress(address _nodeAddress) external view returns (address);
function getNodeTimezoneLocation(address _nodeAddress) external view returns (string memory);
function registerNode(string calldata _timezoneLocation) external;
function getNodeRegistrationTime(address _nodeAddress) external view returns (uint256);
function setTimezoneLocation(string calldata _timezoneLocation) external;
function setRewardNetwork(address _nodeAddress, uint256 network) external;
function getRewardNetwork(address _nodeAddress) external view returns (uint256);
function getFeeDistributorInitialised(address _nodeAddress) external view returns (bool);
function initialiseFeeDistributor() external;
function getAverageNodeFee(address _nodeAddress) external view returns (uint256);
function setSmoothingPoolRegistrationState(bool _state) external;
function getSmoothingPoolRegistrationState(address _nodeAddress) external returns (bool);
function getSmoothingPoolRegistrationChanged(address _nodeAddress) external returns (uint256);
function getSmoothingPoolRegisteredNodeCount(uint256 _offset, uint256 _limit) external view returns (uint256);
function getNodeDetails(address _nodeAddress) external view returns (NodeDetails memory);
function getNodeAddresses(uint256 _offset, uint256 _limit) external view returns (address[] memory);
}
RocketNodeStakingInterface.sol 57 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
interface RocketNodeStakingInterface {
function getTotalRPLStake() external view returns (uint256);
function getNodeRPLStake(address _nodeAddress) external view returns (uint256);
function getNodeETHMatched(address _nodeAddress) external view returns (uint256);
function getNodeETHProvided(address _nodeAddress) external view returns (uint256);
function getNodeETHCollateralisationRatio(address _nodeAddress) external view returns (uint256);
function getNodeRPLStakedTime(address _nodeAddress) external view returns (uint256);
function getNodeEffectiveRPLStake(address _nodeAddress) external view returns (uint256);
function getNodeMinimumRPLStake(address _nodeAddress) external view returns (uint256);
function getNodeMaximumRPLStake(address _nodeAddress) external view returns (uint256);
function getNodeETHMatchedLimit(address _nodeAddress) external view returns (uint256);
function getRPLLockingAllowed(address _nodeAddress) external view returns (bool);
function stakeRPL(uint256 _amount) external;
function stakeRPLFor(address _nodeAddress, uint256 _amount) external;
function setRPLLockingAllowed(address _nodeAddress, bool _allowed) external;
function setStakeRPLForAllowed(address _caller, bool _allowed) external;
function setStakeRPLForAllowed(address _nodeAddress, address _caller, bool _allowed) external;
function getNodeRPLLocked(address _nodeAddress) external view returns (uint256);
function lockRPL(address _nodeAddress, uint256 _amount) external;
function unlockRPL(address _nodeAddress, uint256 _amount) external;
function transferRPL(address _from, address _to, uint256 _amount) external;
function burnRPL(address _from, uint256 _amount) external;
function withdrawRPL(uint256 _amount) external;
function withdrawRPL(address _nodeAddress, uint256 _amount) external;
function slashRPL(address _nodeAddress, uint256 _ethSlashAmount) external;
}
AddressSetStorageInterface.sol 39 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
interface AddressSetStorageInterface {
function getCount(bytes32 _key) external view returns (uint);
function getItem(bytes32 _key, uint _index) external view returns (address);
function getIndexOf(bytes32 _key, address _value) external view returns (int);
function addItem(bytes32 _key, address _value) external;
function removeItem(bytes32 _key, address _value) external;
}
RocketMinipoolInterface.sol 80 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
import "../../types/MinipoolDeposit.sol";
import "../../types/MinipoolStatus.sol";
import "../RocketStorageInterface.sol";
interface RocketMinipoolInterface {
function version() external view returns (uint8);
function initialise(address _nodeAddress) external;
function getStatus() external view returns (MinipoolStatus);
function getFinalised() external view returns (bool);
function getStatusBlock() external view returns (uint256);
function getStatusTime() external view returns (uint256);
function getScrubVoted(address _member) external view returns (bool);
function getDepositType() external view returns (MinipoolDeposit);
function getNodeAddress() external view returns (address);
function getNodeFee() external view returns (uint256);
function getNodeDepositBalance() external view returns (uint256);
function getNodeRefundBalance() external view returns (uint256);
function getNodeDepositAssigned() external view returns (bool);
function getPreLaunchValue() external view returns (uint256);
function getNodeTopUpValue() external view returns (uint256);
function getVacant() external view returns (bool);
function getPreMigrationBalance() external view returns (uint256);
function getUserDistributed() external view returns (bool);
function getUserDepositBalance() external view returns (uint256);
function getUserDepositAssigned() external view returns (bool);
function getUserDepositAssignedTime() external view returns (uint256);
function getTotalScrubVotes() external view returns (uint256);
function calculateNodeShare(uint256 _balance) external view returns (uint256);
function calculateUserShare(uint256 _balance) external view returns (uint256);
function preDeposit(uint256 _bondingValue, bytes calldata _validatorPubkey, bytes calldata _validatorSignature, bytes32 _depositDataRoot) external payable;
function deposit() external payable;
function userDeposit() external payable;
function distributeBalance(bool _rewardsOnly) external;
function beginUserDistribute() external;
function userDistributeAllowed() external view returns (bool);
function refund() external;
function slash() external;
function finalise() external;
function canStake() external view returns (bool);
function canPromote() external view returns (bool);
function stake(bytes calldata _validatorSignature, bytes32 _depositDataRoot) external;
function prepareVacancy(uint256 _bondAmount, uint256 _currentBalance) external;
function promote() external;
function dissolve() external;
function close() external;
function voteScrub() external;
function reduceBondAmount() external;
}
RocketNetworkPricesInterface.sol 37 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
interface RocketNetworkPricesInterface {
function getPricesBlock() external view returns (uint256);
function getRPLPrice() external view returns (uint256);
function submitPrices(uint256 _block, uint256 _slotTimestamp, uint256 _rplPrice) external;
function executeUpdatePrices(uint256 _block, uint256 _slotTimestamp, uint256 _rplPrice) external;
}
RocketNetworkVotingInterface.sol 42 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
interface RocketNetworkVotingInterface {
function initialiseVotingFor(address _nodeAddress) external;
function initialiseVoting() external;
function initialiseVotingWithDelegate(address _delegate) external;
function getVotingInitialised(address _nodeAddress) external view returns (bool);
function getNodeCount(uint32 _block) external view returns (uint256);
function getVotingPower(address _nodeAddress, uint32 _block) external view returns (uint256);
function setDelegate(address _newDelegate) external;
function getDelegate(address _nodeAddress, uint32 _block) external view returns (address);
function getCurrentDelegate(address _nodeAddress) external view returns (address);
}
RocketMinipoolManagerInterface.sol 73 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
pragma abicoder v2;
// SPDX-License-Identifier: GPL-3.0-only
import "../../types/MinipoolDeposit.sol";
import "../../types/MinipoolDetails.sol";
import "./RocketMinipoolInterface.sol";
interface RocketMinipoolManagerInterface {
function getMinipoolCount() external view returns (uint256);
function getStakingMinipoolCount() external view returns (uint256);
function getFinalisedMinipoolCount() external view returns (uint256);
function getActiveMinipoolCount() external view returns (uint256);
function getMinipoolRPLSlashed(address _minipoolAddress) external view returns (bool);
function getMinipoolCountPerStatus(uint256 offset, uint256 limit) external view returns (uint256, uint256, uint256, uint256, uint256);
function getPrelaunchMinipools(uint256 offset, uint256 limit) external view returns (address[] memory);
function getMinipoolAt(uint256 _index) external view returns (address);
function getNodeMinipoolCount(address _nodeAddress) external view returns (uint256);
function getNodeActiveMinipoolCount(address _nodeAddress) external view returns (uint256);
function getNodeFinalisedMinipoolCount(address _nodeAddress) external view returns (uint256);
function getNodeStakingMinipoolCount(address _nodeAddress) external view returns (uint256);
function getNodeStakingMinipoolCountBySize(address _nodeAddress, uint256 _depositSize) external view returns (uint256);
function getNodeMinipoolAt(address _nodeAddress, uint256 _index) external view returns (address);
function getNodeValidatingMinipoolCount(address _nodeAddress) external view returns (uint256);
function getNodeValidatingMinipoolAt(address _nodeAddress, uint256 _index) external view returns (address);
function getMinipoolByPubkey(bytes calldata _pubkey) external view returns (address);
function getMinipoolExists(address _minipoolAddress) external view returns (bool);
function getMinipoolDestroyed(address _minipoolAddress) external view returns (bool);
function getMinipoolPubkey(address _minipoolAddress) external view returns (bytes memory);
function updateNodeStakingMinipoolCount(uint256 _previousBond, uint256 _newBond, uint256 _previousFee, uint256 _newFee) external;
function getMinipoolWithdrawalCredentials(address _minipoolAddress) external pure returns (bytes memory);
function createMinipool(address _nodeAddress, uint256 _salt) external returns (RocketMinipoolInterface);
function createVacantMinipool(address _nodeAddress, uint256 _salt, bytes calldata _validatorPubkey, uint256 _bondAmount, uint256 _currentBalance) external returns (RocketMinipoolInterface);
function removeVacantMinipool() external;
function getVacantMinipoolCount() external view returns (uint256);
function getVacantMinipoolAt(uint256 _index) external view returns (address);
function destroyMinipool() external;
function incrementNodeStakingMinipoolCount(address _nodeAddress) external;
function decrementNodeStakingMinipoolCount(address _nodeAddress) external;
function tryDistribute(address _nodeAddress) external;
function incrementNodeFinalisedMinipoolCount(address _nodeAddress) external;
function setMinipoolPubkey(bytes calldata _pubkey) external;
function getMinipoolDepositType(address _minipoolAddress) external view returns (MinipoolDeposit);
}
RocketNetworkSnapshotsInterface.sol 46 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
struct Checkpoint224 {
uint32 _block;
uint224 _value;
}
/// @notice Accounting for snapshotting of values based on block numbers
interface RocketNetworkSnapshotsInterface {
function push(bytes32 _key, uint224 _value) external;
function length(bytes32 _key) external view returns (uint256);
function latest(bytes32 _key) external view returns (bool, uint32, uint224);
function latestBlock(bytes32 _key) external view returns (uint32);
function latestValue(bytes32 _key) external view returns (uint224);
function lookup(bytes32 _key, uint32 _block) external view returns (uint224);
function lookupRecent(bytes32 _key, uint32 _block, uint256 _recency) external view returns (uint224);
}
RocketDAOProtocolSettingsNodeInterface.sol 41 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
interface RocketDAOProtocolSettingsNodeInterface {
function getRegistrationEnabled() external view returns (bool);
function getSmoothingPoolRegistrationEnabled() external view returns (bool);
function getDepositEnabled() external view returns (bool);
function getVacantMinipoolsEnabled() external view returns (bool);
function getMinimumPerMinipoolStake() external view returns (uint256);
function getMaximumPerMinipoolStake() external view returns (uint256);
function getMaximumStakeForVotingPower() external view returns (uint256);
}
RocketDAOProtocolSettingsRewardsInterface.sol 42 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
interface RocketDAOProtocolSettingsRewardsInterface {
function setSettingRewardsClaimers(uint256 _trustedNodePercent, uint256 _protocolPercent, uint256 _nodePercent) external;
function getRewardsClaimerPerc(string memory _contractName) external view returns (uint256);
function getRewardsClaimersPerc() external view returns (uint256 _trustedNodePercent, uint256 _protocolPercent, uint256 _nodePercent);
function getRewardsClaimersTrustedNodePerc() external view returns (uint256);
function getRewardsClaimersProtocolPerc() external view returns (uint256);
function getRewardsClaimersNodePerc() external view returns (uint256);
function getRewardsClaimersTimeUpdated() external view returns (uint256);
function getRewardsClaimIntervalPeriods() external view returns (uint256);
function getRewardsClaimIntervalTime() external view returns (uint256);
}
RocketDAOProtocolSettingsMinipoolInterface.sol 50 lines
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
import "../../../../types/MinipoolDeposit.sol";
interface RocketDAOProtocolSettingsMinipoolInterface {
function getLaunchBalance() external view returns (uint256);
function getPreLaunchValue() external pure returns (uint256);
function getDepositUserAmount(MinipoolDeposit _depositType) external view returns (uint256);
function getFullDepositUserAmount() external view returns (uint256);
function getHalfDepositUserAmount() external view returns (uint256);
function getVariableDepositAmount() external view returns (uint256);
function getSubmitWithdrawableEnabled() external view returns (bool);
function getBondReductionEnabled() external view returns (bool);
function getLaunchTimeout() external view returns (uint256);
function getMaximumCount() external view returns (uint256);
function isWithinUserDistributeWindow(uint256 _time) external view returns (bool);
function hasUserDistributeWindowPassed(uint256 _time) external view returns (bool);
function getUserDistributeWindowStart() external view returns (uint256);
function getUserDistributeWindowLength() external view returns (uint256);
}
Read Contract
getNodeETHCollateralisationRatio 0x97be2143 → uint256
getNodeETHMatched 0xa493e6a2 → uint256
getNodeETHMatchedLimit 0x48aeedf5 → uint256
getNodeETHProvided 0xe5e82b7c → uint256
getNodeEffectiveRPLStake 0xf0d19b89 → uint256
getNodeMaximumRPLStake 0x4e58ff6e → uint256
getNodeMinimumRPLStake 0x03fa87b4 → uint256
getNodeRPLLocked 0xf3512f84 → uint256
getNodeRPLStake 0x9961cee4 → uint256
getNodeRPLStakedTime 0xc0d05dd8 → uint256
getRPLLockingAllowed 0x641a24d2 → bool
getTotalRPLStake 0x9a206c8e → uint256
version 0x54fd4d50 → uint8
Write Contract 12 functions
These functions modify contract state and require a wallet transaction to execute.
burnRPL 0xa39e96c3
address _from
uint256 _amount
lockRPL 0xc601bf78
address _nodeAddress
uint256 _amount
setRPLLockingAllowed 0x194c63d8
address _nodeAddress
bool _allowed
setStakeRPLForAllowed 0x088903a4
address _caller
bool _allowed
setStakeRPLForAllowed 0x3d65c1fa
address _nodeAddress
address _caller
bool _allowed
slashRPL 0x245395a6
address _nodeAddress
uint256 _ethSlashAmount
stakeRPL 0x3e200d4b
uint256 _amount
stakeRPLFor 0xcb1c8321
address _nodeAddress
uint256 _amount
transferRPL 0x10b63749
address _from
address _to
uint256 _amount
unlockRPL 0x2c177a53
address _nodeAddress
uint256 _amount
withdrawRPL 0x21f3da44
address _nodeAddress
uint256 _amount
withdrawRPL 0x6b088d5c
uint256 _amount
Recent Transactions
No transactions found for this address