Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xc12dfb80d80d564DB9b180AbF61a252eE6355058
Balance 0 ETH
Nonce 1
Code Size 9697 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

9697 bytes
0x60806040526004361061012a5760003560e01c80635cb17a90116100ab5780637c697e741161006f5780637c697e74146102ee5780638554913b146102f6578063888b042f14610320578063cc88c3c814610335578063d0e30db01461035f578063e78ec42e146103675761012a565b80635cb17a90146102735780635fd58f0d1461029f57806363a5db9e146102a75780636ada7847146102d157806372f5158d146102e65761012a565b80633b474a65116100f25780633b474a65146101b45780633fa9c18d146101c957806347fa434a146101f357806354fd4d501461021c5780635b17d04b146102475761012a565b8063035cf1421461012f5780630a019eaf146101565780630c37d2dc1461016057806312065fe01461018a57806327c8f1931461019f575b600080fd5b34801561013b57600080fd5b50610144610391565b60408051918252519081900360200190f35b61015e6103d2565b005b34801561016c57600080fd5b5061015e6004803603602081101561018357600080fd5b50356105a3565b34801561019657600080fd5b506101446108ce565b3480156101ab57600080fd5b5061015e61097d565b3480156101c057600080fd5b50610144610cdb565b3480156101d557600080fd5b5061015e600480360360208110156101ec57600080fd5b5035610d1b565b3480156101ff57600080fd5b50610208610df0565b604080519115158252519081900360200190f35b34801561022857600080fd5b50610231610e30565b6040805160ff9092168252519081900360200190f35b34801561025357600080fd5b5061015e6004803603602081101561026a57600080fd5b50351515610e39565b34801561027f57600080fd5b5061015e6004803603602081101561029657600080fd5b50351515610f06565b61015e610fd8565b3480156102b357600080fd5b5061015e600480360360208110156102ca57600080fd5b50356111a6565b3480156102dd57600080fd5b5061020861146b565b61015e6114a6565b61015e61164a565b34801561030257600080fd5b5061015e6004803603602081101561031957600080fd5b5035611787565b34801561032c57600080fd5b50610144611946565b34801561034157600080fd5b5061015e6004803603602081101561035857600080fd5b5035611a1d565b61015e611bdc565b34801561037357600080fd5b5061015e6004803603602081101561038a57600080fd5b5035611e06565b60006103cc6040518060400160405280601881526020017773657474696e67732e6465706f7369742e6d696e696d756d60401b815250611ed3565b90505b90565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061048882604051602001808060008051602061251f83398151915281525060100182805190602001908083835b602083106104485780518252601f199092019160209182019101610429565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120611fcc565b6001600160a01b0316816001600160a01b0316146104db576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b8152503361054a82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461059d576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b50505050565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061061882604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461066b576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600d81526020016c7374616669576974686472617760981b815250336106dd82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614610730576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60006107606040518060400160405280600d81526020016c7374616669576974686472617760981b815250612026565b9050600061078f6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b90506107996108ce565b8711156107d75760405162461bcd60e51b815260040180806020018281038252602381526020018061255f6023913960400191505060405180910390fd5b806001600160a01b0316633bed33ce886040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561081d57600080fd5b505af1158015610831573d6000803e3d6000fd5b50505050816001600160a01b031663439370b1886040518263ffffffff1660e01b81526004016000604051808303818588803b15801561087057600080fd5b505af1158015610884573d6000803e3d6000fd5b5050604080518b815242602082015281513395507f992f462cfb62e164bd03bf07baf2cffce83fbd9370cae10635842b20200121209450908190039091019150a250505050505050565b6000806108fc6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b9050806001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561094b57600080fd5b505afa15801561095f573d6000803e3d6000fd5b505050506040513d602081101561097557600080fd5b505191505090565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b815250306109f282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614610a45576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b610a4d610df0565b610a5657610cd7565b6000610a8e6040518060400160405280601581526020017473746166695374616b696e67506f6f6c517565756560581b815250612026565b90506000610abd6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b90506000610ac9610cdb565b905060005b81811015610cd2576000846001600160a01b031663516123056040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1157600080fd5b505afa158015610b25573d6000803e3d6000fd5b505050506040513d6020811015610b3b57600080fd5b50519050801580610b52575080610b506108ce565b105b15610b5d5750610cd2565b6000856001600160a01b0316639a9580616040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610b9a57600080fd5b505af1158015610bae573d6000803e3d6000fd5b505050506040513d6020811015610bc457600080fd5b505160408051631df699e760e11b815260048101859052905191925082916001600160a01b03881691633bed33ce91602480830192600092919082900301818387803b158015610c1357600080fd5b505af1158015610c27573d6000803e3d6000fd5b50505050806001600160a01b03166348146113846040518263ffffffff1660e01b81526004016000604051808303818588803b158015610c6657600080fd5b505af1158015610c7a573d6000803e3d6000fd5b50506040805187815242602082015281516001600160a01b03881695507fa1811054b7d96716259cff0d366c2f6405951e0efe00c8db3e237cbf77fe7be99450908190039091019150a2505050806001019050610ace565b505050505b5050565b60006103cc6040518060400160405280601f81526020017f73657474696e67732e6465706f7369742e61737369676e2e6d6178696d756d00815250611ed3565b610d426040518060400160405280600581526020016437bbb732b960d91b815250336120cc565b80610d6f5750610d6f6040518060400160405280600581526020016430b236b4b760d91b815250336120cc565b610dae576040805162461bcd60e51b815260206004820152601b602482015260008051602061253f833981519152604482015290519081900360640190fd5b610ded6040518060400160405280601f81526020017f73657474696e67732e6465706f7369742e61737369676e2e6d6178696d756d0081525082612175565b50565b60006103cc6040518060400160405280601f81526020017f73657474696e67732e6465706f7369742e61737369676e2e656e61626c656400815250612259565b60005460ff1681565b610e606040518060400160405280600581526020016437bbb732b960d91b815250336120cc565b80610e8d5750610e8d6040518060400160405280600581526020016430b236b4b760d91b815250336120cc565b610ecc576040805162461bcd60e51b815260206004820152601b602482015260008051602061253f833981519152604482015290519081900360640190fd5b610ded604051806040016040528060188152602001771cd95d1d1a5b99dccb99195c1bdcda5d0b995b98589b195960421b815250826122b0565b610f2d6040518060400160405280600581526020016437bbb732b960d91b815250336120cc565b80610f5a5750610f5a6040518060400160405280600581526020016430b236b4b760d91b815250336120cc565b610f99576040805162461bcd60e51b815260206004820152601b602482015260008051602061253f833981519152604482015290519081900360640190fd5b610ded6040518060400160405280601f81526020017f73657474696e67732e6465706f7369742e61737369676e2e656e61626c656400815250826122b0565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061104d82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b0316146110a0576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600d81526020016c7374616669576974686472617760981b8152503361111282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611165576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60408051348152426020820152815133927f3a6614e80d02b57255cbb1f8305fbeca53d7e05a4b779d406279196608512925928290030190a261059d612382565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061121b82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461126e576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b604051806040016040528060098152602001683922aa242a37b5b2b760b91b815250336112dc82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461132f576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b600061135b604051806040016040528060098152602001683922aa242a37b5b2b760b91b815250612026565b9050600061138a6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b90506113946108ce565b8711156113d25760405162461bcd60e51b815260040180806020018281038252602381526020018061255f6023913960400191505060405180910390fd5b806001600160a01b0316633bed33ce886040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561141857600080fd5b505af115801561142c573d6000803e3d6000fd5b50505050816001600160a01b0316636c985a88886040518263ffffffff1660e01b81526004016000604051808303818588803b15801561087057600080fd5b60006103cc604051806040016040528060188152602001771cd95d1d1a5b99dccb99195c1bdcda5d0b995b98589b195960421b815250612259565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061151b82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461156e576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60408051717374616b696e67706f6f6c2e65786973747360701b60208083019190915233606081901b603284015283516026818503018152604690930190935281519101206115bc9061240d565b611604576040805162461bcd60e51b8152602060048201526014602482015273125b9d985b1a59081cdd185ada5b99c81c1bdbdb60621b604482015290519081900360640190fd5b60408051348152426020820152815133927f3a6614e80d02b57255cbb1f8305fbeca53d7e05a4b779d406279196608512925928290030190a2611645612382565b505050565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b815250306116bf82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611712576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280601081526020016f39ba30b334a234b9ba3934b13aba37b960811b8152503361111282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b815250306117fc82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461184f576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600e81526020016d737461666953757065724e6f646560901b815250336118c282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611915576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60006107606040518060400160405280600e81526020016d737461666953757065724e6f646560901b815250612026565b60008061197f6040518060400160405280601581526020017473746166695374616b696e67506f6f6c517565756560581b815250612026565b90506000816001600160a01b031663e60b40bf6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119bc57600080fd5b505afa1580156119d0573d6000803e3d6000fd5b505050506040513d60208110156119e657600080fd5b5051905060006119f46108ce565b9050808210611a0957600093505050506103cf565b611a138183612467565b93505050506103cf565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b81525030611a9282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611ae5576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600e81526020016d73746166694c696768744e6f646560901b81525033611b5882604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611bab576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60006107606040518060400160405280600e81526020016d73746166694c696768744e6f646560901b815250612026565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b81525030611c5182604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611ca4576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b611cac61146b565b611ce75760405162461bcd60e51b815260040180806020018281038252602a815260200180612582602a913960400191505060405180910390fd5b611cef610391565b341015611d2d5760405162461bcd60e51b815260040180806020018281038252603a8152602001806124c5603a913960400191505060405180910390fd5b6000611d59604051806040016040528060098152602001683922aa242a37b5b2b760b91b815250612026565b604080516317fe753f60e31b815234600482015233602482015290519192506001600160a01b0383169163bff3a9f89160448082019260009290919082900301818387803b158015611daa57600080fd5b505af1158015611dbe573d6000803e3d6000fd5b50506040805134815242602082015281513394507f7aa1a8eb998c779420645fc14513bf058edb347d95c2fc2e6845bdc22f88863193509081900390910190a2611645612382565b611e2d6040518060400160405280600581526020016437bbb732b960d91b815250336120cc565b80611e5a5750611e5a6040518060400160405280600581526020016430b236b4b760d91b815250336120cc565b611e99576040805162461bcd60e51b815260206004820152601b602482015260008051602061253f833981519152604482015290519081900360640190fd5b610ded6040518060400160405280601881526020017773657474696e67732e6465706f7369742e6d696e696d756d60401b81525082612175565b60008060019054906101000a90046001600160a01b03166001600160a01b031663bd02d0f5836040516020018082805190602001908083835b60208310611f2b5780518252601f199092019160209182019101611f0c565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611f9a57600080fd5b505afa158015611fae573d6000803e3d6000fd5b505050506040513d6020811015611fc457600080fd5b505192915050565b60008060019054906101000a90046001600160a01b03166001600160a01b03166321f8a721836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611f9a57600080fd5b60008061207483604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b90506001600160a01b0381166120c6576040805162461bcd60e51b815260206004820152601260248201527110dbdb9d1c9858dd081b9bdd08199bdd5b9960721b604482015290519081900360640190fd5b92915050565b600061216e838360405160200180806a6163636573732e726f6c6560a81b815250600b0183805190602001908083835b6020831061211b5780518252601f1990920191602091820191016120fc565b6001836020036101000a038019825116818451168082178552505050505050905001826001600160a01b031660601b8152601401925050506040516020818303038152906040528051906020012061240d565b9392505050565b600060019054906101000a90046001600160a01b03166001600160a01b031663e2a4853a836040516020018082805190602001908083835b602083106121cc5780518252601f1990920191602091820191016121ad565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b15801561224557600080fd5b505af1158015610cd2573d6000803e3d6000fd5b60008060019054906101000a90046001600160a01b03166001600160a01b0316637ae1cfca8360405160200180828051906020019080838360208310611f2b5780518252601f199092019160209182019101611f0c565b600060019054906101000a90046001600160a01b03166001600160a01b031663abfdcced836040516020018082805190602001908083835b602083106123075780518252601f1990920191602091820191016122e8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561224557600080fd5b60006123af6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b9050806001600160a01b03166398ea5fca346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156123ec57600080fd5b505af1158015612400573d6000803e3d6000fd5b5050505050610ded61097d565b60008060019054906101000a90046001600160a01b03166001600160a01b0316637ae1cfca836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611f9a57600080fd5b6000828211156124be576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe546865206465706f736974656420616d6f756e74206973206c657373207468616e20746865206d696e696d756d206465706f7369742073697a65496e76616c6964206f72206f7574646174656420636f6e747261637400000000636f6e74726163742e61646472657373000000000000000000000000000000004163636f756e74206973206e6f74206120737570657220757365720000000000496e73756666696369656e742062616c616e636520666f72207769746864726177616c4465706f7369747320696e746f205374616669206172652063757272656e746c792064697361626c6564a2646970667358221220181c7d9b7044f5321b27fd1cd61b34cf94cf8f3f465a3f92855f47aba506712b64736f6c63430007060033

