Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x2D627A50Dc1C4EDa73E42858E8460b0eCF300b25
Balance 0 ETH
Nonce 1
Code Size 18981 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

18981 bytes
0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806375fc2c131161010f5780639de1c862116100a2578063e14bd87411610071578063e14bd87414610447578063e641455e1461047f578063eb86e7c014610492578063fe0d94c1146104a557600080fd5b80639de1c862146103fb5780639eb075751461040e578063aeb9be7e14610421578063b5171d191461043457600080fd5b806386f79edb116100de57806386f79edb146103af57806392d4d1de146103c25780639cb2b69b146103d55780639d118770146103e857600080fd5b806375fc2c1314610381578063775a25e3146103945780637960ee021461021e57806380a6cdd41461039c57600080fd5b806344c9af28116101875780635bc22d1b116101565780635bc22d1b146103355780636b75dbde14610348578063716c3f321461035b57806374f6c6501461036e57600080fd5b806344c9af28146102d057806344ff2d99146102f057806354fd4d501461030357806358590de31461032257600080fd5b806321947507116101c3578063219475071461027457806323d44f0d146102975780632cb9186f146102aa5780633dca885d146102bd57600080fd5b8063021eca58146101f55780631709e0e61461021e5780631c15da271461023f5780631d2db6c814610254575b600080fd5b610208610203366004613b42565b6104b8565b6040516102159190613bb5565b60405180910390f35b61023161022c366004613bc3565b61053c565b604051908152602001610215565b61025261024d366004613bf0565b610589565b005b610267610262366004613bc3565b610a70565b6040516102159190613c8a565b610287610282366004613bc3565b610ad8565b6040519015158152602001610215565b6102876102a5366004613b42565b610b25565b6102316102b8366004613bc3565b610b4c565b6102316102cb366004613bc3565b610b99565b6102e36102de366004613bc3565b610be6565b6040516102159190613c9d565b6102876102fe366004613bc3565b610d96565b6000546103109060ff1681565b60405160ff9091168152602001610215565b610287610330366004613b42565b610de3565b610231610343366004613bc3565b610e32565b610252610356366004613bc3565b610e7f565b610231610369366004613bc3565b611172565b61023161037c366004613bc3565b6111bf565b61023161038f366004613e1d565b61120c565b610231611545565b6102316103aa366004613bc3565b611595565b6102676103bd366004613bc3565b6115e2565b6102316103d0366004613bc3565b61164a565b6102316103e3366004613bc3565b611697565b6102526103f6366004613bc3565b6116e4565b610287610409366004613bc3565b611973565b61023161041c366004613bc3565b611997565b61023161042f366004613bc3565b6119e4565b610252610442366004613f0b565b611a31565b61045a610455366004613bc3565b611db8565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610215565b61028761048d366004613bc3565b611e05565b6102316104a0366004613bc3565b611e52565b6102526104b3366004613bc3565b611e9f565b60006105226040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250848460405160200161050793929190613f6a565b604051602081830303815290604052805190602001206121a3565b600481111561053357610533613b72565b90505b92915050565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e0000000000000000000081525083604051602001610507929190613fdd565b3361060a816040516020016105ef91907f6e6f64652e657869737473000000000000000000000000000000000000000000815260609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016600b820152601f0190565b6040516020818303038152906040528051906020012061223b565b61065b5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6040518060400160405280601981526020017f726f636b657444414f50726f746f636f6c50726f706f73616c00000000000000815250306106c1826040516020016106a69190614026565b604051602081830303815290604052805190602001206122d3565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461073b5760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e7472616374000000006044820152606401610652565b600084600481111561074f5761074f613b72565b0361079c5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c696420766f746500000000000000000000000000000000000000006044820152606401610652565b60026107a786610be6565b60098111156107b8576107b8613b72565b146108055760405162461bcd60e51b815260206004820152601c60248201527f5068617365203220766f74696e67206973206e6f7420616374697665000000006044820152606401610652565b60006108456040518060400160405280601381526020017f726f636b65744e6574776f726b566f74696e670000000000000000000000000081525061236b565b90506000610852876111bf565b6040517f87f78dc600000000000000000000000000000000000000000000000000000000815233600482015263ffffffff8216602482015290915060009073ffffffffffffffffffffffffffffffffffffffff8416906387f78dc690604401602060405180830381865afa1580156108ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f2919061406b565b6040517f28c70de000000000000000000000000000000000000000000000000000000000815233600482015263ffffffff8416602482015290915060009073ffffffffffffffffffffffffffffffffffffffff8516906328c70de090604401602060405180830381865afa15801561096e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109929190614084565b905061099e8982610de3565b15610a575760006109af8a836104b8565b90508860048111156109c3576109c3613b72565b8160048111156109d5576109d5613b72565b03610a485760405162461bcd60e51b815260206004820152602660248201527f566f746520646972656374696f6e206973207468652073616d6520617320646560448201527f6c656761746500000000000000000000000000000000000000000000000000006064820152608401610652565b610a5582338c86856123e7565b505b610a6533838b8b6000612694565b505050505050505050565b60606105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e0000000000000000000081525083604051602001610abd9291906140a8565b60405160208183030381529060405280519060200120612a7a565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250836040516020016105ef9291906140f1565b600080610b3284846104b8565b6004811115610b4357610b43613b72565b14159392505050565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e000000000000000000008152508360405160200161050792919061413a565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e0000000000000000000081525083604051602001610507929190614183565b600081610bf1611545565b10158015610bff5750600082115b610c4b5760405162461bcd60e51b815260206004820152601360248201527f496e76616c69642070726f706f73616c204944000000000000000000000000006044820152606401610652565b610c5482610d96565b15610c6157506003919050565b610c6a82610ad8565b15610c7757506009919050565b6000610c8283610e32565b905080421015610c955750600092915050565b6000610ca08461164a565b90506000610cad856119e4565b905081421015610cc257506001949350505050565b80421015610cd557506002949350505050565b610cde85611973565b15610cee57506004949350505050565b6000610cf986611595565b90506000610d0687610b4c565b90506000610d1388611172565b9050600081610d2284866141fb565b610d2c91906141fb565b9050610d3789611997565b8110610d785782841115610d6957610d4e89610b99565b421015610d645750600798975050505050505050565b610d87565b50600698975050505050505050565b50600598975050505050505050565b50505050505050506008919050565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250836040516020016105ef92919061420e565b60006105336040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e0000000000000000000081525084846040516020016105ef93929190614257565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250836040516020016105079291906142ca565b6040518060400160405280601981526020017f726f636b657444414f50726f746f636f6c50726f706f73616c0000000000000081525030610eca826040516020016106a69190614026565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f445760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e7472616374000000006044820152606401610652565b6004610f4f84610be6565b6009811115610f6057610f60613b72565b14610fad5760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c20686173206e6f74206265656e207665746f6564000000006044820152606401610652565b60006040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e0000000000000000000081525084604051602001610ff7929190614313565b6040516020818303038152906040528051906020012090506110188161223b565b156110655760405162461bcd60e51b815260206004820152601a60248201527f50726f706f73616c20616c72656164792066696e616c697365640000000000006044820152606401610652565b611070816001612b36565b60006110b06040518060400160405280601981526020017f726f636b657444414f50726f746f636f6c56657269666965720000000000000081525061236b565b6040517ff11495280000000000000000000000000000000000000000000000000000000081526004810187905290915073ffffffffffffffffffffffffffffffffffffffff82169063f114952890602401600060405180830381600087803b15801561111b57600080fd5b505af115801561112f573d6000803e3d6000fd5b50506040514281523292508791507f1717e02099dcccdc2e610702ac3584df93eb111ddc89dc9fd33f14917f47729d906020015b60405180910390a35050505050565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e000000000000000000008152508360405160200161050792919061435c565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250836040516020016105079291906143a5565b600033611274816040516020016105ef91907f6e6f64652e657869737473000000000000000000000000000000000000000000815260609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016600b820152601f0190565b6112c05760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f646500000000000000000000000000000000000000006044820152606401610652565b6040518060400160405280601981526020017f726f636b657444414f50726f746f636f6c50726f706f73616c000000000000008152503061130b826040516020016106a69190614026565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113855760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e7472616374000000006044820152606401610652565b60006113bd604051602001610507907f70726f746f636f6c2e64616f2e656e61626c65642e626c6f636b0000000000008152601a0190565b905080158015906113d45750808863ffffffff1610155b6114205760405162461bcd60e51b815260206004820152601860248201527f44414f20686173206e6f74206265656e20656e61626c656400000000000000006044820152606401610652565b50600085815b8181101561146557888882818110611440576114406143ee565b61145392604090910201359050846141fb565b925061145e8161441d565b9050611426565b50600061147b8d8b63ffffffff16858f8f612bcb565b905060006114bd6040518060400160405280601981526020017f726f636b657444414f50726f746f636f6c56657269666965720000000000000081525061236b565b90508073ffffffffffffffffffffffffffffffffffffffff16635817abc583338e8e8e6040518663ffffffff1660e01b8152600401611500959493929190614496565b600060405180830381600087803b15801561151a57600080fd5b505af115801561152e573d6000803e3d6000fd5b509399505050505050505050509695505050505050565b60006115906040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e0000000000000000000081525060405160200161050791906144e3565b905090565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e0000000000000000000081525083604051602001610507929190614524565b60606105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e000000000000000000008152508360405160200161162f92919061456d565b60405160208183030381529060405280519060200120613013565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250836040516020016105079291906145b6565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250836040516020016105079291906145ff565b6040518060400160405280601981526020017f726f636b657444414f50726f746f636f6c50726f706f73616c000000000000008152503061172f826040516020016106a69190614026565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146117a95760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e7472616374000000006044820152606401610652565b6040518060400160405280601981526020017f726f636b657444414f50726f746f636f6c566572696669657200000000000000815250336117f4826040516020016106a69190614026565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461186e5760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e7472616374000000006044820152606401610652565b60006040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250866040516020016118b892919061420e565b6040516020818303038152906040528051906020012090506118d98161223b565b156119265760405162461bcd60e51b815260206004820152601a60248201527f50726f706f73616c20616c72656164792064657374726f7965640000000000006044820152606401610652565b611931816001612b36565b857fa970ae7ff27e20f6f76ea5b9b0f0e37d4d6b2a85510f3f8dd5032c7ce26fdf104260405161196391815260200190565b60405180910390a2505050505050565b60008061197f83611e52565b9050600061198c8461053c565b909110159392505050565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e0000000000000000000081525083604051602001610507929190614648565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e0000000000000000000081525083604051602001610507929190614691565b33611a97816040516020016105ef91907f6e6f64652e657869737473000000000000000000000000000000000000000000815260609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016600b820152601f0190565b611ae35760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f646500000000000000000000000000000000000000006044820152606401610652565b6040518060400160405280601981526020017f726f636b657444414f50726f746f636f6c50726f706f73616c0000000000000081525030611b2e826040516020016106a69190614026565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611ba85760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e7472616374000000006044820152606401610652565b6000886004811115611bbc57611bbc613b72565b03611c095760405162461bcd60e51b815260206004820152600c60248201527f496e76616c696420766f746500000000000000000000000000000000000000006044820152606401610652565b6001611c148a610be6565b6009811115611c2557611c25613b72565b14611c725760405162461bcd60e51b815260206004820152601c60248201527f5068617365203120766f74696e67206973206e6f7420616374697665000000006044820152606401610652565b6000611cb26040518060400160405280601981526020017f726f636b657444414f50726f746f636f6c56657269666965720000000000000081525061236b565b6040517f011f992f00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff82169063011f992f90611d119033908b908f908e908d908d906004016146da565b602060405180830381865afa158015611d2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d529190614728565b611d9e5760405162461bcd60e51b815260206004820152600d60248201527f496e76616c69642070726f6f66000000000000000000000000000000000000006044820152606401610652565b611dac33898c8c6001612694565b50505050505050505050565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250836040516020016106a692919061474a565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250836040516020016105ef929190614313565b60006105366040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e0000000000000000000081525083604051602001610507929190614793565b6040518060400160405280601981526020017f726f636b657444414f50726f746f636f6c50726f706f73616c0000000000000081525030611eea826040516020016106a69190614026565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f645760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e7472616374000000006044820152606401610652565b6007611f6f84610be6565b6009811115611f8057611f80613b72565b1461201a5760405162461bcd60e51b8152602060048201526044602482018190527f50726f706f73616c20686173206e6f74207375636365656465642c2068617320908201527f65787069726564206f722068617320616c7265616479206265656e206578656360648201527f7574656400000000000000000000000000000000000000000000000000000000608482015260a401610652565b6120826040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250846040516020016120659291906140f1565b604051602081830303815290604052805190602001206001612b36565b60006120c26040518060400160405280601a81526020017f726f636b657444414f50726f746f636f6c50726f706f73616c7300000000000081525061236b565b90506000808273ffffffffffffffffffffffffffffffffffffffff166120e787610a70565b6040516120f491906147dc565b6000604051808303816000865af19150503d8060008114612131576040519150601f19603f3d011682016040523d82523d6000602084013e612136565b606091505b50915091508161214582613070565b906121635760405162461bcd60e51b81526004016106529190613c8a565b50604051428152329087907f3b7c90df35b419337cff0919fe91849006607bb66c4373623f06f9d48c1ebb989060200160405180910390a3505050505050565b600080546040517fbd02d0f50000000000000000000000000000000000000000000000000000000081526004810184905261010090910473ffffffffffffffffffffffffffffffffffffffff169063bd02d0f590602401602060405180830381865afa158015612217573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610536919061406b565b600080546040517f7ae1cfca0000000000000000000000000000000000000000000000000000000081526004810184905261010090910473ffffffffffffffffffffffffffffffffffffffff1690637ae1cfca90602401602060405180830381865afa1580156122af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105369190614728565b600080546040517f21f8a7210000000000000000000000000000000000000000000000000000000081526004810184905261010090910473ffffffffffffffffffffffffffffffffffffffff16906321f8a72190602401602060405180830381865afa158015612347573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105369190614084565b600080612382836040516020016106a69190614026565b905073ffffffffffffffffffffffffffffffffffffffff81166105365760405162461bcd60e51b815260206004820152601260248201527f436f6e7472616374206e6f7420666f756e6400000000000000000000000000006044820152606401610652565b600082116124375760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f7420766f74652077697468203020766f74696e6720706f776572006044820152606401610652565b600281600481111561244b5761244b613b72565b036124bc576124b76040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e000000000000000000008152508460405160200161249b929190614524565b60405160208183030381529060405280519060200120836130cf565b6125cf565b60018160048111156124d0576124d0613b72565b03612520576124b76040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e000000000000000000008152508460405160200161249b92919061435c565b600481600481111561253457612534613b72565b03612584576125846040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e000000000000000000008152508460405160200161249b929190614793565b6125cf6040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e000000000000000000008152508460405160200161249b92919061413a565b61261c6040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250848760405160200161249b939291906147f8565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16847fe857ea102a98fb62654940ae1fed947a8139277b3cbd9528658045e676d44e758542604051612685929190918252602082015260400190565b60405180910390a45050505050565b600084116126e45760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f7420766f74652077697468203020766f74696e6720706f776572006044820152606401610652565b6126ee8386610b25565b156127615760405162461bcd60e51b815260206004820152602b60248201527f4e6f6465206f70657261746f722068617320616c726561647920766f7465642060448201527f6f6e2070726f706f73616c0000000000000000000000000000000000000000006064820152608401610652565b600282600481111561277557612775613b72565b036127e6576127e16040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250846040516020016127c5929190614524565b6040516020818303038152906040528051906020012085613131565b6128f9565b60018260048111156127fa576127fa613b72565b0361284a576127e16040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250846040516020016127c592919061435c565b600482600481111561285e5761285e613b72565b036128ae576128ae6040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250846040516020016127c5929190614793565b6128f96040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250846040516020016127c592919061413a565b6129626040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e000000000000000000008152508487604051602001612946939291906147f8565b6040516020818303038152906040528051906020012085613193565b6129dc6040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e0000000000000000000081525084876040516020016129af93929190613f6a565b604051602081830303815290604052805190602001208360048111156129d7576129d7613b72565b613193565b8015612a2f57612a2f6040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250848760405160200161206593929190614257565b8473ffffffffffffffffffffffffffffffffffffffff16837f33236d57a7a2103a3af86b2aad702519360b248b0679028cfdb5d0814d8aa2f58487426040516111639392919061486b565b6000546040517fc031a18000000000000000000000000000000000000000000000000000000000815260048101839052606091610100900473ffffffffffffffffffffffffffffffffffffffff169063c031a180906024015b600060405180830381865afa158015612af0573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261053691908101906148ba565b6000546040517fabfdcced00000000000000000000000000000000000000000000000000000000815260048101849052821515602482015261010090910473ffffffffffffffffffffffffffffffffffffffff169063abfdcced906044015b600060405180830381600087803b158015612baf57600080fd5b505af1158015612bc3573d6000803e3d6000fd5b505050505050565b6000438510612c1c5760405162461bcd60e51b815260206004820152601960248201527f426c6f636b206d75737420626520696e207468652070617374000000000000006044820152606401610652565b6000612c3f6040518060600160405280602281526020016149ce6022913961236b565b9050438173ffffffffffffffffffffffffffffffffffffffff1663f9ef02526040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb1919061406b565b612cbb90886141fb565b11612d085760405162461bcd60e51b815260206004820152600d60248201527f426c6f636b20746f6f206f6c64000000000000000000000000000000000000006044820152606401610652565b60008060008373ffffffffffffffffffffffffffffffffffffffff16638e0add626040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d7c919061406b565b905060008473ffffffffffffffffffffffffffffffffffffffff1663de2494626040518163ffffffff1660e01b8152600401602060405180830381865afa158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def919061406b565b9050670de0b6b3a7640000612e04838b61490b565b612e0e9190614922565b9350670de0b6b3a7640000612e23828b61490b565b612e2d9190614922565b92505050613006338a8a8673ffffffffffffffffffffffffffffffffffffffff166310f664246040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ea6919061406b565b612eb090426141fb565b8773ffffffffffffffffffffffffffffffffffffffff1663fb5870226040518163ffffffff1660e01b8152600401602060405180830381865afa158015612efb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f1f919061406b565b8873ffffffffffffffffffffffffffffffffffffffff16631e0aa3f26040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8e919061406b565b8973ffffffffffffffffffffffffffffffffffffffff16630a092a4e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ffd919061406b565b89898f8f6131f5565b9998505050505050505050565b6000546040517f986e791a00000000000000000000000000000000000000000000000000000000815260048101839052606091610100900473ffffffffffffffffffffffffffffffffffffffff169063986e791a90602401612ad3565b60606044825110156130b557505060408051808201909152601d81527f5472616e73616374696f6e2072657665727465642073696c656e746c79000000602082015290565b6004820191508180602001905181019061053691906148ba565b6000546040517febb9d8c9000000000000000000000000000000000000000000000000000000008152600481018490526024810183905261010090910473ffffffffffffffffffffffffffffffffffffffff169063ebb9d8c990604401612b95565b6000546040517fadb353dc000000000000000000000000000000000000000000000000000000008152600481018490526024810183905261010090910473ffffffffffffffffffffffffffffffffffffffff169063adb353dc90604401612b95565b6000546040517fe2a4853a000000000000000000000000000000000000000000000000000000008152600481018490526024810183905261010090910473ffffffffffffffffffffffffffffffffffffffff169063e2a4853a90604401612b95565b600042891161326c5760405162461bcd60e51b815260206004820152602960248201527f50726f706f73616c2073746172742074696d65206d75737420626520696e207460448201527f68652066757475726500000000000000000000000000000000000000000000006064820152608401610652565b600088116132e15760405162461bcd60e51b8152602060048201526024808201527f50726f706f73616c2063616e6e6f7420686176652061206475726174696f6e2060448201527f6f662030000000000000000000000000000000000000000000000000000000006064820152608401610652565b600087116133565760405162461bcd60e51b8152602060048201526024808201527f50726f706f73616c2063616e6e6f7420686176652061206475726174696f6e2060448201527f6f662030000000000000000000000000000000000000000000000000000000006064820152608401610652565b600086116133cc5760405162461bcd60e51b815260206004820152603060248201527f50726f706f73616c2063616e6e6f742068617665206120657865637574696f6e60448201527f2065787069726174696f6e206f662030000000000000000000000000000000006064820152608401610652565b600085116134425760405162461bcd60e51b815260206004820152603860248201527f50726f706f73616c2063616e6e6f7420686176652061203020766f746573207260448201527f6571756972656420746f206265207375636365737366756c00000000000000006064820152608401610652565b600086886134508b8d6141fb565b61345a91906141fb565b61346491906141fb565b90506000613470611545565b61347b9060016141fb565b90506134e46040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250826040516020016134c892919061474a565b604051602081830303815290604052805190602001208f613a00565b61354b6040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e000000000000000000008152508260405160200161352f92919061456d565b604051602081830303815290604052805190602001208e613a65565b6135b26040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250826040516020016135969291906142ca565b604051602081830303815290604052805190602001208c613193565b61361f6040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250826040516020016135fd9291906145b6565b604051602081830303815290604052805190602001208b8d6129d791906141fb565b6136976040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e000000000000000000008152508260405160200161366a929190614691565b604051602081830303815290604052805190602001208a8c8e61368d91906141fb565b6129d791906141fb565b6136fe6040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250826040516020016136e2929190614183565b6040516020818303038152906040528051906020012083613193565b6137656040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250826040516020016137499291906145ff565b6040516020818303038152906040528051906020012042613193565b6137cc6040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250826040516020016137b0929190614648565b6040516020818303038152906040528051906020012088613193565b6138696040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250826040516020016138179291906140a8565b6040516020818303038152906040528051906020012086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613ac192505050565b6138d06040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e00000000000000000000815250826040516020016138b49291906143a5565b604051602081830303815290604052805190602001208d613193565b6139376040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e000000000000000000008152508260405160200161391b929190613fdd565b6040516020818303038152906040528051906020012087613193565b61399c6040518060400160405280601681526020017f64616f2e70726f746f636f6c2e70726f706f73616c2e0000000000000000000081525060405160200161398091906144e3565b6040516020818303038152906040528051906020012082613193565b808e73ffffffffffffffffffffffffffffffffffffffff167f29d8aca739231bada10eaca8f7a9e6bbd68a37ede7e5c292f2b3378dcb9fec5e8787426040516139e79392919061495d565b60405180910390a39d9c50505050505050505050505050565b6000546040517fca446dd90000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff83811660248301526101009092049091169063ca446dd990604401612b95565b6000546040517f6e89955000000000000000000000000000000000000000000000000000000000815261010090910473ffffffffffffffffffffffffffffffffffffffff1690636e89955090612b9590859085906004016149b4565b6000546040517f2e28d08400000000000000000000000000000000000000000000000000000000815261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e28d08490612b9590859085906004016149b4565b73ffffffffffffffffffffffffffffffffffffffff81168114613b3f57600080fd5b50565b60008060408385031215613b5557600080fd5b823591506020830135613b6781613b1d565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60058110613bb157613bb1613b72565b9052565b602081016105368284613ba1565b600060208284031215613bd557600080fd5b5035919050565b803560058110613beb57600080fd5b919050565b60008060408385031215613c0357600080fd5b82359150613c1360208401613bdc565b90509250929050565b60005b83811015613c37578181015183820152602001613c1f565b50506000910152565b60008151808452613c58816020860160208601613c1c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105336020830184613c40565b60208101600a8310613cb157613cb1613b72565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613d2d57613d2d613cb7565b604052919050565b600067ffffffffffffffff821115613d4f57613d4f613cb7565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60008083601f840112613d8d57600080fd5b50813567ffffffffffffffff811115613da557600080fd5b602083019150836020828501011115613dbd57600080fd5b9250929050565b803563ffffffff81168114613beb57600080fd5b60008083601f840112613dea57600080fd5b50813567ffffffffffffffff811115613e0257600080fd5b6020830191508360208260061b8501011115613dbd57600080fd5b60008060008060008060808789031215613e3657600080fd5b863567ffffffffffffffff80821115613e4e57600080fd5b818901915089601f830112613e6257600080fd5b8135613e75613e7082613d35565b613ce6565b8181528b6020838601011115613e8a57600080fd5b8160208501602083013760006020838301015280995050506020890135915080821115613eb657600080fd5b613ec28a838b01613d7b565b9097509550859150613ed660408a01613dc4565b94506060890135915080821115613eec57600080fd5b50613ef989828a01613dd8565b979a9699509497509295939492505050565b60008060008060008060a08789031215613f2457600080fd5b86359550613f3460208801613bdc565b94506040870135935060608701359250608087013567ffffffffffffffff811115613f5e57600080fd5b613ef989828a01613dd8565b60008451613f7c818460208901613c1c565b7f726563656970742e646972656374696f6e000000000000000000000000000000920191825250601181019290925260601b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166031820152604501919050565b60008351613fef818460208801613c1c565b7f70726f706f73616c2e7665746f2e71756f72756d0000000000000000000000009201918252506014810191909152603401919050565b7f636f6e74726163742e616464726573730000000000000000000000000000000081526000825161405e816010850160208701613c1c565b9190910160100192915050565b60006020828403121561407d57600080fd5b5051919050565b60006020828403121561409657600080fd5b81516140a181613b1d565b9392505050565b600083516140ba818460208801613c1c565b7f7061796c6f6164000000000000000000000000000000000000000000000000009201918252506007810191909152602701919050565b60008351614103818460208801613c1c565b7f65786563757465640000000000000000000000000000000000000000000000009201918252506008810191909152602801919050565b6000835161414c818460208801613c1c565b7f766f7465732e616761696e737400000000000000000000000000000000000000920191825250600d810191909152602d01919050565b60008351614195818460208801613c1c565b7f65787069726573000000000000000000000000000000000000000000000000009201918252506007810191909152602701919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610536576105366141cc565b60008351614220818460208801613c1c565b7f64657374726f79656400000000000000000000000000000000000000000000009201918252506009810191909152602901919050565b60008451614269818460208901613c1c565b7f726563656970742e706861736531000000000000000000000000000000000000920191825250600e81019290925260601b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602e820152604201919050565b600083516142dc818460208801613c1c565b7f73746172740000000000000000000000000000000000000000000000000000009201918252506005810191909152602501919050565b60008351614325818460208801613c1c565b7f66696e616c6973656400000000000000000000000000000000000000000000009201918252506009810191909152602901919050565b6000835161436e818460208801613c1c565b7f766f7465732e6162737461696e65640000000000000000000000000000000000920191825250600f810191909152602f01919050565b600083516143b7818460208801613c1c565b7f70726f706f73616c2e626c6f636b000000000000000000000000000000000000920191825250600e810191909152602e01919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361444e5761444e6141cc565b5060010190565b8183526000602080850194508260005b8581101561448b5781358752828201358388015260409687019690910190600101614465565b509495945050505050565b85815273ffffffffffffffffffffffffffffffffffffffff8516602082015263ffffffff841660408201526080606082015260006144d8608083018486614455565b979650505050505050565b600082516144f5818460208701613c1c565b7f746f74616c000000000000000000000000000000000000000000000000000000920191825250600501919050565b60008351614536818460208801613c1c565b7f766f7465732e666f7200000000000000000000000000000000000000000000009201918252506009810191909152602901919050565b6000835161457f818460208801613c1c565b7f6d657373616765000000000000000000000000000000000000000000000000009201918252506007810191909152602701919050565b600083516145c8818460208801613c1c565b7f706861736531456e6400000000000000000000000000000000000000000000009201918252506009810191909152602901919050565b60008351614611818460208801613c1c565b7f63726561746564000000000000000000000000000000000000000000000000009201918252506007810191909152602701919050565b6000835161465a818460208801613c1c565b7f766f7465732e7265717569726564000000000000000000000000000000000000920191825250600e810191909152602e01919050565b600083516146a3818460208801613c1c565b7f706861736532456e6400000000000000000000000000000000000000000000009201918252506009810191909152602901919050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015284604082015283606082015260a06080820152600061471c60a083018486614455565b98975050505050505050565b60006020828403121561473a57600080fd5b815180151581146140a157600080fd5b6000835161475c818460208801613c1c565b7f70726f706f7365720000000000000000000000000000000000000000000000009201918252506008810191909152602801919050565b600083516147a5818460208801613c1c565b7f766f7465732e7665746f00000000000000000000000000000000000000000000920191825250600a810191909152602a01919050565b600082516147ee818460208701613c1c565b9190910192915050565b6000845161480a818460208901613c1c565b7f726563656970742e766f74657300000000000000000000000000000000000000920191825250600d81019290925260601b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602d820152604101919050565b606081016148798286613ba1565b602082019390935260400152919050565b6000614898613e7084613d35565b90508281528383830111156148ac57600080fd5b6140a1836020830184613c1c565b6000602082840312156148cc57600080fd5b815167ffffffffffffffff8111156148e357600080fd5b8201601f810184136148f457600080fd5b6149038482516020840161488a565b949350505050565b8082028115828204841417610536576105366141cc565b600082614958577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6040815282604082015282846060830137600060608483010152600060607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8601168301019050826020830152949350505050565b8281526040602082015260006149036040830184613c4056fe726f636b657444414f50726f746f636f6c53657474696e677350726f706f73616c73a264697066735822122071d2ad4be1ca193c243ea2882cf14aba74207ed1884835fa553c74353fe9021b64736f6c63430008120033

