Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- IncentivePoolTreasury
- Optimization enabled
- true
- Compiler version
- v0.7.6+commit.7338295f
- Optimization runs
- 200
- Verified at
- 2022-07-13T21:02:35.617732Z
./contracts/genesis/implementation/IncentivePoolTreasury.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "../../governance/implementation/GovernedAtGenesis.sol"; /** * @title Incentive pool treasury * @notice A genesis contract which holds the entire treasury for the incentive pool. * It enables limited flow of funds to the incentive pool. */ contract IncentivePoolTreasury is GovernedAtGenesis { // How often can incentive pool pull funds - 23 hours constant uint256 internal constant MAX_PULL_FREQUENCY_SEC = 23 hours; uint256 public constant MAX_DAILY_PULL_AMOUNT_WEI = 25000000 ether; // Errors string internal constant ERR_INCENTIVE_POOL_ONLY = "incentive pool only"; string internal constant ERR_TOO_OFTEN = "too often"; string internal constant ERR_TOO_MUCH = "too much"; string internal constant ERR_PULL_FAILED = "pull failed"; string internal constant ERR_ALREADY_SET = "already set"; // Storage address public incentivePool; uint256 public lastPullTs; modifier onlyIncentivePool { require (msg.sender == incentivePool, ERR_INCENTIVE_POOL_ONLY); _; } /** * @dev This constructor should contain no code as this contract is pre-loaded into the genesis block. * The super constructor is called for testing convenience. */ constructor() GovernedAtGenesis(address(0)) { /* empty block */ } /** * @notice Sets incentive pool contract address. * @param _incentivePool Incentive pool contract address. */ function setIncentivePoolContract(address _incentivePool) external onlyGovernance { require(incentivePool == address(0), ERR_ALREADY_SET); incentivePool = _incentivePool; } /** * @notice Moves funds to the incentive pool contract (once per day) * @param _amountWei The amount of wei to pull to incentive pool contract */ function pullFunds(uint256 _amountWei) external onlyIncentivePool { // this also serves as reentrancy guard, since any re-entry will happen in the same block require(lastPullTs + MAX_PULL_FREQUENCY_SEC <= block.timestamp, ERR_TOO_OFTEN); require(_amountWei <= MAX_DAILY_PULL_AMOUNT_WEI, ERR_TOO_MUCH); lastPullTs = block.timestamp; /* solhint-disable avoid-low-level-calls */ //slither-disable-next-line arbitrary-send (bool success, ) = msg.sender.call{value: _amountWei}(""); /* solhint-enable avoid-low-level-calls */ require(success, ERR_PULL_FAILED); } }
./contracts/governance/implementation/GovernedAtGenesis.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "./GovernedBase.sol"; /** * @title Governed At Genesis * @dev This contract enforces a fixed governance address when the constructor * is not executed on a contract (for instance when directly loaded to the genesis block). * This is required to fix governance on a contract when the network starts, at such point * where theoretically no accounts yet exist, and leaving it ungoverned could result in a race * to claim governance by an unauthorized address. **/ contract GovernedAtGenesis is GovernedBase { constructor(address _governance) GovernedBase(_governance) { } /** * @notice Set governance to a fixed address when constructor is not called. **/ function initialiseFixedAddress() public virtual returns (address) { address governanceAddress = address(0xfffEc6C83c8BF5c3F4AE0cCF8c45CE20E4560BD7); super.initialise(governanceAddress); return governanceAddress; } /** * @notice Disallow initialise to be called * @param _governance The governance address for initial claiming **/ // solhint-disable-next-line no-unused-vars function initialise(address _governance) public override pure { assert(false); } }
./contracts/governance/implementation/GovernedBase.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "../../userInterfaces/IGovernanceSettings.sol"; /** * @title Governed Base * @notice This abstract base class defines behaviors for a governed contract. * @dev This class is abstract so that specific behaviors can be defined for the constructor. * Contracts should not be left ungoverned, but not all contract will have a constructor * (for example those pre-defined in genesis). **/ abstract contract GovernedBase { struct TimelockedCall { uint256 allowedAfterTimestamp; bytes encodedCall; } // solhint-disable-next-line const-name-snakecase IGovernanceSettings public constant governanceSettings = IGovernanceSettings(0x1000000000000000000000000000000000000007); address private initialGovernance; bool private initialised; bool public productionMode; bool private executing; mapping(bytes4 => TimelockedCall) public timelockedCalls; event GovernanceCallTimelocked(bytes4 selector, uint256 allowedAfterTimestamp, bytes encodedCall); event TimelockedGovernanceCallExecuted(bytes4 selector, uint256 timestamp); event TimelockedGovernanceCallCanceled(bytes4 selector, uint256 timestamp); event GovernanceInitialised(address initialGovernance); event GovernedProductionModeEntered(address governanceSettings); modifier onlyGovernance { if (executing || !productionMode) { _beforeExecute(); _; } else { _recordTimelockedCall(msg.data); } } modifier onlyImmediateGovernance () { _checkOnlyGovernance(); _; } constructor(address _initialGovernance) { if (_initialGovernance != address(0)) { initialise(_initialGovernance); } } /** * @notice Execute the timelocked governance calls once the timelock period expires. * @dev Only executor can call this method. * @param _selector The method selector (only one timelocked call per method is stored). */ function executeGovernanceCall(bytes4 _selector) external { require(governanceSettings.isExecutor(msg.sender), "only executor"); TimelockedCall storage call = timelockedCalls[_selector]; require(call.allowedAfterTimestamp != 0, "timelock: invalid selector"); require(block.timestamp >= call.allowedAfterTimestamp, "timelock: not allowed yet"); bytes memory encodedCall = call.encodedCall; delete timelockedCalls[_selector]; executing = true; //solhint-disable-next-line avoid-low-level-calls (bool success,) = address(this).call(encodedCall); executing = false; emit TimelockedGovernanceCallExecuted(_selector, block.timestamp); _passReturnOrRevert(success); } /** * Cancel a timelocked governance call before it has been executed. * @dev Only governance can call this method. * @param _selector The method selector. */ function cancelGovernanceCall(bytes4 _selector) external onlyImmediateGovernance { require(timelockedCalls[_selector].allowedAfterTimestamp != 0, "timelock: invalid selector"); emit TimelockedGovernanceCallCanceled(_selector, block.timestamp); delete timelockedCalls[_selector]; } /** * Enter the production mode after all the initial governance settings have been set. * This enables timelocks and the governance is afterwards obtained by calling * governanceSettings.getGovernanceAddress(). */ function switchToProductionMode() external { _checkOnlyGovernance(); require(!productionMode, "already in production mode"); initialGovernance = address(0); productionMode = true; emit GovernedProductionModeEntered(address(governanceSettings)); } /** * @notice Initialize the governance address if not first initialized. */ function initialise(address _initialGovernance) public virtual { require(initialised == false, "initialised != false"); initialised = true; initialGovernance = _initialGovernance; emit GovernanceInitialised(_initialGovernance); } /** * Returns the current effective governance address. */ function governance() public view returns (address) { return productionMode ? governanceSettings.getGovernanceAddress() : initialGovernance; } function _beforeExecute() private { if (executing) { // can only be run from executeGovernanceCall(), where we check that only executor can call // make sure nothing else gets executed, even in case of reentrancy assert(msg.sender == address(this)); executing = false; } else { // must be called with: productionMode=false // must check governance in this case _checkOnlyGovernance(); } } function _recordTimelockedCall(bytes calldata _data) private { _checkOnlyGovernance(); bytes4 selector; //solhint-disable-next-line no-inline-assembly assembly { selector := calldataload(_data.offset) } uint256 timelock = governanceSettings.getTimelock(); uint256 allowedAt = block.timestamp + timelock; timelockedCalls[selector] = TimelockedCall({ allowedAfterTimestamp: allowedAt, encodedCall: _data }); emit GovernanceCallTimelocked(selector, allowedAt, _data); } function _checkOnlyGovernance() private view { require(msg.sender == governance(), "only governance"); } function _passReturnOrRevert(bool _success) private pure { // pass exact return or revert data - needs to be done in assembly //solhint-disable-next-line no-inline-assembly assembly { let size := returndatasize() let ptr := mload(0x40) mstore(0x40, add(ptr, size)) returndatacopy(ptr, 0, size) if _success { return(ptr, size) } revert(ptr, size) } } }
./contracts/userInterfaces/IGovernanceSettings.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; /** * A special contract that holds Flare governance address. * This contract enables updating governance address and timelock only by hard forking the network, * meaning only by updating validator code. */ interface IGovernanceSettings { /** * Get the governance account address. * The governance address can only be changed by a hardfork. */ function getGovernanceAddress() external view returns (address); /** * Get the time in seconds that must pass between a governance call and execution. * The timelock value can only be changed by a hardfork. */ function getTimelock() external view returns (uint256); /** * Get the addresses of the accounts that are allowed to execute the timelocked governance calls * once the timelock period expires. * Executors can be changed without a hardfork, via a normal governance call. */ function getExecutors() external view returns (address[] memory); /** * Check whether an address is one of the executors. */ function isExecutor(address _address) external view returns (bool); }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"GovernanceCallTimelocked","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"allowedAfterTimestamp","internalType":"uint256","indexed":false},{"type":"bytes","name":"encodedCall","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"GovernanceInitialised","inputs":[{"type":"address","name":"initialGovernance","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"GovernedProductionModeEntered","inputs":[{"type":"address","name":"governanceSettings","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"TimelockedGovernanceCallCanceled","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TimelockedGovernanceCallExecuted","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_DAILY_PULL_AMOUNT_WEI","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancelGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"executeGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"governance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IGovernanceSettings"}],"name":"governanceSettings","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"incentivePool","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[],"name":"initialise","inputs":[{"type":"address","name":"_governance","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"initialiseFixedAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastPullTs","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"productionMode","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pullFunds","inputs":[{"type":"uint256","name":"_amountWei","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setIncentivePoolContract","inputs":[{"type":"address","name":"_incentivePool","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"switchToProductionMode","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"allowedAfterTimestamp","internalType":"uint256"},{"type":"bytes","name":"encodedCall","internalType":"bytes"}],"name":"timelockedCalls","inputs":[{"type":"bytes4","name":"","internalType":"bytes4"}]}]
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c806397249db71161008c578063d4456c9711610066578063d4456c9714610269578063e17f212e1461028f578063ec8d8777146102ab578063f5a98383146102c8576100ea565b806397249db7146102335780639d6a890f1461023b578063c9f960eb14610261576100ea565b80635ff27079116100c85780635ff270791461013557806362354e031461015e57806367fc40291461016657806374e6310e1461018d576100ea565b8063100223bb146100ef5780634841422e146101095780635aa6e6751461012d575b600080fd5b6100f76102d0565b60408051918252519081900360200190f35b6101116102d6565b604080516001600160a01b039092168252519081900360200190f35b6101116102e5565b61015c6004803603602081101561014b57600080fd5b50356001600160e01b03191661037a565b005b6101116106cf565b61015c6004803603602081101561017c57600080fd5b50356001600160e01b0319166106da565b6101b4600480360360208110156101a357600080fd5b50356001600160e01b0319166107c2565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156101f75781810151838201526020016101df565b50505050905090810190601f1680156102245780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b6100f7610868565b61015c6004803603602081101561025157600080fd5b50356001600160a01b0316610877565b61011161087c565b61015c6004803603602081101561027f57600080fd5b50356001600160a01b031661089c565b6102976109af565b604080519115158252519081900360200190f35b61015c600480360360208110156102c157600080fd5b50356109bf565b61015c610bf8565b60035481565b6002546001600160a01b031681565b60008054600160a81b900460ff16610308576000546001600160a01b0316610375565b60076001609c1b016001600160a01b031663732524946040518163ffffffff1660e01b815260040160206040518083038186803b15801561034857600080fd5b505afa15801561035c573d6000803e3d6000fd5b505050506040513d602081101561037257600080fd5b50515b905090565b60408051630debfda360e41b8152336004820152905160076001609c1b019163debfda30916024808301926020929190829003018186803b1580156103be57600080fd5b505afa1580156103d2573d6000803e3d6000fd5b505050506040513d60208110156103e857600080fd5b505161042b576040805162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b604482015290519081900360640190fd5b6001600160e01b0319811660009081526001602052604090208054610497576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b80544210156104ed576040805162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f7765642079657400000000000000604482015290519081900360640190fd5b6000816001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105875780601f1061055c57610100808354040283529160200191610587565b820191906000526020600020905b81548152906001019060200180831161056a57829003601f168201915b5050506001600160e01b03198616600090815260016020819052604082208281559495509092506105bb9150830182610fa1565b50506000805460ff60b01b1916600160b01b178155604051825130918491819060208401908083835b602083106106035780518252601f1990920191602091820191016105e4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610665576040519150601f19603f3d011682016040523d82523d6000602084013e61066a565b606091505b50506000805460ff60b01b19169055604080516001600160e01b03198716815242602082015281519293507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438929081900390910190a16106c981610cb2565b50505050565b60076001609c1b0181565b6106e2610ccf565b6001600160e01b0319811660009081526001602052604090205461074d576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b604080516001600160e01b03198316815242602082015281517f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8929181900390910190a16001600160e01b031981166000908152600160208190526040822082815591906107bd90830182610fa1565b505050565b600160208181526000928352604092839020805481840180548651600296821615610100026000190190911695909504601f8101859004850286018501909652858552909491939290919083018282801561085e5780601f106108335761010080835404028352916020019161085e565b820191906000526020600020905b81548152906001019060200180831161084157829003601f168201915b5050505050905082565b6a14adf4b7320334b900000081565bfe5b50565b600073fffec6c83c8bf5c3f4ae0ccf8c45ce20e4560bd761037581610d30565b600054600160b01b900460ff16806108be5750600054600160a81b900460ff16155b156109a4576108cb610de9565b60025460408051808201909152600b81526a185b1c9958591e481cd95d60aa1b6020820152906001600160a01b0316156109835760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610948578181015183820152602001610930565b50505050905090810190601f1680156109755780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600280546001600160a01b0319166001600160a01b038316179055610879565b610879600036610e1e565b600054600160a81b900460ff1681565b600254604080518082019091526013815272696e63656e7469766520706f6f6c206f6e6c7960681b6020820152906001600160a01b03163314610a435760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610948578181015183820152602001610930565b504262014370600354011115604051806040016040528060098152602001683a37b79037b33a32b760b91b81525090610abd5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610948578181015183820152602001610930565b506040805180820190915260088152670e8dede40daeac6d60c31b60208201526a14adf4b7320334b9000000821115610b375760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610948578181015183820152602001610930565b5042600355604051600090339083908381818185875af1925050503d8060008114610b7e576040519150601f19603f3d011682016040523d82523d6000602084013e610b83565b606091505b50509050806040518060400160405280600b81526020016a1c1d5b1b0819985a5b195960aa1b815250906107bd5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610948578181015183820152602001610930565b610c00610ccf565b600054600160a81b900460ff1615610c5f576040805162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f6465000000000000604482015290519081900360640190fd5b60008054600161ff0160a01b031916600160a81b1790556040805160076001609c1b01815290517f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9181900360200190a1565b3d604051818101604052816000823e8215610ccb578181f35b8181fd5b610cd76102e5565b6001600160a01b0316336001600160a01b031614610d2e576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b565b600054600160a01b900460ff1615610d86576040805162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b600054600160b01b900460ff1615610e1657333014610e0457fe5b6000805460ff60b01b19169055610d2e565b610d2e610ccf565b610e26610ccf565b600082359050600060076001609c1b016001600160a01b0316636221a54b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e6e57600080fd5b505afa158015610e82573d6000803e3d6000fd5b505050506040513d6020811015610e9857600080fd5b505160408051808201825242830180825282516020601f89018190048102820181019094528781529394509290918281019190889088908190840183828082843760009201829052509390945250506001600160e01b03198616815260016020818152604090922084518155848301518051919450610f1c93928501920190610fe5565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405180856001600160e01b0319168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f191690920182900397509095505050505050a15050505050565b50805460018160011615610100020316600290046000825580601f10610fc75750610879565b601f0160209004906000526020600020908101906108799190611071565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261101b5760008555611061565b82601f1061103457805160ff1916838001178555611061565b82800160010185558215611061579182015b82811115611061578251825591602001919060010190611046565b5061106d929150611071565b5090565b5b8082111561106d576000815560010161107256fea26469706673582212202553285371ed9813b00e179bc0891ef5c20c5625a744d5d7bb3ea8f2a389163e64736f6c63430007060033