Verified Source Code Full Match

Compiler: v0.7.6+commit.7338295f EVM: istanbul Optimization: Yes (200 runs)
StafiBase.sol 181 lines
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

import "./interfaces/storage/IStafiStorage.sol";

abstract contract StafiBase {

    // Version of the contract
    uint8 public version;

    // The main storage contract where primary persistant storage is maintained
    IStafiStorage stafiStorage = IStafiStorage(0);


    /**
    * @dev Throws if called by any sender that doesn't match a 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 trusted node
    */
    modifier onlyTrustedNode(address _nodeAddress) {
        require(getBool(keccak256(abi.encodePacked("node.trusted", _nodeAddress))), "Invalid trusted node");
        _;
    }
    
    /**
    * @dev Throws if called by any sender that isn't a super node
    */
    modifier onlySuperNode(address _nodeAddress) {
        require(getBool(keccak256(abi.encodePacked("node.super", _nodeAddress))), "Invalid super node");
        _;
    }


    /**
    * @dev Throws if called by any sender that isn't a registered staking pool
    */
    modifier onlyRegisteredStakingPool(address _stakingPoolAddress) {
        require(getBool(keccak256(abi.encodePacked("stakingpool.exists", _stakingPoolAddress))), "Invalid staking pool");
        _;
    }


    /**
    * @dev Throws if called by any account other than the owner.
    */
    modifier onlyOwner() {
        require(roleHas("owner", msg.sender), "Account is not the owner");
        _;
    }


    /**
    * @dev Modifier to scope access to admins
    */
    modifier onlyAdmin() {
        require(roleHas("admin", msg.sender), "Account is not an admin");
        _;
    }


    /**
    * @dev Modifier to scope access to admins
    */
    modifier onlySuperUser() {
        require(roleHas("owner", msg.sender) || roleHas("admin", msg.sender), "Account is not a super user");
        _;
    }


    /**
    * @dev Reverts if the address doesn't have this role
    */
    modifier onlyRole(string memory _role) {
        require(roleHas(_role, msg.sender), "Account does not match the specified role");
        _;
    }


    /// @dev Set the main Storage address
    constructor(address _stafiStorageAddress) {
        // Update the contract address
        stafiStorage = IStafiStorage(_stafiStorageAddress);
    }


    /// @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 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(keccak256(abi.encodePacked(contractName)) != keccak256(abi.encodePacked("")), "Contract not found");
        // Return
        return contractName;
    }


    /// @dev Storage get methods
    function getAddress(bytes32 _key) internal view returns (address) { return stafiStorage.getAddress(_key); }
    function getUint(bytes32 _key) internal view returns (uint256) { return stafiStorage.getUint(_key); }
    function getString(bytes32 _key) internal view returns (string memory) { return stafiStorage.getString(_key); }
    function getBytes(bytes32 _key) internal view returns (bytes memory) { return stafiStorage.getBytes(_key); }
    function getBool(bytes32 _key) internal view returns (bool) { return stafiStorage.getBool(_key); }
    function getInt(bytes32 _key) internal view returns (int256) { return stafiStorage.getInt(_key); }
    function getBytes32(bytes32 _key) internal view returns (bytes32) { return stafiStorage.getBytes32(_key); }
    function getAddressS(string memory _key) internal view returns (address) { return stafiStorage.getAddress(keccak256(abi.encodePacked(_key))); }
    function getUintS(string memory _key) internal view returns (uint256) { return stafiStorage.getUint(keccak256(abi.encodePacked(_key))); }
    function getStringS(string memory _key) internal view returns (string memory) { return stafiStorage.getString(keccak256(abi.encodePacked(_key))); }
    function getBytesS(string memory _key) internal view returns (bytes memory) { return stafiStorage.getBytes(keccak256(abi.encodePacked(_key))); }
    function getBoolS(string memory _key) internal view returns (bool) { return stafiStorage.getBool(keccak256(abi.encodePacked(_key))); }
    function getIntS(string memory _key) internal view returns (int256) { return stafiStorage.getInt(keccak256(abi.encodePacked(_key))); }
    function getBytes32S(string memory _key) internal view returns (bytes32) { return stafiStorage.getBytes32(keccak256(abi.encodePacked(_key))); }

    /// @dev Storage set methods
    function setAddress(bytes32 _key, address _value) internal { stafiStorage.setAddress(_key, _value); }
    function setUint(bytes32 _key, uint256 _value) internal { stafiStorage.setUint(_key, _value); }
    function setString(bytes32 _key, string memory _value) internal { stafiStorage.setString(_key, _value); }
    function setBytes(bytes32 _key, bytes memory _value) internal { stafiStorage.setBytes(_key, _value); }
    function setBool(bytes32 _key, bool _value) internal { stafiStorage.setBool(_key, _value); }
    function setInt(bytes32 _key, int256 _value) internal { stafiStorage.setInt(_key, _value); }
    function setBytes32(bytes32 _key, bytes32 _value) internal { stafiStorage.setBytes32(_key, _value); }
    function setAddressS(string memory _key, address _value) internal { stafiStorage.setAddress(keccak256(abi.encodePacked(_key)), _value); }
    function setUintS(string memory _key, uint256 _value) internal { stafiStorage.setUint(keccak256(abi.encodePacked(_key)), _value); }
    function setStringS(string memory _key, string memory _value) internal { stafiStorage.setString(keccak256(abi.encodePacked(_key)), _value); }
    function setBytesS(string memory _key, bytes memory _value) internal { stafiStorage.setBytes(keccak256(abi.encodePacked(_key)), _value); }
    function setBoolS(string memory _key, bool _value) internal { stafiStorage.setBool(keccak256(abi.encodePacked(_key)), _value); }
    function setIntS(string memory _key, int256 _value) internal { stafiStorage.setInt(keccak256(abi.encodePacked(_key)), _value); }
    function setBytes32S(string memory _key, bytes32 _value) internal { stafiStorage.setBytes32(keccak256(abi.encodePacked(_key)), _value); }

    /// @dev Storage delete methods
    function deleteAddress(bytes32 _key) internal { stafiStorage.deleteAddress(_key); }
    function deleteUint(bytes32 _key) internal { stafiStorage.deleteUint(_key); }
    function deleteString(bytes32 _key) internal { stafiStorage.deleteString(_key); }
    function deleteBytes(bytes32 _key) internal { stafiStorage.deleteBytes(_key); }
    function deleteBool(bytes32 _key) internal { stafiStorage.deleteBool(_key); }
    function deleteInt(bytes32 _key) internal { stafiStorage.deleteInt(_key); }
    function deleteBytes32(bytes32 _key) internal { stafiStorage.deleteBytes32(_key); }
    function deleteAddressS(string memory _key) internal { stafiStorage.deleteAddress(keccak256(abi.encodePacked(_key))); }
    function deleteUintS(string memory _key) internal { stafiStorage.deleteUint(keccak256(abi.encodePacked(_key))); }
    function deleteStringS(string memory _key) internal { stafiStorage.deleteString(keccak256(abi.encodePacked(_key))); }
    function deleteBytesS(string memory _key) internal { stafiStorage.deleteBytes(keccak256(abi.encodePacked(_key))); }
    function deleteBoolS(string memory _key) internal { stafiStorage.deleteBool(keccak256(abi.encodePacked(_key))); }
    function deleteIntS(string memory _key) internal { stafiStorage.deleteInt(keccak256(abi.encodePacked(_key))); }
    function deleteBytes32S(string memory _key) internal { stafiStorage.deleteBytes32(keccak256(abi.encodePacked(_key))); }


    /**
    * @dev Check if an address has this role
    */
    function roleHas(string memory _role, address _address) internal view returns (bool) {
        return getBool(keccak256(abi.encodePacked("access.role", _role, _address)));
    }

}
DepositType.sol 13 lines
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