Verified Source Code Partial Match

Compiler: v0.8.18+commit.87f61d96 EVM: paris Optimization: Yes (15000 runs)
SettingType.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

enum SettingType {
  UINT256,
  BOOL,
  ADDRESS,
  STRING,
  BYTES,
  BYTES32,
  INT256
}
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); }
}
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;
}
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);
}
RocketDAOProtocolProposal.sol 496 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 "../../RocketBase.sol";
import "../../../interface/dao/protocol/RocketDAOProtocolVerifierInterface.sol";
import "../../../interface/network/RocketNetworkVotingInterface.sol";
import "../../../interface/dao/protocol/settings/RocketDAOProtocolSettingsProposalsInterface.sol";
import "../../../interface/dao/security/RocketDAOSecurityInterface.sol";
import "../../../interface/dao/security/RocketDAOSecurityProposalsInterface.sol";
import "../../../interface/dao/protocol/RocketDAOProtocolProposalInterface.sol";

/// @notice Manages protocol DAO proposals
contract RocketDAOProtocolProposal is RocketBase, RocketDAOProtocolProposalInterface {

    // Events
    event ProposalAdded(address indexed proposer, uint256 indexed proposalID, bytes payload, uint256 time);
    event ProposalVoted(uint256 indexed proposalID, address indexed voter, VoteDirection direction, uint256 votingPower, uint256 time);
    event ProposalVoteOverridden(uint256 indexed proposalID, address indexed delegate, address indexed voter, uint256 votingPower, uint256 time);
    event ProposalExecuted(uint256 indexed proposalID, address indexed executor, uint256 time);
    event ProposalFinalised(uint256 indexed proposalID, address indexed executor, uint256 time);
    event ProposalDestroyed(uint256 indexed proposalID, uint256 time);

    // The namespace for any data stored in the protocol DAO (do not change)
    string constant internal daoProposalNameSpace = "dao.protocol.proposal.";

    constructor(RocketStorageInterface _rocketStorageAddress) RocketBase(_rocketStorageAddress) {
        version = 2;
    }

    /*** Proposals **********************/

    /// @notice Create a DAO proposal with calldata, if successful will be added to a queue where it can be executed
    ///         A general message can be passed by the proposer along with the calldata payload that can be executed
    ///         if the proposal passes
    /// @param _proposalMessage A string explaining what the proposal does
    /// @param _payload An ABI encoded payload which is executed on this contract if the proposal is successful
    /// @param _blockNumber The block number the proposal is being made for
    /// @param _treeNodes A merkle pollard generated at _blockNumber for the voting power state of the DAO
    function propose(string memory _proposalMessage, bytes calldata _payload, uint32 _blockNumber, Types.Node[] calldata _treeNodes) override external onlyRegisteredNode(msg.sender) onlyLatestContract("rocketDAOProtocolProposal", address(this)) returns (uint256) {
        // Check on-chain governance has been enabled
        {
            uint256 enabledBlock = getUint(keccak256(abi.encodePacked("protocol.dao.enabled.block")));
            require(enabledBlock != 0 && _blockNumber >= enabledBlock, "DAO has not been enabled");
        }
        // Calculate total voting power by summing the pollard
        uint256 totalVotingPower = 0;
        uint256 treeNodesLength = _treeNodes.length;
        for (uint256 i = 0; i < treeNodesLength; ++i) {
            totalVotingPower += _treeNodes[i].sum;
        }
        // Create the proposal
        uint256 proposalID = _propose(_proposalMessage, _blockNumber, totalVotingPower, _payload);
        // Add root to verifier so it can be challenged if incorrect
        RocketDAOProtocolVerifierInterface rocketDAOProtocolVerifier = RocketDAOProtocolVerifierInterface(getContractAddress("rocketDAOProtocolVerifier"));
        rocketDAOProtocolVerifier.submitProposalRoot(proposalID, msg.sender, _blockNumber, _treeNodes);
        return proposalID;
    }

    /// @notice Applies a vote during phase 1
    /// @param _proposalID ID of the proposal to vote on
    /// @param _voteDirection Direction of the vote
    /// @param _votingPower Total delegated voting power for the voter at the proposal block
    /// @param _nodeIndex The index of the node voting
    /// @param _witness A merkle proof into the network voting power tree proving the supplied voting power is correct
    function vote(uint256 _proposalID, VoteDirection _voteDirection, uint256 _votingPower, uint256 _nodeIndex, Types.Node[] calldata _witness) external onlyRegisteredNode(msg.sender) onlyLatestContract("rocketDAOProtocolProposal", address(this)) {
        // Check valid vote
        require(_voteDirection != VoteDirection.NoVote, "Invalid vote");
        // Check the proposal is in a state that can be voted on
        require(getState(_proposalID) == ProposalState.ActivePhase1, "Phase 1 voting is not active");
        // Verify the voting power is correct
        RocketDAOProtocolVerifierInterface rocketDAOProtocolVerifier = RocketDAOProtocolVerifierInterface(getContractAddress("rocketDAOProtocolVerifier"));
        require(rocketDAOProtocolVerifier.verifyVote(msg.sender, _nodeIndex, _proposalID, _votingPower, _witness), "Invalid proof");
        // Apply vote
        _vote(msg.sender, _votingPower, _proposalID, _voteDirection, true);
    }

    /// @notice Applies a vote during phase 2 (can be used to override vote direction of delegate)
    /// @param _proposalID ID of the proposal to vote on
    /// @param _voteDirection Direction of the vote
    function overrideVote(uint256 _proposalID, VoteDirection _voteDirection) override external onlyRegisteredNode(msg.sender) onlyLatestContract("rocketDAOProtocolProposal", address(this)) {
        // Check valid vote
        require(_voteDirection != VoteDirection.NoVote, "Invalid vote");
        // Check the proposal is in a state that can be voted on
        require(getState(_proposalID) == ProposalState.ActivePhase2, "Phase 2 voting is not active");
        // Load contracts
        RocketNetworkVotingInterface rocketNetworkVoting = RocketNetworkVotingInterface(getContractAddress("rocketNetworkVoting"));
        // Get caller's voting power and direction of their delegate
        uint32 blockNumber = uint32(getProposalBlock(_proposalID));
        uint256 votingPower = rocketNetworkVoting.getVotingPower(msg.sender, blockNumber);
        address delegate = rocketNetworkVoting.getDelegate(msg.sender, blockNumber);
        // Check if delegate voted in phase 1
        if (getReceiptHasVotedPhase1(_proposalID, delegate)) {
            // Get the vote direction of their delegate
            VoteDirection delegateVote = getReceiptDirection(_proposalID, delegate);
            require (delegateVote != _voteDirection, "Vote direction is the same as delegate");
            // Reverse the delegate's vote
            _overrideVote(delegate, msg.sender, _proposalID, votingPower, delegateVote);
        }
        // Apply this voter's vote
        _vote(msg.sender, votingPower, _proposalID, _voteDirection, false);
    }

    /// @notice Finalises a vetoed proposal by burning the proposer's bond
    /// @param _proposalID ID of the proposal to finalise
    function finalise(uint256 _proposalID) override external onlyLatestContract("rocketDAOProtocolProposal", address(this)) {
        // Check state
        require(getState(_proposalID) == ProposalState.Vetoed, "Proposal has not been vetoed");
        bytes32 finalisedKey = keccak256(abi.encodePacked(daoProposalNameSpace, "finalised", _proposalID));
        require(getBool(finalisedKey) == false, "Proposal already finalised");
        setBool(finalisedKey, true);
        // Burn the proposer's bond
        RocketDAOProtocolVerifierInterface rocketDAOProtocolVerifier = RocketDAOProtocolVerifierInterface(getContractAddress("rocketDAOProtocolVerifier"));
        rocketDAOProtocolVerifier.burnProposalBond(_proposalID);
        // Log it
        emit ProposalFinalised(_proposalID, tx.origin, block.timestamp);
    }

    /// @notice Executes a successful proposal
    /// @param _proposalID ID of the proposal to execute
    function execute(uint256 _proposalID) override external onlyLatestContract("rocketDAOProtocolProposal", address(this)) {
        // Firstly make sure this proposal has passed
        require(getState(_proposalID) == ProposalState.Succeeded, "Proposal has not succeeded, has expired or has already been executed");
        // Set as executed now before running payload
        setBool(keccak256(abi.encodePacked(daoProposalNameSpace, "executed", _proposalID)), true);
        // Get the proposals contract
        address daoProtocolProposalsAddress = getContractAddress("rocketDAOProtocolProposals");
        // Ok all good, lets run the payload on the dao contract that the proposal relates too, it should execute one of the methods on this contract
        (bool success, bytes memory response) = daoProtocolProposalsAddress.call(getPayload(_proposalID));
        // Was there an error?
        require(success, getRevertMsg(response));
        // Log it
        emit ProposalExecuted(_proposalID, tx.origin, block.timestamp);
    }

    /// @dev Called by the verifier contract to destroy a proven invalid proposal
    function destroy(uint256 _proposalID) override external onlyLatestContract("rocketDAOProtocolProposal", address(this)) onlyLatestContract("rocketDAOProtocolVerifier", msg.sender) {
        // Cancel the proposal
        bytes32 destroyedKey = keccak256(abi.encodePacked(daoProposalNameSpace, "destroyed", _proposalID));
        require(getBool(destroyedKey) == false, "Proposal already destroyed");
        setBool(destroyedKey, true);
        // Log it
        emit ProposalDestroyed(_proposalID, block.timestamp);
    }

    /// @notice Gets the block used to generate a proposal
    /// @param _proposalID The ID of the proposal to query
    /// @return The block used to generated the requested proposal
    function getProposalBlock(uint256 _proposalID) override public view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "proposal.block", _proposalID)));
    }

    /// @notice Gets the amount of vetos required to stop a proposal
    /// @param _proposalID The ID of the proposal to veto
    /// @return The amount of voting power required to veto a proposal
    function getProposalVetoQuorum(uint256 _proposalID) override external view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "proposal.veto.quorum", _proposalID)));
    }

    /// @notice Get the current total proposals
    function getTotal() override public view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "total")));
    }

    /// @notice Get the member who proposed
    /// @param _proposalID The ID of the proposal to query
    function getProposer(uint256 _proposalID) override public view returns (address) {
        return getAddress(keccak256(abi.encodePacked(daoProposalNameSpace, "proposer", _proposalID)));
    }

    /// @notice Get the proposal message
    /// @param _proposalID The ID of the proposal to query
    function getMessage(uint256 _proposalID) override external view returns (string memory) {
        return getString(keccak256(abi.encodePacked(daoProposalNameSpace, "message", _proposalID)));
    }

    /// @notice Get the start of this proposal as a timestamp
    /// @param _proposalID The ID of the proposal to query
    function getStart(uint256 _proposalID) override public view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "start", _proposalID)));
    }

    /// @notice Get the end of phase1 of this proposal as a timestamp
    /// @param _proposalID The ID of the proposal to query
    function getPhase1End(uint256 _proposalID) override public view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "phase1End", _proposalID)));
    }

    /// @notice Get the end of phase2 of this proposal as a timestamp
    /// @param _proposalID The ID of the proposal to query
    /// @return timestamp for the end of phase2
    function getPhase2End(uint256 _proposalID) override public view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "phase2End", _proposalID)));
    }

    /// @notice The timestamp where the proposal expires and can no longer be executed if it is successful
    /// @param _proposalID The ID of the proposal to query
    function getExpires(uint256 _proposalID) override public view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "expires", _proposalID)));
    }

    /// @notice Get the created status of this proposal
    /// @param _proposalID The ID of the proposal to query
    function getCreated(uint256 _proposalID) override external view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "created", _proposalID)));
    }

    /// @notice Get the for voting power count of this proposal
    /// @param _proposalID The ID of the proposal to query
    function getVotingPowerFor(uint256 _proposalID) override public view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.for", _proposalID)));
    }

    /// @notice Get the against voting power count of this proposal
    /// @param _proposalID The ID of the proposal to query
    function getVotingPowerAgainst(uint256 _proposalID) override public view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.against", _proposalID)));
    }

    /// @notice Get the veto voting power  count of this proposal
    /// @param _proposalID The ID of the proposal to query
    function getVotingPowerVeto(uint256 _proposalID) override public view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.veto", _proposalID)));
    }

    /// @notice Get the against voteing power count of this proposal
    /// @param _proposalID The ID of the proposal to query
    function getVotingPowerAbstained(uint256 _proposalID) override public view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.abstained", _proposalID)));
    }

    /// @notice How much voting power is required for the proposal to succeed
    /// @param _proposalID The ID of the proposal to query
    function getVotingPowerRequired(uint256 _proposalID) override public view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.required", _proposalID)));
    }

    /// @notice Get the destroyed status of this proposal
    /// @param _proposalID The ID of the proposal to query
    function getDestroyed(uint256 _proposalID) override public view returns (bool) {
        return getBool(keccak256(abi.encodePacked(daoProposalNameSpace, "destroyed", _proposalID)));
    }

    /// @notice Get the finalised status of this proposal
    /// @param _proposalID The ID of the proposal to query
    function getFinalised(uint256 _proposalID) override external view returns (bool) {
        return getBool(keccak256(abi.encodePacked(daoProposalNameSpace, "finalised", _proposalID)));
    }

    /// @notice Get the executed status of this proposal
    /// @param _proposalID The ID of the proposal to query
    function getExecuted(uint256 _proposalID) override public view returns (bool) {
        return getBool(keccak256(abi.encodePacked(daoProposalNameSpace, "executed", _proposalID)));
    }

    /// @notice Get the amount of veto votes required to veto this proposal
    /// @param _proposalID The ID of the proposal to query
    function getVetoQuorum(uint256 _proposalID) override public view returns (uint256) {
        return getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "proposal.veto.quorum", _proposalID)));
    }

    /// @notice Get the veto status of this proposal
    /// @param _proposalID The ID of the proposal to query
    function getVetoed(uint256 _proposalID) override public view returns (bool) {
        uint256 votesVeto = getVotingPowerVeto(_proposalID);
        uint256 quorum = getVetoQuorum(_proposalID);
        return votesVeto >= quorum;
    }

    /// @notice Get the proposal payload
    /// @param _proposalID The ID of the proposal to query
    function getPayload(uint256 _proposalID) override public view returns (bytes memory) {
        return getBytes(keccak256(abi.encodePacked(daoProposalNameSpace, "payload", _proposalID)));
    }

    /// @notice Returns true if this proposal has already been voted on by a node
    /// @param _proposalID The ID of the proposal to query
    /// @param _nodeAddress The node operator address to query
    function getReceiptHasVoted(uint256 _proposalID, address _nodeAddress) override public view returns (bool) {
        return getReceiptDirection(_proposalID, _nodeAddress) != VoteDirection.NoVote;
    }

    /// @notice Returns true if this proposal has been voted on in phase 1 by a node
    /// @param _proposalID The ID of the proposal to query
    /// @param _nodeAddress The node operator address to query
    function getReceiptHasVotedPhase1(uint256 _proposalID, address _nodeAddress) override public view returns (bool) {
        return getBool(keccak256(abi.encodePacked(daoProposalNameSpace, "receipt.phase1", _proposalID, _nodeAddress)));
    }

    /// @notice Returns the direction a node voted on a given proposal
    /// @param _proposalID The ID of the proposal to query
    /// @param _nodeAddress The node operator address to query
    function getReceiptDirection(uint256 _proposalID, address _nodeAddress) override public view returns (VoteDirection) {
        return VoteDirection(getUint(keccak256(abi.encodePacked(daoProposalNameSpace, "receipt.direction", _proposalID, _nodeAddress))));
    }

    /// @notice Return the state of the specified proposal
    /// @param _proposalID The ID of the proposal to query
    function getState(uint256 _proposalID) override public view returns (ProposalState) {
        // Check the proposal ID is legit
        require(getTotal() >= _proposalID && _proposalID > 0, "Invalid proposal ID");
        // Destroyed?
        if (getDestroyed(_proposalID)) {
            return ProposalState.Destroyed;
        }
        // Has it been executed?
        else if (getExecuted(_proposalID)) {
            return ProposalState.Executed;
        } else {
            uint256 start = getStart(_proposalID);
            // Is the proposal pending?
            if (block.timestamp < start) {
                return ProposalState.Pending;
            } else {
                // The proposal is active and can be voted on
                uint256 phase1End = getPhase1End(_proposalID);
                uint256 phase2End = getPhase2End(_proposalID);
                if (block.timestamp < phase1End) {
                    return ProposalState.ActivePhase1;
                } else if (block.timestamp < phase2End) {
                        return ProposalState.ActivePhase2;
                } else {
                    // Is the proposal vetoed?
                    if (getVetoed(_proposalID)) {
                        return ProposalState.Vetoed;
                    }

                    uint256 votesFor = getVotingPowerFor(_proposalID);
                    uint256 votesAgainst = getVotingPowerAgainst(_proposalID);
                    uint256 votesAbstained = getVotingPowerAbstained(_proposalID);
                    uint256 totalVotes = votesFor + votesAgainst + votesAbstained;

                    // Has the proposal reached quorum?
                    if (totalVotes >= getVotingPowerRequired(_proposalID)) {
                        if (votesFor > votesAgainst) {
                            if (block.timestamp < getExpires(_proposalID)) {
                                // Vote was successful, is now awaiting execution
                                return ProposalState.Succeeded;
                            }
                        } else {
                            // Vote was defeated
                            return ProposalState.Defeated;
                        }
                    } else {
                        return ProposalState.QuorumNotMet;
                    }
                }
            }
        }
        return ProposalState.Expired;
    }

    /// @dev Internal function to generate a proposal
    /// @param _proposalMessage the message associated with the proposal
    /// @param _blockNumber the block number considered for the proposal snapshot
    /// @param _totalVotingPower the total voting power for the proposal - used to calculate quorum
    /// @param _payload A calldata payload to execute after the proposal is successful
    /// @return The new proposal's ID
    function _propose(string memory _proposalMessage, uint256 _blockNumber, uint256 _totalVotingPower, bytes calldata _payload) internal returns (uint256) {
        // Validate block number
        require(_blockNumber < block.number, "Block must be in the past");
        // Load contracts
        RocketDAOProtocolSettingsProposalsInterface rocketDAOProtocolSettingsProposals = RocketDAOProtocolSettingsProposalsInterface(getContractAddress("rocketDAOProtocolSettingsProposals"));
        require(_blockNumber + rocketDAOProtocolSettingsProposals.getProposalMaxBlockAge() > block.number, "Block too old");
        // Calculate quorums
        uint256 quorum = 0;
        uint256 vetoQuorum = 0;
        {
            uint256 proposalQuorum = rocketDAOProtocolSettingsProposals.getProposalQuorum();
            uint256 vetoProposalQuorum = rocketDAOProtocolSettingsProposals.getProposalVetoQuorum();
            quorum = _totalVotingPower * proposalQuorum / calcBase;
            vetoQuorum = _totalVotingPower * vetoProposalQuorum / calcBase;
        }
        // Add proposal
        return _addProposal(
            msg.sender,
            _proposalMessage,
            _blockNumber,
            block.timestamp + rocketDAOProtocolSettingsProposals.getVoteDelayTime(),
            rocketDAOProtocolSettingsProposals.getVotePhase1Time(),
            rocketDAOProtocolSettingsProposals.getVotePhase2Time(),
            rocketDAOProtocolSettingsProposals.getExecuteTime(),
            quorum,
            vetoQuorum,
            _payload
        );
    }

    /// @dev Add a proposal to the protocol DAO
    function _addProposal(address _proposer, string memory _message, uint256 _blockNumber, uint256 _startTime, uint256 _phase1Duration, uint256 _phase2Duration, uint256 _expires, uint256 _votesRequired, uint256 _vetoQuorum, bytes calldata _payload) internal returns (uint256) {
        // Basic checks
        require(_startTime > block.timestamp, "Proposal start time must be in the future");
        require(_phase1Duration > 0, "Proposal cannot have a duration of 0");
        require(_phase2Duration > 0, "Proposal cannot have a duration of 0");
        require(_expires > 0, "Proposal cannot have a execution expiration of 0");
        require(_votesRequired > 0, "Proposal cannot have a 0 votes required to be successful");
        // Set the expires block
        uint256 expires = _startTime + _phase1Duration + _phase2Duration + _expires;
        // Get the proposal ID
        uint256 proposalID = getTotal() + 1;
        // The data structure for a proposal
        setAddress(keccak256(abi.encodePacked(daoProposalNameSpace, "proposer", proposalID)), _proposer);                   // Which node is making the proposal
        setString(keccak256(abi.encodePacked(daoProposalNameSpace, "message", proposalID)), _message);                      // A general message that can be included with the proposal
        setUint(keccak256(abi.encodePacked(daoProposalNameSpace, "start", proposalID)), _startTime);                        // The time the proposal becomes active for voting on
        setUint(keccak256(abi.encodePacked(daoProposalNameSpace, "phase1End", proposalID)), _startTime + _phase1Duration);  // The time the proposal where voting ends on phase 1
        setUint(keccak256(abi.encodePacked(daoProposalNameSpace, "phase2End", proposalID)), _startTime + _phase1Duration + _phase2Duration); // The time the proposal where voting ends on phase 2
        setUint(keccak256(abi.encodePacked(daoProposalNameSpace, "expires", proposalID)), expires);                         // The time when the proposal expires and can no longer be executed if it is successful
        setUint(keccak256(abi.encodePacked(daoProposalNameSpace, "created", proposalID)), block.timestamp);                 // The time the proposal was created at
        setUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.required", proposalID)), _votesRequired);           // How many votes are required for the proposal to pass
        setBytes(keccak256(abi.encodePacked(daoProposalNameSpace, "payload", proposalID)), _payload);                       // A calldata payload to execute after it is successful
        setUint(keccak256(abi.encodePacked(daoProposalNameSpace, "proposal.block", proposalID)), uint256(_blockNumber));    // The block that the network voting power tree was generated for for this proposal
        setUint(keccak256(abi.encodePacked(daoProposalNameSpace, "proposal.veto.quorum", proposalID)), _vetoQuorum);        // The number of veto votes required to veto this proposal
        // Update the total proposals
        setUint(keccak256(abi.encodePacked(daoProposalNameSpace, "total")), proposalID);
        // Log it
        emit ProposalAdded(_proposer, proposalID, _payload, block.timestamp);
        // Done
        return proposalID;
    }

    /// @dev Internal method to override the vote of a delegate
    function _overrideVote(address _delegate, address _voter, uint256 _proposalID, uint256 _votes, VoteDirection _voteDirection) internal {
        // Check for non-zero voting power
        require(_votes > 0, "Cannot vote with 0 voting power");
        // Remove votes from proposal
        if (_voteDirection == VoteDirection.For) {
            subUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.for", _proposalID)), _votes);
        } else if(_voteDirection == VoteDirection.Abstain) {
            subUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.abstained", _proposalID)), _votes);
        } else {
            if(_voteDirection == VoteDirection.AgainstWithVeto) {
                subUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.veto", _proposalID)), _votes);
            }
            subUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.against", _proposalID)), _votes);
        }
        // Reduce the voting power applied by the delegate to this proposal
        subUint(keccak256(abi.encodePacked(daoProposalNameSpace, "receipt.votes", _proposalID, _delegate)), _votes);
        // Log it
        emit ProposalVoteOverridden(_proposalID, _delegate, _voter, _votes, block.timestamp);
    }

    /// @dev Internal method to apply voting power against a proposal
    function _vote(address _nodeOperator, uint256 _votes, uint256 _proposalID, VoteDirection _voteDirection, bool _phase1) internal {
        // Check for non-zero voting power
        require(_votes > 0, "Cannot vote with 0 voting power");
        // Has this node already voted on this proposal?
        require(!getReceiptHasVoted(_proposalID, _nodeOperator), "Node operator has already voted on proposal");
        // Add votes to proposal
        if (_voteDirection == VoteDirection.For) {
            addUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.for", _proposalID)), _votes);
        } else if(_voteDirection == VoteDirection.Abstain) {
            addUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.abstained", _proposalID)), _votes);
        } else {
            if(_voteDirection == VoteDirection.AgainstWithVeto) {
                addUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.veto", _proposalID)), _votes);
            }
            addUint(keccak256(abi.encodePacked(daoProposalNameSpace, "votes.against", _proposalID)), _votes);
        }
        // Record the vote receipt now
        setUint(keccak256(abi.encodePacked(daoProposalNameSpace, "receipt.votes", _proposalID, _nodeOperator)), _votes);
        setUint(keccak256(abi.encodePacked(daoProposalNameSpace, "receipt.direction", _proposalID, _nodeOperator)), uint256(_voteDirection));
        // Record delegate voted in phase 1
        if (_phase1) {
            setBool(keccak256(abi.encodePacked(daoProposalNameSpace, "receipt.phase1", _proposalID, _nodeOperator)), true);
        }
        // Log it
        emit ProposalVoted(_proposalID, _nodeOperator, _voteDirection, _votes, block.timestamp);
    }
}
RocketDAOSecurityInterface.sol 40 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 RocketDAOSecurityInterface {
    function getMemberQuorumVotesRequired() external view returns (uint256);
    function getMemberIsValid(address _nodeAddress) external view returns (bool);
    function getMemberAt(uint256 _index) external view returns (address);
    function getMemberCount() external view returns (uint256);
    function getMemberID(address _nodeAddress) external view returns (string memory);
    function getMemberJoinedTime(address _nodeAddress) external view returns (uint256);
    function getMemberProposalExecutedTime(string memory _proposalType, address _nodeAddress) external view returns (uint256);
}
RocketDAOProtocolProposalInterface.sol 92 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/SettingType.sol";
import "./RocketDAOProtocolVerifierInterface.sol";