// Represents the type of deposits
enum DepositType {
    None,    // Marks an invalid deposit type
    FOUR,    // Require 4 ETH from the node operator to be matched with 28 ETH from user deposits
    EIGHT,   // Require 8 ETH from the node operator to be matched with 24 ETH from user deposits
    TWELVE,  // Require 12 ETH from the node operator to be matched with 20 ETH from user deposits
    SIXTEEN,  // Require 16 ETH from the node operator to be matched with 16 ETH from user deposits
    Empty    // Require 0 ETH from the node operator to be matched with 32 ETH from user deposits (trusted nodes only)
}
IStafiEther.sol 9 lines
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

interface IStafiEther {
    function balanceOf(address _contractAddress) external view returns (uint256);
    function depositEther() external payable;
    function withdrawEther(uint256 _amount) external;
}
StakingPoolStatus.sol 12 lines
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

// Represents a stakingpool's status within the network
enum StakingPoolStatus {
    Initialized,    // The stakingpool has been initialized and is awaiting a deposit of user ETH
    Prelaunch,      // The stakingpool has enough ETH to begin staking and is awaiting launch by the node
    Staking,        // The stakingpool is currently staking
    Withdrawn,   // The stakingpool has been withdrawn from by the node
    Dissolved       // The stakingpool has been dissolved and its user deposited ETH has been returned to the deposit pool
}
StafiUserDeposit.sol 238 lines
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

import "@openzeppelin/contracts/math/SafeMath.sol";
import "../StafiBase.sol";
import "../interfaces/IStafiEther.sol";
import "../interfaces/IStafiEtherWithdrawer.sol";
import "../interfaces/deposit/IStafiUserDeposit.sol";
import "../interfaces/pool/IStafiStakingPool.sol";
import "../interfaces/pool/IStafiStakingPoolQueue.sol";
import "../interfaces/token/IRETHToken.sol";
import "../interfaces/node/IStafiSuperNode.sol";
import "../interfaces/node/IStafiLightNode.sol";
import "../interfaces/withdraw/IStafiWithdraw.sol";

// Accepts user deposits and mints rETH; handles assignment of deposited ETH to pools
contract StafiUserDeposit is StafiBase, IStafiUserDeposit, IStafiEtherWithdrawer {

    // Libs
    using SafeMath for uint256;

    // Events
    event DepositReceived(address indexed from, uint256 amount, uint256 time);
    event DepositRecycled(address indexed from, uint256 amount, uint256 time);
    event DepositAssigned(address indexed stakingPool, uint256 amount, uint256 time);
    event ExcessWithdrawn(address indexed to, uint256 amount, uint256 time);

    // Construct
    constructor(address _stafiStorageAddress) StafiBase(_stafiStorageAddress) {
        version = 1;
        // Initialize settings on deployment
        if (!getBoolS("settings.user.deposit.init")) {
            // Apply settings
            setDepositEnabled(true);
            setAssignDepositsEnabled(true);
            setMinimumDeposit(0.01 ether);
            // setMaximumDepositPoolSize(100000 ether);
            setMaximumDepositAssignments(2);
            // Settings initialized
            setBoolS("settings.user.deposit.init", true);
        }
    }

    // Current deposit pool balance
    function getBalance() override public view returns (uint256) {
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        return stafiEther.balanceOf(address(this));
    }

    // Excess deposit pool balance (in excess of stakingPool queue capacity)
    function getExcessBalance() override public view returns (uint256) {
        // Get stakingPool queue capacity
        IStafiStakingPoolQueue stafiStakingPoolQueue = IStafiStakingPoolQueue(getContractAddress("stafiStakingPoolQueue"));
        uint256 stakingPoolCapacity = stafiStakingPoolQueue.getEffectiveCapacity();
        // Calculate and return
        uint256 balance = getBalance();
        if (stakingPoolCapacity >= balance) { return 0; }
        else { return balance.sub(stakingPoolCapacity); }
    }

    // Receive a ether withdrawal
    // Only accepts calls from the StafiEther contract
    function receiveEtherWithdrawal() override external payable onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("stafiEther", msg.sender) {}

    // Accept a deposit from a user
    function deposit() override external payable onlyLatestContract("stafiUserDeposit", address(this)) {
        // Check deposit settings
        require(getDepositEnabled(), "Deposits into Stafi are currently disabled");
        require(msg.value >= getMinimumDeposit(), "The deposited amount is less than the minimum deposit size");
        // Load contracts
        IRETHToken rETHToken = IRETHToken(getContractAddress("rETHToken"));
        // Mint rETH to user account
        rETHToken.userMint(msg.value, msg.sender);
        // Emit deposit received event
        emit DepositReceived(msg.sender, msg.value, block.timestamp);
        // Process deposit
        processDeposit();
    }

    // Recycle a deposit from a dissolved stakingPool
    // Only accepts calls from registered stakingPools
    function recycleDissolvedDeposit() override external payable onlyLatestContract("stafiUserDeposit", address(this)) onlyRegisteredStakingPool(msg.sender) {
        // Emit deposit recycled event
        emit DepositRecycled(msg.sender, msg.value, block.timestamp);
        // Process deposit
        processDeposit();
    }

    // Recycle a deposit from fee collector
    // Only accepts calls from registered stafiDistributor
    function recycleDistributorDeposit() override external payable onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("stafiDistributor", msg.sender) {
        // Emit deposit recycled event
        emit DepositRecycled(msg.sender, msg.value, block.timestamp);
        // Process deposit
        processDeposit();
    }
    
    // Recycle a deposit from withdraw pool
    // Only accepts calls from registered stafiWithdraw
    function recycleWithdrawDeposit() override external payable onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("stafiWithdraw", msg.sender) {
        // Emit deposit recycled event
        emit DepositRecycled(msg.sender, msg.value, block.timestamp);
        // Process deposit
        processDeposit();
    }

    // Process a deposit
    function processDeposit() private {
        // Load contracts
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        // Transfer ETH to stafiEther
        stafiEther.depositEther{value: msg.value}();
        // Assign deposits if enabled
        assignDeposits();
    }

    // Assign deposits to available stakingPools
    function assignDeposits() override public onlyLatestContract("stafiUserDeposit", address(this)) {
        // Check deposit settings
        if (!getAssignDepositsEnabled()) {
            return;
        }

        // Load contracts
        IStafiStakingPoolQueue stafiStakingPoolQueue = IStafiStakingPoolQueue(getContractAddress("stafiStakingPoolQueue"));
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        // Assign deposits
        uint256 maximumDepositAssignments = getMaximumDepositAssignments();
        for (uint256 i = 0; i < maximumDepositAssignments; ++i) {
            // Get & check next available staking pool capacity
            uint256 stakingPoolCapacity = stafiStakingPoolQueue.getNextCapacity();
            if (stakingPoolCapacity == 0 || getBalance() < stakingPoolCapacity) { break; }
            // Dequeue next available staking pool
            address stakingPoolAddress = stafiStakingPoolQueue.dequeueStakingPool();
            IStafiStakingPool stakingPool = IStafiStakingPool(stakingPoolAddress);
            // Withdraw ETH from stafiEther
            stafiEther.withdrawEther(stakingPoolCapacity);
            // Assign deposit to staking pool
            stakingPool.userDeposit{value: stakingPoolCapacity}();
            // Emit deposit assigned event
            emit DepositAssigned(stakingPoolAddress, stakingPoolCapacity, block.timestamp);
        }
    }

    // Withdraw excess deposit pool balance for rETH collateral
    function withdrawExcessBalance(uint256 _amount) override external onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("rETHToken", msg.sender) {
        // Load contracts
        IRETHToken rETHToken = IRETHToken(getContractAddress("rETHToken"));
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        // Check amount
        require(_amount <= getBalance(), "Insufficient balance for withdrawal");
        // Withdraw ETH from vault
        stafiEther.withdrawEther(_amount);
        // Transfer to rETH contract
        rETHToken.depositExcess{value: _amount}();
        // Emit excess withdrawn event
        emit ExcessWithdrawn(msg.sender, _amount, block.timestamp);
    }

    // Withdraw excess deposit pool balance for super node
    function withdrawExcessBalanceForSuperNode(uint256 _amount) override external onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("stafiSuperNode", msg.sender) {
        // Load contracts
        IStafiSuperNode superNode = IStafiSuperNode(getContractAddress("stafiSuperNode"));
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        // Check amount
        require(_amount <= getBalance(), "Insufficient balance for withdrawal");
        // Withdraw ETH from vault
        stafiEther.withdrawEther(_amount);
        // Transfer to superNode contract
        superNode.depositEth{value: _amount}();
        // Emit excess withdrawn event
        emit ExcessWithdrawn(msg.sender, _amount, block.timestamp);
    }
    
    // Withdraw excess deposit pool balance for light node
    function withdrawExcessBalanceForLightNode(uint256 _amount) override external onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("stafiLightNode", msg.sender) {
        // Load contracts
        IStafiLightNode lightNode = IStafiLightNode(getContractAddress("stafiLightNode"));
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        // Check amount
        require(_amount <= getBalance(), "Insufficient balance for withdrawal");
        // Withdraw ETH from vault
        stafiEther.withdrawEther(_amount);
        // Transfer to superNode contract
        lightNode.depositEth{value: _amount}();
        // Emit excess withdrawn event
        emit ExcessWithdrawn(msg.sender, _amount, block.timestamp);
    }
    
    // Withdraw excess deposit pool balance for light node
    function withdrawExcessBalanceForWithdraw(uint256 _amount) override external onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("stafiWithdraw", msg.sender) {
        // Load contracts
        IStafiWithdraw stafiWithdraw = IStafiWithdraw(getContractAddress("stafiWithdraw"));
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        // Check amount
        require(_amount <= getBalance(), "Insufficient balance for withdrawal");
        // Withdraw ETH from vault
        stafiEther.withdrawEther(_amount);
        // Transfer to superNode contract
        stafiWithdraw.depositEth{value: _amount}();
        // Emit excess withdrawn event
        emit ExcessWithdrawn(msg.sender, _amount, block.timestamp);
    }

    // Deposits currently enabled
    function getDepositEnabled() public view returns (bool) {
        return getBoolS("settings.deposit.enabled");
    }
    function setDepositEnabled(bool _value) public onlySuperUser {
        setBoolS("settings.deposit.enabled", _value);
    }

    // Deposit assignments currently enabled
    function getAssignDepositsEnabled() public view returns (bool) {
        return getBoolS("settings.deposit.assign.enabled");
    }
    function setAssignDepositsEnabled(bool _value) public onlySuperUser {
        setBoolS("settings.deposit.assign.enabled", _value);
    }

    // Minimum deposit size
    function getMinimumDeposit() public view returns (uint256) {
        return getUintS("settings.deposit.minimum");
    }
    function setMinimumDeposit(uint256 _value) public onlySuperUser {
        setUintS("settings.deposit.minimum", _value);
    }

    // The maximum number of deposit assignments to perform at once
    function getMaximumDepositAssignments() public view returns (uint256) {
        return getUintS("settings.deposit.assign.maximum");
    }
    function setMaximumDepositAssignments(uint256 _value) public onlySuperUser {
        setUintS("settings.deposit.assign.maximum", _value);
    }

}
SafeMath.sol 214 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}
IRETHToken.sol 15 lines
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