interface RocketDAOProtocolProposalInterface {
    // Possible states that a proposal may be in
    enum ProposalState {
        Pending,
        ActivePhase1,
        ActivePhase2,
        Destroyed,
        Vetoed,
        QuorumNotMet,
        Defeated,
        Succeeded,
        Expired,
        Executed
    }

    enum VoteDirection {
        NoVote,
        Abstain,
        For,
        Against,
        AgainstWithVeto
    }

    function getTotal() external view returns (uint256);
    function getProposer(uint256 _proposalID) external view returns (address);
    function getMessage(uint256 _proposalID) external view returns (string memory);
    function getStart(uint256 _proposalID) external view returns (uint256);
    function getPhase1End(uint256 _proposalID) external view returns (uint256);
    function getPhase2End(uint256 _proposalID) external view returns (uint256);
    function getExpires(uint256 _proposalID) external view returns (uint256);
    function getCreated(uint256 _proposalID) external view returns (uint256);
    function getVotingPowerFor(uint256 _proposalID) external view returns (uint256);
    function getVotingPowerAgainst(uint256 _proposalID) external view returns (uint256);
    function getVotingPowerVeto(uint256 _proposalID) external view returns (uint256);
    function getVotingPowerAbstained(uint256 _proposalID) external view returns (uint256);
    function getVotingPowerRequired(uint256 _proposalID) external view returns (uint256);
    function getDestroyed(uint256 _proposalID) external view returns (bool);
    function getFinalised(uint256 _proposalID) external view returns (bool);
    function getExecuted(uint256 _proposalID) external view returns (bool);
    function getVetoQuorum(uint256 _proposalID) external view returns (uint256);
    function getVetoed(uint256 _proposalID) external view returns (bool);
    function getPayload(uint256 _proposalID) external view returns (bytes memory);
    function getReceiptHasVoted(uint256 _proposalID, address _nodeAddress) external view returns (bool);
    function getReceiptHasVotedPhase1(uint256 _proposalID, address _nodeAddress) external view returns (bool);
    function getReceiptDirection(uint256 _proposalID, address _nodeAddress) external view returns (VoteDirection);
    function getState(uint256 _proposalID) external view returns (ProposalState);