interface IRETHToken {
    function getEthValue(uint256 _rethAmount) external view returns (uint256);
    function getRethValue(uint256 _ethAmount) external view returns (uint256);
    function getExchangeRate() external view returns (uint256);
    function getTotalCollateral() external view returns (uint256);
    function getCollateralRate() external view returns (uint256);
    function depositRewards() external payable;
    function depositExcess() external payable;
    function userMint(uint256 _ethAmount, address _to) external;
    function userBurn(uint256 _rethAmount) external;
}
IStafiLightNode.sol 16 lines
pragma solidity 0.7.6;
pragma abicoder v2;
// SPDX-License-Identifier: GPL-3.0-only

interface IStafiLightNode {
    function depositEth() external payable;
    function deposit(bytes[] calldata _validatorPubkeys, bytes[] calldata _validatorSignatures, bytes32[] calldata _depositDataRoots) external payable;
    function stake(bytes[] calldata _validatorPubkeys, bytes[] calldata _validatorSignatures, bytes32[] calldata _depositDataRoots) external;
    function offBoard(bytes calldata _validatorPubkey) external;
    function provideNodeDepositToken(bytes calldata _validatorPubkey) external payable;
    function withdrawNodeDepositToken(bytes calldata _validatorPubkey) external;
    function getLightNodePubkeyCount(address _nodeAddress) external view returns (uint256);
    function getLightNodePubkeyAt(address _nodeAddress, uint256 _index) external view returns (bytes memory);
    function getLightNodePubkeyStatus(bytes calldata _validatorPubkey) external view returns (uint256);
    function voteWithdrawCredentials(bytes[] calldata _pubkey, bool[] calldata _match) external;
}
IStafiSuperNode.sol 13 lines
pragma solidity 0.7.6;
pragma abicoder v2;
// SPDX-License-Identifier: GPL-3.0-only