    function getProposalBlock(uint256 _proposalID) external view returns (uint256);
    function getProposalVetoQuorum(uint256 _proposalID) external view returns (uint256);

    function propose(string memory _proposalMessage, bytes memory _payload, uint32 _blockNumber, Types.Node[] calldata _treeNodes) external returns (uint256);
    function vote(uint256 _proposalID, VoteDirection _vote, uint256 _votingPower, uint256 _nodeIndex, Types.Node[] calldata _witness) external;
    function overrideVote(uint256 _proposalID, VoteDirection _voteDirection) external;
    function finalise(uint256 _proposalID) external;
    function execute(uint256 _proposalID) external;
    function destroy(uint256 _proposalID) external;
}
RocketDAOProtocolVerifierInterface.sol 72 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;

interface Types {
    enum ChallengeState {
        Unchallenged,
        Challenged,
        Responded,
        Paid
    }

    struct Proposal {
        address proposer;
        uint32 blockNumber;
        uint128 nodeCount;
        bytes32 hash;
        uint256 sum;
    }

    struct Node {
        uint256 sum;
        bytes32 hash;
    }

    struct Leaf {
        address nodeAddress;
        uint256 effectiveRpl;
    }
}

interface RocketDAOProtocolVerifierInterface {
    function getDefeatIndex(uint256 _proposalID) external view returns (uint256);
    function getProposalBond(uint256 _proposalID) external view returns (uint256);
    function getChallengeBond(uint256 _proposalID) external view returns (uint256);
    function getChallengePeriod(uint256 _proposalID) external view returns (uint256);
    function getDepthPerRound() external pure returns (uint256);
    function submitProposalRoot(uint256 _proposalId, address _proposer, uint32 _blockNumber, Types.Node[] memory _treeNodes) external;
    function burnProposalBond(uint256 _proposalID) external;
    function createChallenge(uint256 _proposalID, uint256 _index, Types.Node calldata _node, Types.Node[] calldata _witness) external;
    function submitRoot(uint256 propId, uint256 index, Types.Node[] memory nodes) external;
    function getChallengeState(uint256 _proposalID, uint256 _index) external view returns (Types.ChallengeState);
    function verifyVote(address _voter, uint256 _nodeIndex, uint256 _proposalID, uint256 _votingPower, Types.Node[] calldata _witness) external view returns (bool);
}
RocketDAOSecurityProposalsInterface.sol 49 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/SettingType.sol";