interface IStafiSuperNode {
    function depositEth() external payable;
    function deposit(bytes[] calldata _validatorPubkeys, bytes[] calldata _validatorSignatures, bytes32[] calldata _depositDataRoots) external;
    function stake(bytes[] calldata _validatorPubkeys, bytes[] calldata _validatorSignatures, bytes32[] calldata _depositDataRoots) external;
    function getSuperNodePubkeyCount(address _nodeAddress) external view returns (uint256);
    function getSuperNodePubkeyAt(address _nodeAddress, uint256 _index) external view returns (bytes memory);
    function getSuperNodePubkeyStatus(bytes calldata _validatorPubkey) external view returns (uint256);
    function voteWithdrawCredentials(bytes[] calldata _pubkey, bool[] calldata _match) external;
}
IStafiEtherWithdrawer.sol 7 lines
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

interface IStafiEtherWithdrawer {
    function receiveEtherWithdrawal() external payable;
}
IStafiStorage.sol 34 lines
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

interface IStafiStorage {

    // 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;

}
IStafiStakingPool.sol 32 lines
pragma solidity 0.7.6;
// SPDX-License-Identifier: GPL-3.0-only

import "../../types/DepositType.sol";
import "../../types/StakingPoolStatus.sol";

interface IStafiStakingPool {
    function initialise(address _nodeAddress, DepositType _depositType) external;
    function getStatus() external view returns (StakingPoolStatus);
    function getStatusBlock() external view returns (uint256);
    function getStatusTime() external view returns (uint256);
    function getWithdrawalCredentialsMatch() external view returns (bool);
    function getDepositType() external view returns (DepositType);
    function getNodeAddress() external view returns (address);
    function getNodeFee() external view returns (uint256);
    function getNodeDepositBalance() external view returns (uint256);
    function getNodeRefundBalance() external view returns (uint256);
    function getNodeDepositAssigned() external view returns (bool);
    function getNodeCommonlyRefunded() external view returns (bool);
    function getNodeTrustedRefunded() external view returns (bool);
    function getUserDepositBalance() external view returns (uint256);
    function getUserDepositAssigned() external view returns (bool);
    function getUserDepositAssignedTime() external view returns (uint256);
    function getPlatformDepositBalance() external view returns (uint256);
    function nodeDeposit(bytes calldata _validatorPubkey, bytes calldata _validatorSignature, bytes32 _depositDataRoot) external payable;
    function userDeposit() external payable;
    function stake(bytes calldata _validatorSignature, bytes32 _depositDataRoot)  external;
    function refund() external;
    function dissolve() external;
    function close() external;
    function voteWithdrawCredentials() external;
}
IStafiWithdraw.sol 35 lines
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