interface RocketDAOSecurityProposalsInterface {
    function propose(string memory _proposalMessage, bytes memory _payload) external returns (uint256);
    function vote(uint256 _proposalID, bool _support) external;
    function cancel(uint256 _proposalID) external;
    function execute(uint256 _proposalID) external;

    function proposalSettingUint(string memory _settingContractName, string memory _settingPath, uint256 _value) external;
    function proposalSettingBool(string memory _settingContractName, string memory _settingPath, bool _value) external;
    function proposalSettingAddress(string memory _settingContractName, string memory _settingPath, address _value) external;

    function proposalInvite(string memory _id, address _memberAddress) external;
    function proposalKick(address _memberAddress) external;
    function proposalKickMulti(address[] calldata _memberAddresses) external;
    function proposalReplace(address _existingMemberAddress, string calldata _newMemberId, address _newMemberAddress) external;
}
RocketDAOProtocolSettingsProposalsInterface.sol 44 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 RocketDAOProtocolSettingsProposalsInterface {
    function getVotePhase1Time() external view returns(uint256);
    function getVotePhase2Time() external view returns(uint256);
    function getVoteDelayTime() external view returns(uint256);
    function getExecuteTime() external view returns(uint256);
    function getProposalBond() external view returns(uint256);
    function getChallengeBond() external view returns(uint256);
    function getChallengePeriod() external view returns(uint256);
    function getProposalQuorum() external view returns (uint256);
    function getProposalVetoQuorum() external view returns (uint256);
    function getProposalMaxBlockAge() external view returns (uint256);
}