interface IStafiWithdraw {
    // user

    function unstake(uint256 _rEthAmount) external;

    function withdraw(uint256[] calldata _withdrawIndexList) external;

    // ejector
    function notifyValidatorExit(
        uint256 _withdrawCycle,
        uint256 _ejectedStartWithdrawCycle,
        uint256[] calldata _validatorIndex
    ) external;

    // voter
    function distributeWithdrawals(
        uint256 _dealedHeight,
        uint256 _userAmount,
        uint256 _nodeAmount,
        uint256 _platformAmount,
        uint256 _maxClaimableWithdrawIndex
    ) external;

    function reserveEthForWithdraw(uint256 _withdrawCycle) external;

    function depositEth() external payable;

    function getUnclaimedWithdrawalsOfUser(address user) external view returns (uint256[] memory);

    function getEjectedValidatorsAtCycle(uint256 cycle) external view returns (uint256[] memory);
}
IStafiUserDeposit.sol 17 lines
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

interface IStafiUserDeposit {
    function getBalance() external view returns (uint256);
    function getExcessBalance() external view returns (uint256);
    function deposit() external payable;
    function recycleDissolvedDeposit() external payable;
    function recycleWithdrawDeposit() external payable;
    function recycleDistributorDeposit() external payable;
    function assignDeposits() external;
    function withdrawExcessBalance(uint256 _amount) external;
    function withdrawExcessBalanceForSuperNode(uint256 _amount) external;
    function withdrawExcessBalanceForLightNode(uint256 _amount) external;
    function withdrawExcessBalanceForWithdraw(uint256 _amount) external;
}
IStafiStakingPoolQueue.sol 16 lines
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

import "../../types/DepositType.sol";

interface IStafiStakingPoolQueue {
    function getTotalLength() external view returns (uint256);
    function getLength(DepositType _depositType) external view returns (uint256);
    function getTotalCapacity() external view returns (uint256);
    function getEffectiveCapacity() external view returns (uint256);
    function getNextCapacity() external view returns (uint256);
    function enqueueStakingPool(DepositType _depositType, address _stakingPool) external;
    function dequeueStakingPool() external returns (address);
    function removeStakingPool() external;
}

Read Contract

getAssignDepositsEnabled 0x47fa434a → bool
getBalance 0x12065fe0 → uint256
getDepositEnabled 0x6ada7847 → bool
getExcessBalance 0x888b042f → uint256
getMaximumDepositAssignments 0x3b474a65 → uint256
getMinimumDeposit 0x035cf142 → uint256
version 0x54fd4d50 → uint8

Write Contract 14 functions

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

assignDeposits 0x27c8f193
No parameters
deposit 0xd0e30db0
No parameters
receiveEtherWithdrawal 0x0a019eaf
No parameters
recycleDissolvedDeposit 0x72f5158d
No parameters
recycleDistributorDeposit 0x7c697e74
No parameters
recycleWithdrawDeposit 0x5fd58f0d
No parameters
setAssignDepositsEnabled 0x5cb17a90
bool _value
setDepositEnabled 0x5b17d04b
bool _value
setMaximumDepositAssignments 0x3fa9c18d
uint256 _value
setMinimumDeposit 0xe78ec42e
uint256 _value
withdrawExcessBalance 0x63a5db9e
uint256 _amount
withdrawExcessBalanceForLightNode 0xcc88c3c8
uint256 _amount
withdrawExcessBalanceForSuperNode 0x8554913b
uint256 _amount
withdrawExcessBalanceForWithdraw 0x0c37d2dc
uint256 _amount

Recent Transactions

No transactions found for this address