Read Contract

getCreated 0x9cb2b69b → uint256
getDestroyed 0x44ff2d99 → bool
getExecuted 0x21947507 → bool
getExpires 0x3dca885d → uint256
getFinalised 0xe641455e → bool
getMessage 0x86f79edb → string
getPayload 0x1d2db6c8 → bytes
getPhase1End 0x92d4d1de → uint256
getPhase2End 0xaeb9be7e → uint256
getProposalBlock 0x74f6c650 → uint256
getProposalVetoQuorum 0x7960ee02 → uint256
getProposer 0xe14bd874 → address
getReceiptDirection 0x021eca58 → uint8
getReceiptHasVoted 0x23d44f0d → bool
getReceiptHasVotedPhase1 0x58590de3 → bool
getStart 0x5bc22d1b → uint256
getState 0x44c9af28 → uint8
getTotal 0x775a25e3 → uint256
getVetoQuorum 0x1709e0e6 → uint256
getVetoed 0x9de1c862 → bool
getVotingPowerAbstained 0x716c3f32 → uint256
getVotingPowerAgainst 0x2cb9186f → uint256
getVotingPowerFor 0x80a6cdd4 → uint256
getVotingPowerRequired 0x9eb07575 → uint256
getVotingPowerVeto 0xeb86e7c0 → uint256
version 0x54fd4d50 → uint8

Write Contract 6 functions

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

destroy 0x9d118770
uint256 _proposalID
execute 0xfe0d94c1
uint256 _proposalID
finalise 0x6b75dbde
uint256 _proposalID
overrideVote 0x1c15da27
uint256 _proposalID
uint8 _voteDirection
propose 0xc966c547
string _proposalMessage
bytes _payload
uint32 _blockNumber
tuple[] _treeNodes
returns: uint256
vote 0x5f64eba3
uint256 _proposalID
uint8 _voteDirection
uint256 _votingPower
uint256 _nodeIndex
tuple[] _witness

Recent Transactions

No transactions found for this address