From 9aa24985b37291f55939e5217619b723ae5c0423 Mon Sep 17 00:00:00 2001 From: Aodhgan Date: Fri, 12 Mar 2021 13:33:31 -0800 Subject: [PATCH] added view, deployed to Kovan --- contracts/PrizePoolRegistry.sol | 2 +- contracts/PrizeStrategyUpkeep.sol | 2 +- contracts/interfaces/PrizePoolInterface.sol | 2 +- .../interfaces/PrizePoolRegistryInterface.sol | 2 +- contracts/utils/SafeAwardable.sol | 6 +- deploy/deploy.js | 10 +-- deployments/kovan/PrizePoolRegistry.json | 40 +++++------ deployments/kovan/PrizeStrategyUpkeep.json | 30 ++++----- .../20d3358fd77b25249d09dbdeb2d71edd.json | 66 +++++++++++++++++++ 9 files changed, 113 insertions(+), 47 deletions(-) create mode 100644 deployments/kovan/solcInputs/20d3358fd77b25249d09dbdeb2d71edd.json diff --git a/contracts/PrizePoolRegistry.sol b/contracts/PrizePoolRegistry.sol index 2062717..07740c9 100644 --- a/contracts/PrizePoolRegistry.sol +++ b/contracts/PrizePoolRegistry.sol @@ -29,7 +29,7 @@ contract PrizePoolRegistry is Ownable { /// @notice Returns an array of all prizePools in the linked list ///@return Array of prize pool addresses - function getPrizePools() external returns(address[] memory){ + function getPrizePools() view external returns(address[] memory){ return prizePoolList.addressArray(); } diff --git a/contracts/PrizeStrategyUpkeep.sol b/contracts/PrizeStrategyUpkeep.sol index dde8535..e7fab27 100644 --- a/contracts/PrizeStrategyUpkeep.sol +++ b/contracts/PrizeStrategyUpkeep.sol @@ -28,7 +28,7 @@ contract PrizeStrategyUpkeep is KeeperCompatibleInterface { /// @notice Checks if PrizePools require upkeep. Call in a static manner every block by the Chainlink Upkeep network. /// @param checkData Not used in this implementation. /// @return upkeepNeeded as true if performUpkeep() needs to be called, false otherwise. performData returned empty. - function checkUpkeep(bytes calldata checkData) override external returns (bool upkeepNeeded, bytes memory performData){ // check view + function checkUpkeep(bytes calldata checkData) view override external returns (bool upkeepNeeded, bytes memory performData){ // check view address[] memory prizePools = PrizePoolRegistryInterface(prizePoolRegistry).getPrizePools(); diff --git a/contracts/interfaces/PrizePoolInterface.sol b/contracts/interfaces/PrizePoolInterface.sol index f69f5ac..725670f 100644 --- a/contracts/interfaces/PrizePoolInterface.sol +++ b/contracts/interfaces/PrizePoolInterface.sol @@ -3,5 +3,5 @@ pragma solidity ^0.7.6; interface PrizePoolInterface { - function prizeStrategy() external returns (address); + function prizeStrategy() external view returns (address); } \ No newline at end of file diff --git a/contracts/interfaces/PrizePoolRegistryInterface.sol b/contracts/interfaces/PrizePoolRegistryInterface.sol index e9fefbc..b5a2956 100644 --- a/contracts/interfaces/PrizePoolRegistryInterface.sol +++ b/contracts/interfaces/PrizePoolRegistryInterface.sol @@ -3,5 +3,5 @@ pragma solidity ^0.7.6; interface PrizePoolRegistryInterface { - function getPrizePools() external returns(address[] memory); + function getPrizePools() external view returns(address[] memory); } \ No newline at end of file diff --git a/contracts/utils/SafeAwardable.sol b/contracts/utils/SafeAwardable.sol index 331e741..bd22657 100644 --- a/contracts/utils/SafeAwardable.sol +++ b/contracts/utils/SafeAwardable.sol @@ -10,7 +10,7 @@ import "../interfaces/PeriodicPrizeStrategyInterface.sol"; library SafeAwardable{ ///@return canCompleteAward returns true if the function is supported AND can be completed - function canCompleteAward(address self) internal returns (bool canCompleteAward){ + function canCompleteAward(address self) internal view returns (bool canCompleteAward){ if(supportsFunction(self, PeriodicPrizeStrategyInterface.canCompleteAward.selector)){ return PeriodicPrizeStrategyInterface(self).canCompleteAward(); } @@ -18,7 +18,7 @@ library SafeAwardable{ } ///@return canStartAward returns true if the function is supported AND can be started, false otherwise - function canStartAward(address self) internal returns (bool canStartAward){ + function canStartAward(address self) internal view returns (bool canStartAward){ if(supportsFunction(self, PeriodicPrizeStrategyInterface.canStartAward.selector)){ return PeriodicPrizeStrategyInterface(self).canStartAward(); } @@ -27,7 +27,7 @@ library SafeAwardable{ ///@param selector is the function selector to check against ///@return success returns true if function is implemented, false otherwise - function supportsFunction(address self, bytes4 selector) internal returns (bool success){ + function supportsFunction(address self, bytes4 selector) internal view returns (bool success){ bytes memory encodedParams = abi.encodeWithSelector(selector); (bool success, bytes memory result) = self.staticcall{ gas: 30000 }(encodedParams); if (result.length < 32){ diff --git a/deploy/deploy.js b/deploy/deploy.js index ff74eef..15b5e9c 100644 --- a/deploy/deploy.js +++ b/deploy/deploy.js @@ -14,7 +14,7 @@ module.exports = async (hardhat) => { console.log("running deploy script") - console.log("network id ", getChainId()) + console.log("network id ", await getChainId()) const { getNamedAccounts, deployments, ethers } = hardhat const { deploy } = deployments @@ -29,17 +29,17 @@ module.exports = async (hardhat) => { const prizePoolRegistry = await deploy('PrizePoolRegistry', { args: [], from: deployer, - skipIfAlreadyDeployed: true + skipIfAlreadyDeployed: false }) green(`Deployed PrizePoolRegistry: ${prizePoolRegistry.address}`) - dim(`deploying PrizePoolUpkeep contract from ${deployer}`) + dim(`deploying PrizeStrategyUpkeep contract from ${deployer}`) const prizePoolUpkeep = await deploy('PrizeStrategyUpkeep', { args: [prizePoolRegistry.address, batchSize], from: deployer, - skipIfAlreadyDeployed: true + skipIfAlreadyDeployed: false }) - green(`Deployed PrizePoolUpkeep: ${prizePoolUpkeep.address}`) + green(`Deployed PrizeStrategyUpkeep: ${prizePoolUpkeep.address}`) } \ No newline at end of file diff --git a/deployments/kovan/PrizePoolRegistry.json b/deployments/kovan/PrizePoolRegistry.json index 19e6af8..dbb226e 100644 --- a/deployments/kovan/PrizePoolRegistry.json +++ b/deployments/kovan/PrizePoolRegistry.json @@ -1,5 +1,5 @@ { - "address": "0xcb901A9a76D01A16b1a0529F30110Dd0F9A77024", + "address": "0x8817bB292941e1A69F12879B274c8A15D315ABb1", "abi": [ { "inputs": [], @@ -74,7 +74,7 @@ "type": "address[]" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { @@ -129,42 +129,42 @@ "type": "function" } ], - "transactionHash": "0x87bfbfbf1ff2484da1de3bb99a216745b521e61173e288ac870e6710186e5ba9", + "transactionHash": "0x37bc0e8d91e7d87c41da83ca7f55560734dd8b8584d709a402f21b1b5e40d26b", "receipt": { "to": null, "from": "0x8a6897bc4965cB3FA6a2DB3283Be068908064D13", - "contractAddress": "0xcb901A9a76D01A16b1a0529F30110Dd0F9A77024", - "transactionIndex": 6, + "contractAddress": "0x8817bB292941e1A69F12879B274c8A15D315ABb1", + "transactionIndex": 19, "gasUsed": "626641", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100020000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x6df67e1d08e9baf7950bb36b831fdbdd90bfcc74c62f71bcff633d7687c6a1be", - "transactionHash": "0x87bfbfbf1ff2484da1de3bb99a216745b521e61173e288ac870e6710186e5ba9", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000008000000020000000000000000000000000000000000000000000000000000000000000060000000000000100000000000000000000000000000000000000000000000000000", + "blockHash": "0xa0b6d062315a3a7acf8bbc1d60a628113b1a377cb5d7a0c2d1f6d40eeae82746", + "transactionHash": "0x37bc0e8d91e7d87c41da83ca7f55560734dd8b8584d709a402f21b1b5e40d26b", "logs": [ { - "transactionIndex": 6, - "blockNumber": 23842560, - "transactionHash": "0x87bfbfbf1ff2484da1de3bb99a216745b521e61173e288ac870e6710186e5ba9", - "address": "0xcb901A9a76D01A16b1a0529F30110Dd0F9A77024", + "transactionIndex": 19, + "blockNumber": 23842806, + "transactionHash": "0x37bc0e8d91e7d87c41da83ca7f55560734dd8b8584d709a402f21b1b5e40d26b", + "address": "0x8817bB292941e1A69F12879B274c8A15D315ABb1", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000008a6897bc4965cb3fa6a2db3283be068908064d13" ], "data": "0x", - "logIndex": 5, - "blockHash": "0x6df67e1d08e9baf7950bb36b831fdbdd90bfcc74c62f71bcff633d7687c6a1be" + "logIndex": 49, + "blockHash": "0xa0b6d062315a3a7acf8bbc1d60a628113b1a377cb5d7a0c2d1f6d40eeae82746" } ], - "blockNumber": 23842560, - "cumulativeGasUsed": "904851", + "blockNumber": 23842806, + "cumulativeGasUsed": "2461861", "status": 1, "byzantium": true }, "args": [], - "solcInputHash": "4e8203afa008e9aec6b04940a7a9a5b1", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"prizePool\",\"type\":\"address\"}],\"name\":\"PrizePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"prizePool\",\"type\":\"address\"}],\"name\":\"PrizePoolRemoved\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_prizePools\",\"type\":\"address[]\"}],\"name\":\"addPrizePools\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPrizePools\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_previousPrizePool\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_prizePool\",\"type\":\"address\"}],\"name\":\"removePrizePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addPrizePools(address[])\":{\"params\":{\"_prizePools\":\"Array of prizePool addresses\"}},\"getPrizePools()\":{\"returns\":{\"_0\":\"Array of prize pool addresses\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"removePrizePool(address,address)\":{\"params\":{\"_previousPrizePool\":\"The address positionally localed before the address that will be deleted. This may be the SENTINEL address if the list contains one prize pool address\",\"_prizePool\":\"The address to remove from the linked list. \"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addPrizePools(address[])\":{\"notice\":\"Adds addresses to the linked list. Will revert if the address is already in the list. Can only be called by the Registry owner.\"},\"getPrizePools()\":{\"notice\":\"Returns an array of all prizePools in the linked list\"},\"removePrizePool(address,address)\":{\"notice\":\"Removes an address from the linked list. Can only be called by the Registry owner.\"}},\"notice\":\"A registry to hold Prize Pool addresses. Underlying data structure is a singly linked list. \",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/PrizePoolRegistry.sol\":\"PrizePoolRegistry\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x15e2d5bd4c28a88548074c54d220e8086f638a71ed07e6b3ba5a70066fcf458d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/PrizePoolRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.6;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport \\\"./interfaces/KeeperCompatibleInterface.sol\\\";\\nimport \\\"./interfaces/PeriodicPrizeStrategyInterface.sol\\\";\\nimport \\\"./interfaces/PrizePoolInterface.sol\\\";\\nimport \\\"./utils/MappedSinglyLinkedList.sol\\\";\\n\\n\\n\\n///@notice A registry to hold Prize Pool addresses. Underlying data structure is a singly linked list. \\ncontract PrizePoolRegistry is Ownable {\\n\\n using MappedSinglyLinkedList for MappedSinglyLinkedList.Mapping;\\n\\n event PrizePoolAdded(address indexed prizePool);\\n event PrizePoolRemoved(address indexed prizePool);\\n\\n MappedSinglyLinkedList.Mapping internal prizePoolList;\\n\\n constructor() Ownable(){\\n prizePoolList.initialize();\\n }\\n\\n\\n /// @notice Returns an array of all prizePools in the linked list\\n ///@return Array of prize pool addresses\\n function getPrizePools() external returns(address[] memory){\\n return prizePoolList.addressArray();\\n } \\n\\n /// @notice Adds addresses to the linked list. Will revert if the address is already in the list. Can only be called by the Registry owner.\\n /// @param _prizePools Array of prizePool addresses\\n function addPrizePools(address[] calldata _prizePools) public onlyOwner {\\n for(uint256 prizePool = 0; prizePool < _prizePools.length; prizePool++ ){ \\n prizePoolList.addAddress(_prizePools[prizePool]);\\n emit PrizePoolAdded(_prizePools[prizePool]);\\n }\\n }\\n\\n /// @notice Removes an address from the linked list. Can only be called by the Registry owner.\\n /// @param _previousPrizePool The address positionally localed before the address that will be deleted. This may be the SENTINEL address if the list contains one prize pool address\\n /// @param _prizePool The address to remove from the linked list. \\n function removePrizePool(address _previousPrizePool, address _prizePool) public onlyOwner{\\n prizePoolList.removeAddress(_previousPrizePool, _prizePool); \\n emit PrizePoolRemoved(_prizePool);\\n } \\n}\",\"keccak256\":\"0x95e5e7f64252b3810315367028e15e146edc39c8d432df7dabd33cacfb57aafe\",\"license\":\"MIT\"},\"contracts/interfaces/KeeperCompatibleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.7.6;\\n\\ninterface KeeperCompatibleInterface {\\n\\n /**\\n * @notice method that is simulated by the keepers to see if any work actually\\n * needs to be performed. This method does does not actually need to be\\n * executable, and since it is only ever simulated it can consume lots of gas.\\n * @dev To ensure that it is never called, you may want to add the\\n * cannotExecute modifier from KeeperBase to your implementation of this\\n * method.\\n * @param checkData specified in the upkeep registration so it is always the\\n * same for a registered upkeep. This can easily be broken down into specific\\n * arguments using `abi.decode`, so multiple upkeeps can be registered on the\\n * same contract and easily differentiated by the contract.\\n * @return upkeepNeeded boolean to indicate whether the keeper should call\\n * performUpkeep or not.\\n * @return performData bytes that the keeper should call performUpkeep with, if\\n * upkeep is needed. If you would like to encode data to decode later, try\\n * `abi.encode`.\\n */\\n function checkUpkeep(\\n bytes calldata checkData\\n )\\n external\\n returns (\\n bool upkeepNeeded,\\n bytes memory performData\\n );\\n /**\\n * @notice method that is actually executed by the keepers, via the registry.\\n * The data returned by the checkUpkeep simulation will be passed into\\n * this method to actually be executed.\\n * @dev The input to this method should not be trusted, and the caller of the\\n * method should not even be restricted to any single registry. Anyone should\\n * be able call it, and the input should be validated, there is no guarantee\\n * that the data passed in is the performData returned from checkUpkeep. This\\n * could happen due to malicious keepers, racing keepers, or simply a state\\n * change while the performUpkeep transaction is waiting for confirmation.\\n * Always validate the data passed in.\\n * @param performData is the data which was passed back from the checkData\\n * simulation. If it is encoded, it can easily be decoded into other types by\\n * calling `abi.decode`. This data should not be trusted, and should be\\n * validated against the contract's current state.\\n */\\n function performUpkeep(\\n bytes calldata performData\\n ) external;\\n}\",\"keccak256\":\"0x5174919ce142bffa1517f63837e932ce18224d3b4cda828e0d88ff8a5b99d920\",\"license\":\"MIT\"},\"contracts/interfaces/PeriodicPrizeStrategyInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.6;\\n\\ninterface PeriodicPrizeStrategyInterface {\\n function startAward() external;\\n function completeAward() external;\\n function canStartAward() external view returns (bool);\\n function canCompleteAward() external view returns (bool);\\n}\",\"keccak256\":\"0x109f0a01f57f08936e7bb94fe357fa71e7237794f6f8576c37c773a80dcd155f\",\"license\":\"MIT\"},\"contracts/interfaces/PrizePoolInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.6;\\n\\ninterface PrizePoolInterface {\\n function prizeStrategy() external returns (address);\\n}\",\"keccak256\":\"0xdebf90b28b22d82ca90297dc816a0248a7dbf52168f6a032dc68c80f85ebc42c\",\"license\":\"MIT\"},\"contracts/utils/MappedSinglyLinkedList.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.7.6;\\n\\n/// @notice An efficient implementation of a singly linked list of addresses\\n/// @dev A mapping(address => address) tracks the 'next' pointer. A special address called the SENTINEL is used to denote the beginning and end of the list.\\nlibrary MappedSinglyLinkedList {\\n\\n /// @notice The special value address used to denote the end of the list\\n address public constant SENTINEL = address(0x1);\\n\\n /// @notice The data structure to use for the list.\\n struct Mapping {\\n uint256 count;\\n\\n mapping(address => address) addressMap;\\n }\\n\\n /// @notice Initializes the list.\\n /// @dev It is important that this is called so that the SENTINEL is correctly setup.\\n function initialize(Mapping storage self) internal {\\n require(self.count == 0, \\\"Already init\\\");\\n self.addressMap[SENTINEL] = SENTINEL;\\n }\\n\\n function start(Mapping storage self) internal view returns (address) {\\n return self.addressMap[SENTINEL];\\n }\\n\\n function next(Mapping storage self, address current) internal view returns (address) {\\n return self.addressMap[current];\\n }\\n\\n function end(Mapping storage) internal pure returns (address) {\\n return SENTINEL;\\n }\\n\\n function addAddresses(Mapping storage self, address[] memory addresses) internal {\\n for (uint256 i = 0; i < addresses.length; i++) {\\n addAddress(self, addresses[i]);\\n }\\n }\\n\\n /// @notice Adds an address to the front of the list.\\n /// @param self The Mapping struct that this function is attached to\\n /// @param newAddress The address to shift to the front of the list\\n function addAddress(Mapping storage self, address newAddress) internal {\\n require(newAddress != SENTINEL && newAddress != address(0), \\\"Invalid address\\\");\\n require(self.addressMap[newAddress] == address(0), \\\"Already added\\\");\\n self.addressMap[newAddress] = self.addressMap[SENTINEL];\\n self.addressMap[SENTINEL] = newAddress;\\n self.count = self.count + 1;\\n }\\n\\n /// @notice Removes an address from the list\\n /// @param self The Mapping struct that this function is attached to\\n /// @param prevAddress The address that precedes the address to be removed. This may be the SENTINEL if at the start.\\n /// @param addr The address to remove from the list.\\n function removeAddress(Mapping storage self, address prevAddress, address addr) internal {\\n require(addr != SENTINEL && addr != address(0), \\\"Invalid address\\\");\\n require(self.addressMap[prevAddress] == addr, \\\"Invalid prevAddress\\\");\\n self.addressMap[prevAddress] = self.addressMap[addr];\\n delete self.addressMap[addr];\\n self.count = self.count - 1;\\n }\\n\\n /// @notice Determines whether the list contains the given address\\n /// @param self The Mapping struct that this function is attached to\\n /// @param addr The address to check\\n /// @return True if the address is contained, false otherwise.\\n function contains(Mapping storage self, address addr) internal view returns (bool) {\\n return addr != SENTINEL && addr != address(0) && self.addressMap[addr] != address(0);\\n }\\n\\n /// @notice Returns an address array of all the addresses in this list\\n /// @dev Contains a for loop, so complexity is O(n) wrt the list size\\n /// @param self The Mapping struct that this function is attached to\\n /// @return An array of all the addresses\\n function addressArray(Mapping storage self) internal view returns (address[] memory) {\\n address[] memory array = new address[](self.count);\\n uint256 count;\\n address currentAddress = self.addressMap[SENTINEL];\\n while (currentAddress != address(0) && currentAddress != SENTINEL) {\\n array[count] = currentAddress;\\n currentAddress = self.addressMap[currentAddress];\\n count++;\\n }\\n return array;\\n }\\n\\n /// @notice Removes every address from the list\\n /// @param self The Mapping struct that this function is attached to\\n function clearAll(Mapping storage self) internal {\\n address currentAddress = self.addressMap[SENTINEL];\\n while (currentAddress != address(0) && currentAddress != SENTINEL) {\\n address nextAddress = self.addressMap[currentAddress];\\n delete self.addressMap[currentAddress];\\n currentAddress = nextAddress;\\n }\\n self.addressMap[SENTINEL] = SENTINEL;\\n self.count = 0;\\n }\\n}\\n\",\"keccak256\":\"0x14a99407202bafc5988b8ea002afabac73c13f88372083cf381d447ef30edc85\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50600061001b61007e565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350610079600161008260201b61044d1760201c565b6100ea565b3390565b8054156100c5576040805162461bcd60e51b815260206004820152600c60248201526b105b1c9958591e481a5b9a5d60a21b604482015290519081900360640190fd5b60016000818152918101602052604090912080546001600160a01b0319169091179055565b610982806100f96000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c8063097a584f14610067578063715018a61461007c5780638da5cb5b14610084578063a28e6219146100a2578063d7d4796c146100b7578063f2fde38b146100ca575b600080fd5b61007a610075366004610836565b6100dd565b005b61007a6101d9565b61008c610285565b60405161009991906108a5565b60405180910390f35b6100aa610294565b60405161009991906108b9565b61007a6100c5366004610804565b6102a5565b61007a6100d83660046107e3565b61034b565b6100e56104b5565b6001600160a01b03166100f6610285565b6001600160a01b03161461013f576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b60005b818110156101d45761017683838381811061015957fe5b905060200201602081019061016e91906107e3565b6001906104b9565b82828281811061018257fe5b905060200201602081019061019791906107e3565b6001600160a01b03167f59394a9dad6d755c0a4f06421118bb52b49ff946870e9ab26fe4547dd5c3d63260405160405180910390a2600101610142565b505050565b6101e16104b5565b6001600160a01b03166101f2610285565b6001600160a01b03161461023b576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b60606102a060016105cd565b905090565b6102ad6104b5565b6001600160a01b03166102be610285565b6001600160a01b031614610307576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b610313600183836106b0565b6040516001600160a01b038216907f74ea0f566f4d31f3c79bf82475da668ddb523523351bd8349b65803c07f97e7a90600090a25050565b6103536104b5565b6001600160a01b0316610364610285565b6001600160a01b0316146103ad576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b6001600160a01b0381166103f25760405162461bcd60e51b81526004018080602001828103825260268152602001806109076026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b805415610490576040805162461bcd60e51b815260206004820152600c60248201526b105b1c9958591e481a5b9a5d60a21b604482015290519081900360640190fd5b60016000818152918101602052604090912080546001600160a01b0319169091179055565b3390565b6001600160a01b0381166001148015906104db57506001600160a01b03811615155b61051e576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b6001600160a01b038181166000908152600184016020526040902054161561057d576040805162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e481859191959609a1b604482015290519081900360640190fd5b60016000818152838201602052604080822080546001600160a01b039586168085529284208054969091166001600160a01b03199687161790559183905281549093169092179091558154019055565b60606000826000015467ffffffffffffffff811180156105ec57600080fd5b50604051908082528060200260200182016040528015610616578160200160208202803683370190505b50600160008181529085016020526040812054919250906001600160a01b03165b6001600160a01b0381161580159061065957506001600160a01b038116600114155b156106a5578083838151811061066b57fe5b6001600160a01b03928316602091820292909201810191909152918116600090815260018088019093526040902054929091019116610637565b50909150505b919050565b6001600160a01b0381166001148015906106d257506001600160a01b03811615155b610715576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b6001600160a01b03828116600090815260018501602052604090205481169082161461077e576040805162461bcd60e51b8152602060048201526013602482015272496e76616c696420707265764164647265737360681b604482015290519081900360640190fd5b6001600160a01b039081166000818152600185016020526040808220805495851683529082208054959094166001600160a01b03199586161790935552805490911690558054600019019055565b80356001600160a01b03811681146106ab57600080fd5b6000602082840312156107f4578081fd5b6107fd826107cc565b9392505050565b60008060408385031215610816578081fd5b61081f836107cc565b915061082d602084016107cc565b90509250929050565b60008060208385031215610848578182fd5b823567ffffffffffffffff8082111561085f578384fd5b818501915085601f830112610872578384fd5b813581811115610880578485fd5b8660208083028501011115610893578485fd5b60209290920196919550909350505050565b6001600160a01b0391909116815260200190565b6020808252825182820181905260009190848201906040850190845b818110156108fa5783516001600160a01b0316835292840192918401916001016108d5565b5090969550505050505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a26469706673582212207902778e0c717c074cd279f194354cede403e54114397daa25feff8a9f5f9a2f64736f6c63430007060033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c8063097a584f14610067578063715018a61461007c5780638da5cb5b14610084578063a28e6219146100a2578063d7d4796c146100b7578063f2fde38b146100ca575b600080fd5b61007a610075366004610836565b6100dd565b005b61007a6101d9565b61008c610285565b60405161009991906108a5565b60405180910390f35b6100aa610294565b60405161009991906108b9565b61007a6100c5366004610804565b6102a5565b61007a6100d83660046107e3565b61034b565b6100e56104b5565b6001600160a01b03166100f6610285565b6001600160a01b03161461013f576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b60005b818110156101d45761017683838381811061015957fe5b905060200201602081019061016e91906107e3565b6001906104b9565b82828281811061018257fe5b905060200201602081019061019791906107e3565b6001600160a01b03167f59394a9dad6d755c0a4f06421118bb52b49ff946870e9ab26fe4547dd5c3d63260405160405180910390a2600101610142565b505050565b6101e16104b5565b6001600160a01b03166101f2610285565b6001600160a01b03161461023b576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b60606102a060016105cd565b905090565b6102ad6104b5565b6001600160a01b03166102be610285565b6001600160a01b031614610307576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b610313600183836106b0565b6040516001600160a01b038216907f74ea0f566f4d31f3c79bf82475da668ddb523523351bd8349b65803c07f97e7a90600090a25050565b6103536104b5565b6001600160a01b0316610364610285565b6001600160a01b0316146103ad576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b6001600160a01b0381166103f25760405162461bcd60e51b81526004018080602001828103825260268152602001806109076026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b805415610490576040805162461bcd60e51b815260206004820152600c60248201526b105b1c9958591e481a5b9a5d60a21b604482015290519081900360640190fd5b60016000818152918101602052604090912080546001600160a01b0319169091179055565b3390565b6001600160a01b0381166001148015906104db57506001600160a01b03811615155b61051e576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b6001600160a01b038181166000908152600184016020526040902054161561057d576040805162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e481859191959609a1b604482015290519081900360640190fd5b60016000818152838201602052604080822080546001600160a01b039586168085529284208054969091166001600160a01b03199687161790559183905281549093169092179091558154019055565b60606000826000015467ffffffffffffffff811180156105ec57600080fd5b50604051908082528060200260200182016040528015610616578160200160208202803683370190505b50600160008181529085016020526040812054919250906001600160a01b03165b6001600160a01b0381161580159061065957506001600160a01b038116600114155b156106a5578083838151811061066b57fe5b6001600160a01b03928316602091820292909201810191909152918116600090815260018088019093526040902054929091019116610637565b50909150505b919050565b6001600160a01b0381166001148015906106d257506001600160a01b03811615155b610715576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b6001600160a01b03828116600090815260018501602052604090205481169082161461077e576040805162461bcd60e51b8152602060048201526013602482015272496e76616c696420707265764164647265737360681b604482015290519081900360640190fd5b6001600160a01b039081166000818152600185016020526040808220805495851683529082208054959094166001600160a01b03199586161790935552805490911690558054600019019055565b80356001600160a01b03811681146106ab57600080fd5b6000602082840312156107f4578081fd5b6107fd826107cc565b9392505050565b60008060408385031215610816578081fd5b61081f836107cc565b915061082d602084016107cc565b90509250929050565b60008060208385031215610848578182fd5b823567ffffffffffffffff8082111561085f578384fd5b818501915085601f830112610872578384fd5b813581811115610880578485fd5b8660208083028501011115610893578485fd5b60209290920196919550909350505050565b6001600160a01b0391909116815260200190565b6020808252825182820181905260009190848201906040850190845b818110156108fa5783516001600160a01b0316835292840192918401916001016108d5565b5090969550505050505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a26469706673582212207902778e0c717c074cd279f194354cede403e54114397daa25feff8a9f5f9a2f64736f6c63430007060033", + "solcInputHash": "20d3358fd77b25249d09dbdeb2d71edd", + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"prizePool\",\"type\":\"address\"}],\"name\":\"PrizePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"prizePool\",\"type\":\"address\"}],\"name\":\"PrizePoolRemoved\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_prizePools\",\"type\":\"address[]\"}],\"name\":\"addPrizePools\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPrizePools\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_previousPrizePool\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_prizePool\",\"type\":\"address\"}],\"name\":\"removePrizePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addPrizePools(address[])\":{\"params\":{\"_prizePools\":\"Array of prizePool addresses\"}},\"getPrizePools()\":{\"returns\":{\"_0\":\"Array of prize pool addresses\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"removePrizePool(address,address)\":{\"params\":{\"_previousPrizePool\":\"The address positionally localed before the address that will be deleted. This may be the SENTINEL address if the list contains one prize pool address\",\"_prizePool\":\"The address to remove from the linked list. \"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addPrizePools(address[])\":{\"notice\":\"Adds addresses to the linked list. Will revert if the address is already in the list. Can only be called by the Registry owner.\"},\"getPrizePools()\":{\"notice\":\"Returns an array of all prizePools in the linked list\"},\"removePrizePool(address,address)\":{\"notice\":\"Removes an address from the linked list. Can only be called by the Registry owner.\"}},\"notice\":\"A registry to hold Prize Pool addresses. Underlying data structure is a singly linked list. \",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/PrizePoolRegistry.sol\":\"PrizePoolRegistry\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x15e2d5bd4c28a88548074c54d220e8086f638a71ed07e6b3ba5a70066fcf458d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/PrizePoolRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.6;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport \\\"./interfaces/KeeperCompatibleInterface.sol\\\";\\nimport \\\"./interfaces/PeriodicPrizeStrategyInterface.sol\\\";\\nimport \\\"./interfaces/PrizePoolInterface.sol\\\";\\nimport \\\"./utils/MappedSinglyLinkedList.sol\\\";\\n\\n\\n\\n///@notice A registry to hold Prize Pool addresses. Underlying data structure is a singly linked list. \\ncontract PrizePoolRegistry is Ownable {\\n\\n using MappedSinglyLinkedList for MappedSinglyLinkedList.Mapping;\\n\\n event PrizePoolAdded(address indexed prizePool);\\n event PrizePoolRemoved(address indexed prizePool);\\n\\n MappedSinglyLinkedList.Mapping internal prizePoolList;\\n\\n constructor() Ownable(){\\n prizePoolList.initialize();\\n }\\n\\n\\n /// @notice Returns an array of all prizePools in the linked list\\n ///@return Array of prize pool addresses\\n function getPrizePools() view external returns(address[] memory){\\n return prizePoolList.addressArray();\\n } \\n\\n /// @notice Adds addresses to the linked list. Will revert if the address is already in the list. Can only be called by the Registry owner.\\n /// @param _prizePools Array of prizePool addresses\\n function addPrizePools(address[] calldata _prizePools) public onlyOwner {\\n for(uint256 prizePool = 0; prizePool < _prizePools.length; prizePool++ ){ \\n prizePoolList.addAddress(_prizePools[prizePool]);\\n emit PrizePoolAdded(_prizePools[prizePool]);\\n }\\n }\\n\\n /// @notice Removes an address from the linked list. Can only be called by the Registry owner.\\n /// @param _previousPrizePool The address positionally localed before the address that will be deleted. This may be the SENTINEL address if the list contains one prize pool address\\n /// @param _prizePool The address to remove from the linked list. \\n function removePrizePool(address _previousPrizePool, address _prizePool) public onlyOwner{\\n prizePoolList.removeAddress(_previousPrizePool, _prizePool); \\n emit PrizePoolRemoved(_prizePool);\\n } \\n}\",\"keccak256\":\"0x103014acff45ec739622937a73952bb537c8cd0290a00b0f472061a437002e16\",\"license\":\"MIT\"},\"contracts/interfaces/KeeperCompatibleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.7.6;\\n\\ninterface KeeperCompatibleInterface {\\n\\n /**\\n * @notice method that is simulated by the keepers to see if any work actually\\n * needs to be performed. This method does does not actually need to be\\n * executable, and since it is only ever simulated it can consume lots of gas.\\n * @dev To ensure that it is never called, you may want to add the\\n * cannotExecute modifier from KeeperBase to your implementation of this\\n * method.\\n * @param checkData specified in the upkeep registration so it is always the\\n * same for a registered upkeep. This can easily be broken down into specific\\n * arguments using `abi.decode`, so multiple upkeeps can be registered on the\\n * same contract and easily differentiated by the contract.\\n * @return upkeepNeeded boolean to indicate whether the keeper should call\\n * performUpkeep or not.\\n * @return performData bytes that the keeper should call performUpkeep with, if\\n * upkeep is needed. If you would like to encode data to decode later, try\\n * `abi.encode`.\\n */\\n function checkUpkeep(\\n bytes calldata checkData\\n )\\n external\\n returns (\\n bool upkeepNeeded,\\n bytes memory performData\\n );\\n /**\\n * @notice method that is actually executed by the keepers, via the registry.\\n * The data returned by the checkUpkeep simulation will be passed into\\n * this method to actually be executed.\\n * @dev The input to this method should not be trusted, and the caller of the\\n * method should not even be restricted to any single registry. Anyone should\\n * be able call it, and the input should be validated, there is no guarantee\\n * that the data passed in is the performData returned from checkUpkeep. This\\n * could happen due to malicious keepers, racing keepers, or simply a state\\n * change while the performUpkeep transaction is waiting for confirmation.\\n * Always validate the data passed in.\\n * @param performData is the data which was passed back from the checkData\\n * simulation. If it is encoded, it can easily be decoded into other types by\\n * calling `abi.decode`. This data should not be trusted, and should be\\n * validated against the contract's current state.\\n */\\n function performUpkeep(\\n bytes calldata performData\\n ) external;\\n}\",\"keccak256\":\"0x5174919ce142bffa1517f63837e932ce18224d3b4cda828e0d88ff8a5b99d920\",\"license\":\"MIT\"},\"contracts/interfaces/PeriodicPrizeStrategyInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.6;\\n\\ninterface PeriodicPrizeStrategyInterface {\\n function startAward() external;\\n function completeAward() external;\\n function canStartAward() external view returns (bool);\\n function canCompleteAward() external view returns (bool);\\n}\",\"keccak256\":\"0x109f0a01f57f08936e7bb94fe357fa71e7237794f6f8576c37c773a80dcd155f\",\"license\":\"MIT\"},\"contracts/interfaces/PrizePoolInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.6;\\n\\ninterface PrizePoolInterface {\\n function prizeStrategy() external view returns (address);\\n}\",\"keccak256\":\"0x25c3deefae7b4f2270303b5646e28f49922853ae946173ca2032173bd1844210\",\"license\":\"MIT\"},\"contracts/utils/MappedSinglyLinkedList.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.7.6;\\n\\n/// @notice An efficient implementation of a singly linked list of addresses\\n/// @dev A mapping(address => address) tracks the 'next' pointer. A special address called the SENTINEL is used to denote the beginning and end of the list.\\nlibrary MappedSinglyLinkedList {\\n\\n /// @notice The special value address used to denote the end of the list\\n address public constant SENTINEL = address(0x1);\\n\\n /// @notice The data structure to use for the list.\\n struct Mapping {\\n uint256 count;\\n\\n mapping(address => address) addressMap;\\n }\\n\\n /// @notice Initializes the list.\\n /// @dev It is important that this is called so that the SENTINEL is correctly setup.\\n function initialize(Mapping storage self) internal {\\n require(self.count == 0, \\\"Already init\\\");\\n self.addressMap[SENTINEL] = SENTINEL;\\n }\\n\\n function start(Mapping storage self) internal view returns (address) {\\n return self.addressMap[SENTINEL];\\n }\\n\\n function next(Mapping storage self, address current) internal view returns (address) {\\n return self.addressMap[current];\\n }\\n\\n function end(Mapping storage) internal pure returns (address) {\\n return SENTINEL;\\n }\\n\\n function addAddresses(Mapping storage self, address[] memory addresses) internal {\\n for (uint256 i = 0; i < addresses.length; i++) {\\n addAddress(self, addresses[i]);\\n }\\n }\\n\\n /// @notice Adds an address to the front of the list.\\n /// @param self The Mapping struct that this function is attached to\\n /// @param newAddress The address to shift to the front of the list\\n function addAddress(Mapping storage self, address newAddress) internal {\\n require(newAddress != SENTINEL && newAddress != address(0), \\\"Invalid address\\\");\\n require(self.addressMap[newAddress] == address(0), \\\"Already added\\\");\\n self.addressMap[newAddress] = self.addressMap[SENTINEL];\\n self.addressMap[SENTINEL] = newAddress;\\n self.count = self.count + 1;\\n }\\n\\n /// @notice Removes an address from the list\\n /// @param self The Mapping struct that this function is attached to\\n /// @param prevAddress The address that precedes the address to be removed. This may be the SENTINEL if at the start.\\n /// @param addr The address to remove from the list.\\n function removeAddress(Mapping storage self, address prevAddress, address addr) internal {\\n require(addr != SENTINEL && addr != address(0), \\\"Invalid address\\\");\\n require(self.addressMap[prevAddress] == addr, \\\"Invalid prevAddress\\\");\\n self.addressMap[prevAddress] = self.addressMap[addr];\\n delete self.addressMap[addr];\\n self.count = self.count - 1;\\n }\\n\\n /// @notice Determines whether the list contains the given address\\n /// @param self The Mapping struct that this function is attached to\\n /// @param addr The address to check\\n /// @return True if the address is contained, false otherwise.\\n function contains(Mapping storage self, address addr) internal view returns (bool) {\\n return addr != SENTINEL && addr != address(0) && self.addressMap[addr] != address(0);\\n }\\n\\n /// @notice Returns an address array of all the addresses in this list\\n /// @dev Contains a for loop, so complexity is O(n) wrt the list size\\n /// @param self The Mapping struct that this function is attached to\\n /// @return An array of all the addresses\\n function addressArray(Mapping storage self) internal view returns (address[] memory) {\\n address[] memory array = new address[](self.count);\\n uint256 count;\\n address currentAddress = self.addressMap[SENTINEL];\\n while (currentAddress != address(0) && currentAddress != SENTINEL) {\\n array[count] = currentAddress;\\n currentAddress = self.addressMap[currentAddress];\\n count++;\\n }\\n return array;\\n }\\n\\n /// @notice Removes every address from the list\\n /// @param self The Mapping struct that this function is attached to\\n function clearAll(Mapping storage self) internal {\\n address currentAddress = self.addressMap[SENTINEL];\\n while (currentAddress != address(0) && currentAddress != SENTINEL) {\\n address nextAddress = self.addressMap[currentAddress];\\n delete self.addressMap[currentAddress];\\n currentAddress = nextAddress;\\n }\\n self.addressMap[SENTINEL] = SENTINEL;\\n self.count = 0;\\n }\\n}\\n\",\"keccak256\":\"0x14a99407202bafc5988b8ea002afabac73c13f88372083cf381d447ef30edc85\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50600061001b61007e565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350610079600161008260201b61044d1760201c565b6100ea565b3390565b8054156100c5576040805162461bcd60e51b815260206004820152600c60248201526b105b1c9958591e481a5b9a5d60a21b604482015290519081900360640190fd5b60016000818152918101602052604090912080546001600160a01b0319169091179055565b610982806100f96000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c8063097a584f14610067578063715018a61461007c5780638da5cb5b14610084578063a28e6219146100a2578063d7d4796c146100b7578063f2fde38b146100ca575b600080fd5b61007a610075366004610836565b6100dd565b005b61007a6101d9565b61008c610285565b60405161009991906108a5565b60405180910390f35b6100aa610294565b60405161009991906108b9565b61007a6100c5366004610804565b6102a5565b61007a6100d83660046107e3565b61034b565b6100e56104b5565b6001600160a01b03166100f6610285565b6001600160a01b03161461013f576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b60005b818110156101d45761017683838381811061015957fe5b905060200201602081019061016e91906107e3565b6001906104b9565b82828281811061018257fe5b905060200201602081019061019791906107e3565b6001600160a01b03167f59394a9dad6d755c0a4f06421118bb52b49ff946870e9ab26fe4547dd5c3d63260405160405180910390a2600101610142565b505050565b6101e16104b5565b6001600160a01b03166101f2610285565b6001600160a01b03161461023b576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b60606102a060016105cd565b905090565b6102ad6104b5565b6001600160a01b03166102be610285565b6001600160a01b031614610307576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b610313600183836106b0565b6040516001600160a01b038216907f74ea0f566f4d31f3c79bf82475da668ddb523523351bd8349b65803c07f97e7a90600090a25050565b6103536104b5565b6001600160a01b0316610364610285565b6001600160a01b0316146103ad576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b6001600160a01b0381166103f25760405162461bcd60e51b81526004018080602001828103825260268152602001806109076026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b805415610490576040805162461bcd60e51b815260206004820152600c60248201526b105b1c9958591e481a5b9a5d60a21b604482015290519081900360640190fd5b60016000818152918101602052604090912080546001600160a01b0319169091179055565b3390565b6001600160a01b0381166001148015906104db57506001600160a01b03811615155b61051e576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b6001600160a01b038181166000908152600184016020526040902054161561057d576040805162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e481859191959609a1b604482015290519081900360640190fd5b60016000818152838201602052604080822080546001600160a01b039586168085529284208054969091166001600160a01b03199687161790559183905281549093169092179091558154019055565b60606000826000015467ffffffffffffffff811180156105ec57600080fd5b50604051908082528060200260200182016040528015610616578160200160208202803683370190505b50600160008181529085016020526040812054919250906001600160a01b03165b6001600160a01b0381161580159061065957506001600160a01b038116600114155b156106a5578083838151811061066b57fe5b6001600160a01b03928316602091820292909201810191909152918116600090815260018088019093526040902054929091019116610637565b50909150505b919050565b6001600160a01b0381166001148015906106d257506001600160a01b03811615155b610715576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b6001600160a01b03828116600090815260018501602052604090205481169082161461077e576040805162461bcd60e51b8152602060048201526013602482015272496e76616c696420707265764164647265737360681b604482015290519081900360640190fd5b6001600160a01b039081166000818152600185016020526040808220805495851683529082208054959094166001600160a01b03199586161790935552805490911690558054600019019055565b80356001600160a01b03811681146106ab57600080fd5b6000602082840312156107f4578081fd5b6107fd826107cc565b9392505050565b60008060408385031215610816578081fd5b61081f836107cc565b915061082d602084016107cc565b90509250929050565b60008060208385031215610848578182fd5b823567ffffffffffffffff8082111561085f578384fd5b818501915085601f830112610872578384fd5b813581811115610880578485fd5b8660208083028501011115610893578485fd5b60209290920196919550909350505050565b6001600160a01b0391909116815260200190565b6020808252825182820181905260009190848201906040850190845b818110156108fa5783516001600160a01b0316835292840192918401916001016108d5565b5090969550505050505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a264697066735822122020633d4addc1055a60ad969342c0bf01d94c9daeb550ddcdb59d96947bb3a4df64736f6c63430007060033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c8063097a584f14610067578063715018a61461007c5780638da5cb5b14610084578063a28e6219146100a2578063d7d4796c146100b7578063f2fde38b146100ca575b600080fd5b61007a610075366004610836565b6100dd565b005b61007a6101d9565b61008c610285565b60405161009991906108a5565b60405180910390f35b6100aa610294565b60405161009991906108b9565b61007a6100c5366004610804565b6102a5565b61007a6100d83660046107e3565b61034b565b6100e56104b5565b6001600160a01b03166100f6610285565b6001600160a01b03161461013f576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b60005b818110156101d45761017683838381811061015957fe5b905060200201602081019061016e91906107e3565b6001906104b9565b82828281811061018257fe5b905060200201602081019061019791906107e3565b6001600160a01b03167f59394a9dad6d755c0a4f06421118bb52b49ff946870e9ab26fe4547dd5c3d63260405160405180910390a2600101610142565b505050565b6101e16104b5565b6001600160a01b03166101f2610285565b6001600160a01b03161461023b576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b60606102a060016105cd565b905090565b6102ad6104b5565b6001600160a01b03166102be610285565b6001600160a01b031614610307576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b610313600183836106b0565b6040516001600160a01b038216907f74ea0f566f4d31f3c79bf82475da668ddb523523351bd8349b65803c07f97e7a90600090a25050565b6103536104b5565b6001600160a01b0316610364610285565b6001600160a01b0316146103ad576040805162461bcd60e51b8152602060048201819052602482015260008051602061092d833981519152604482015290519081900360640190fd5b6001600160a01b0381166103f25760405162461bcd60e51b81526004018080602001828103825260268152602001806109076026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b805415610490576040805162461bcd60e51b815260206004820152600c60248201526b105b1c9958591e481a5b9a5d60a21b604482015290519081900360640190fd5b60016000818152918101602052604090912080546001600160a01b0319169091179055565b3390565b6001600160a01b0381166001148015906104db57506001600160a01b03811615155b61051e576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b6001600160a01b038181166000908152600184016020526040902054161561057d576040805162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e481859191959609a1b604482015290519081900360640190fd5b60016000818152838201602052604080822080546001600160a01b039586168085529284208054969091166001600160a01b03199687161790559183905281549093169092179091558154019055565b60606000826000015467ffffffffffffffff811180156105ec57600080fd5b50604051908082528060200260200182016040528015610616578160200160208202803683370190505b50600160008181529085016020526040812054919250906001600160a01b03165b6001600160a01b0381161580159061065957506001600160a01b038116600114155b156106a5578083838151811061066b57fe5b6001600160a01b03928316602091820292909201810191909152918116600090815260018088019093526040902054929091019116610637565b50909150505b919050565b6001600160a01b0381166001148015906106d257506001600160a01b03811615155b610715576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b6001600160a01b03828116600090815260018501602052604090205481169082161461077e576040805162461bcd60e51b8152602060048201526013602482015272496e76616c696420707265764164647265737360681b604482015290519081900360640190fd5b6001600160a01b039081166000818152600185016020526040808220805495851683529082208054959094166001600160a01b03199586161790935552805490911690558054600019019055565b80356001600160a01b03811681146106ab57600080fd5b6000602082840312156107f4578081fd5b6107fd826107cc565b9392505050565b60008060408385031215610816578081fd5b61081f836107cc565b915061082d602084016107cc565b90509250929050565b60008060208385031215610848578182fd5b823567ffffffffffffffff8082111561085f578384fd5b818501915085601f830112610872578384fd5b813581811115610880578485fd5b8660208083028501011115610893578485fd5b60209290920196919550909350505050565b6001600160a01b0391909116815260200190565b6020808252825182820181905260009190848201906040850190845b818110156108fa5783516001600160a01b0316835292840192918401916001016108d5565b5090969550505050505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a264697066735822122020633d4addc1055a60ad969342c0bf01d94c9daeb550ddcdb59d96947bb3a4df64736f6c63430007060033", "devdoc": { "kind": "dev", "methods": { diff --git a/deployments/kovan/PrizeStrategyUpkeep.json b/deployments/kovan/PrizeStrategyUpkeep.json index 057cfcb..906e0d9 100644 --- a/deployments/kovan/PrizeStrategyUpkeep.json +++ b/deployments/kovan/PrizeStrategyUpkeep.json @@ -1,5 +1,5 @@ { - "address": "0x0d6487BcF92a805a811BcB1e1c9b2425DE3aA703", + "address": "0xb853503F62779ac16068A8fc40B84Ee174b50337", "abi": [ { "inputs": [ @@ -38,7 +38,7 @@ "type": "bytes" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { @@ -81,30 +81,30 @@ "type": "function" } ], - "transactionHash": "0x028e0f1c6f5c46ce12d886dc9f6346ca3b05217ef1cf122846667411138e8d64", + "transactionHash": "0x97dc1506a4f7fc63e43076024f2629115d5ab599ef8837d0ee3aa164b91198ed", "receipt": { "to": null, "from": "0x8a6897bc4965cB3FA6a2DB3283Be068908064D13", - "contractAddress": "0x0d6487BcF92a805a811BcB1e1c9b2425DE3aA703", - "transactionIndex": 8, - "gasUsed": "619247", + "contractAddress": "0xb853503F62779ac16068A8fc40B84Ee174b50337", + "transactionIndex": 7, + "gasUsed": "617159", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf5d5078c2827d20e1b90b8bb2bb8d9a80953e371127249181d7eb361cdb800d6", - "transactionHash": "0x028e0f1c6f5c46ce12d886dc9f6346ca3b05217ef1cf122846667411138e8d64", + "blockHash": "0xd897e4a5b70818142a3fe48afce3ec5ce5e17a0542526cfaf92b0a64e77f8937", + "transactionHash": "0x97dc1506a4f7fc63e43076024f2629115d5ab599ef8837d0ee3aa164b91198ed", "logs": [], - "blockNumber": 23842563, - "cumulativeGasUsed": "1772531", + "blockNumber": 23842809, + "cumulativeGasUsed": "1192804", "status": 1, "byzantium": true }, "args": [ - "0xcb901A9a76D01A16b1a0529F30110Dd0F9A77024", + "0x8817bB292941e1A69F12879B274c8A15D315ABb1", 5 ], - "solcInputHash": "4e8203afa008e9aec6b04940a7a9a5b1", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_prizePoolRegistry\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_upkeepBatchSize\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"prizePoolRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepBatchSize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"checkUpkeep(bytes)\":{\"params\":{\"checkData\":\"Not used in this implementation.\"},\"returns\":{\"upkeepNeeded\":\"as true if performUpkeep() needs to be called, false otherwise. performData returned empty. \"}},\"performUpkeep(bytes)\":{\"params\":{\"performData\":\"Not used in this implementation.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"checkUpkeep(bytes)\":{\"notice\":\"Checks if PrizePools require upkeep. Call in a static manner every block by the Chainlink Upkeep network.\"},\"performUpkeep(bytes)\":{\"notice\":\"Performs upkeep on the prize pools. \"}},\"notice\":\"Contract implements Chainlink's Upkeep system interface, automating the upkeep of PrizePools in the associated registry. \",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/PrizeStrategyUpkeep.sol\":\"PrizeStrategyUpkeep\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/PrizeStrategyUpkeep.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.6;\\npragma experimental ABIEncoderV2;\\n\\n\\nimport \\\"./interfaces/KeeperCompatibleInterface.sol\\\";\\nimport \\\"./interfaces/PeriodicPrizeStrategyInterface.sol\\\";\\nimport \\\"./interfaces/PrizePoolRegistryInterface.sol\\\";\\nimport \\\"./interfaces/PrizePoolInterface.sol\\\";\\nimport \\\"./utils/SafeAwardable.sol\\\";\\n\\n\\n///@notice Contract implements Chainlink's Upkeep system interface, automating the upkeep of PrizePools in the associated registry. \\ncontract PrizeStrategyUpkeep is KeeperCompatibleInterface {\\n\\n using SafeAwardable for address;\\n\\n address public prizePoolRegistry;\\n\\n uint public upkeepBatchSize;\\n \\n constructor(address _prizePoolRegistry, uint256 _upkeepBatchSize) public {\\n prizePoolRegistry = _prizePoolRegistry;\\n upkeepBatchSize = _upkeepBatchSize;\\n }\\n\\n /// @notice Checks if PrizePools require upkeep. Call in a static manner every block by the Chainlink Upkeep network.\\n /// @param checkData Not used in this implementation.\\n /// @return upkeepNeeded as true if performUpkeep() needs to be called, false otherwise. performData returned empty. \\n function checkUpkeep(bytes calldata checkData) override external returns (bool upkeepNeeded, bytes memory performData){ // check view\\n\\n address[] memory prizePools = PrizePoolRegistryInterface(prizePoolRegistry).getPrizePools();\\n\\n // check if canStartAward()\\n for(uint256 pool = 0; pool < prizePools.length; pool++){\\n address prizeStrategy = PrizePoolInterface(prizePools[pool]).prizeStrategy();\\n if(prizeStrategy.canStartAward()){\\n return (true, performData);\\n } \\n }\\n // check if canCompleteAward()\\n for(uint256 pool = 0; pool < prizePools.length; pool++){\\n address prizeStrategy = PrizePoolInterface(prizePools[pool]).prizeStrategy();\\n if(prizeStrategy.canCompleteAward()){\\n return (true, performData);\\n } \\n }\\n return (false, performData);\\n }\\n /// @notice Performs upkeep on the prize pools. \\n /// @param performData Not used in this implementation.\\n function performUpkeep(bytes calldata performData) override external{\\n\\n address[] memory prizePools = PrizePoolRegistryInterface(prizePoolRegistry).getPrizePools();\\n \\n uint256 batchCounter = upkeepBatchSize; //counter for batch\\n uint256 poolIndex = 0;\\n \\n while(batchCounter > 0 && poolIndex < prizePools.length){\\n \\n address prizeStrategy = PrizePoolInterface(prizePools[poolIndex]).prizeStrategy();\\n \\n if(prizeStrategy.canStartAward()){\\n PeriodicPrizeStrategyInterface(prizeStrategy).startAward();\\n batchCounter--;\\n }\\n else if(prizeStrategy.canCompleteAward()){\\n PeriodicPrizeStrategyInterface(prizeStrategy).completeAward();\\n batchCounter--;\\n }\\n poolIndex++; \\n }\\n \\n }\\n\\n}\\n\\n\\n\",\"keccak256\":\"0x3e6dd5b172020ef71dc5f6e2dfee003e276cfe19f920512d89ebf0f016ce0060\",\"license\":\"MIT\"},\"contracts/interfaces/KeeperCompatibleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.7.6;\\n\\ninterface KeeperCompatibleInterface {\\n\\n /**\\n * @notice method that is simulated by the keepers to see if any work actually\\n * needs to be performed. This method does does not actually need to be\\n * executable, and since it is only ever simulated it can consume lots of gas.\\n * @dev To ensure that it is never called, you may want to add the\\n * cannotExecute modifier from KeeperBase to your implementation of this\\n * method.\\n * @param checkData specified in the upkeep registration so it is always the\\n * same for a registered upkeep. This can easily be broken down into specific\\n * arguments using `abi.decode`, so multiple upkeeps can be registered on the\\n * same contract and easily differentiated by the contract.\\n * @return upkeepNeeded boolean to indicate whether the keeper should call\\n * performUpkeep or not.\\n * @return performData bytes that the keeper should call performUpkeep with, if\\n * upkeep is needed. If you would like to encode data to decode later, try\\n * `abi.encode`.\\n */\\n function checkUpkeep(\\n bytes calldata checkData\\n )\\n external\\n returns (\\n bool upkeepNeeded,\\n bytes memory performData\\n );\\n /**\\n * @notice method that is actually executed by the keepers, via the registry.\\n * The data returned by the checkUpkeep simulation will be passed into\\n * this method to actually be executed.\\n * @dev The input to this method should not be trusted, and the caller of the\\n * method should not even be restricted to any single registry. Anyone should\\n * be able call it, and the input should be validated, there is no guarantee\\n * that the data passed in is the performData returned from checkUpkeep. This\\n * could happen due to malicious keepers, racing keepers, or simply a state\\n * change while the performUpkeep transaction is waiting for confirmation.\\n * Always validate the data passed in.\\n * @param performData is the data which was passed back from the checkData\\n * simulation. If it is encoded, it can easily be decoded into other types by\\n * calling `abi.decode`. This data should not be trusted, and should be\\n * validated against the contract's current state.\\n */\\n function performUpkeep(\\n bytes calldata performData\\n ) external;\\n}\",\"keccak256\":\"0x5174919ce142bffa1517f63837e932ce18224d3b4cda828e0d88ff8a5b99d920\",\"license\":\"MIT\"},\"contracts/interfaces/PeriodicPrizeStrategyInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.6;\\n\\ninterface PeriodicPrizeStrategyInterface {\\n function startAward() external;\\n function completeAward() external;\\n function canStartAward() external view returns (bool);\\n function canCompleteAward() external view returns (bool);\\n}\",\"keccak256\":\"0x109f0a01f57f08936e7bb94fe357fa71e7237794f6f8576c37c773a80dcd155f\",\"license\":\"MIT\"},\"contracts/interfaces/PrizePoolInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.6;\\n\\ninterface PrizePoolInterface {\\n function prizeStrategy() external returns (address);\\n}\",\"keccak256\":\"0xdebf90b28b22d82ca90297dc816a0248a7dbf52168f6a032dc68c80f85ebc42c\",\"license\":\"MIT\"},\"contracts/interfaces/PrizePoolRegistryInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.6;\\n\\ninterface PrizePoolRegistryInterface {\\n function getPrizePools() external returns(address[] memory);\\n}\",\"keccak256\":\"0xc88c04d1fce84ed2d89aa47bb0c25bf880448c97c567b6ac40bc69d515803b75\",\"license\":\"MIT\"},\"contracts/utils/SafeAwardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.6;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../interfaces/PeriodicPrizeStrategyInterface.sol\\\";\\n\\n\\n///@notice Wrapper library for address that checks that the address supports canStartAward() and canCompleteAward() before calling\\nlibrary SafeAwardable{\\n\\n ///@return canCompleteAward returns true if the function is supported AND can be completed \\n function canCompleteAward(address self) internal returns (bool canCompleteAward){\\n if(supportsFunction(self, PeriodicPrizeStrategyInterface.canCompleteAward.selector)){\\n return PeriodicPrizeStrategyInterface(self).canCompleteAward(); \\n }\\n return false;\\n }\\n\\n ///@return canStartAward returns true if the function is supported AND can be started, false otherwise\\n function canStartAward(address self) internal returns (bool canStartAward){\\n if(supportsFunction(self, PeriodicPrizeStrategyInterface.canStartAward.selector)){\\n return PeriodicPrizeStrategyInterface(self).canStartAward();\\n }\\n return false;\\n }\\n \\n ///@param selector is the function selector to check against\\n ///@return success returns true if function is implemented, false otherwise\\n function supportsFunction(address self, bytes4 selector) internal returns (bool success){\\n bytes memory encodedParams = abi.encodeWithSelector(selector);\\n (bool success, bytes memory result) = self.staticcall{ gas: 30000 }(encodedParams);\\n if (result.length < 32){\\n return (false);\\n }\\n if(!success && result.length > 0){\\n revert(string(result));\\n }\\n return (success);\\n }\\n}\",\"keccak256\":\"0x5f93fc3698d9ebb18c6202f8adeb21ebb9d1fa6387db5f23391ce490e8a337d6\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50604051610a14380380610a1483398101604081905261002f91610058565b600080546001600160a01b0319166001600160a01b039390931692909217909155600155610090565b6000806040838503121561006a578182fd5b82516001600160a01b0381168114610080578283fd5b6020939093015192949293505050565b6109758061009f6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80632dc41821146100515780634585e33b1461006f5780636e04ff0d14610084578063ad06337f146100a5575b600080fd5b6100596100ba565b6040516100669190610906565b60405180910390f35b61008261007d366004610807565b6100c0565b005b610097610092366004610807565b6102ee565b6040516100669291906108d0565b6100ad610514565b60405161006691906108bc565b60015481565b60008060009054906101000a90046001600160a01b03166001600160a01b031663a28e62196040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561011157600080fd5b505af1158015610125573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261014d9190810190610732565b60015490915060005b6000821180156101665750825181105b156102e757600083828151811061017957fe5b60200260200101516001600160a01b03166398bf3eb66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156101bb57600080fd5b505af11580156101cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101f39190610711565b9050610207816001600160a01b0316610523565b1561026c57806001600160a01b031663b9ee1e056040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561024757600080fd5b505af115801561025b573d6000803e3d6000fd5b505060001990940193506102de9050565b61027e816001600160a01b03166105bc565b156102de57806001600160a01b031663dfb2f13b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102be57600080fd5b505af11580156102d2573d6000803e3d6000fd5b50506000199094019350505b50600101610156565b5050505050565b6000606060008060009054906101000a90046001600160a01b03166001600160a01b031663a28e62196040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561034357600080fd5b505af1158015610357573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261037f9190810190610732565b905060005b815181101561044357600082828151811061039b57fe5b60200260200101516001600160a01b03166398bf3eb66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156103dd57600080fd5b505af11580156103f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104159190610711565b9050610429816001600160a01b0316610523565b1561043a576001945050505061050d565b50600101610384565b5060005b815181101561050657600082828151811061045e57fe5b60200260200101516001600160a01b03166398bf3eb66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156104a057600080fd5b505af11580156104b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d89190610711565b90506104ec816001600160a01b03166105bc565b156104fd576001945050505061050d565b50600101610447565b5060009250505b9250929050565b6000546001600160a01b031681565b6000610536826343b7ae3f60e11b61060d565b156105b357816001600160a01b031663876f5c7e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561057457600080fd5b505afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac91906107e7565b90506105b7565b5060005b919050565b60006105cf82636a74f10760e01b61060d565b156105b357816001600160a01b0316636a74f1076040518163ffffffff1660e01b815260040160206040518083038186803b15801561057457600080fd5b60408051600481526024810182526020810180516001600160e01b03166001600160e01b03198516179052905160009190829081906001600160a01b038716906175309061065c9086906108a0565b6000604051808303818686fa925050503d8060008114610698576040519150601f19603f3d011682016040523d82523d6000602084013e61069d565b606091505b50915091506020815110156106b857600093505050506106f4565b811580156106c7575060008151115b156106ef578060405162461bcd60e51b81526004016106e691906108f3565b60405180910390fd5b509150505b92915050565b80516001600160a01b03811681146105b757600080fd5b600060208284031215610722578081fd5b61072b826106fa565b9392505050565b60006020808385031215610744578182fd5b825167ffffffffffffffff8082111561075b578384fd5b818501915085601f83011261076e578384fd5b81518181111561077a57fe5b8381026040518582820101818110858211171561079357fe5b604052828152858101935084860182860187018a10156107b1578788fd5b8795505b838610156107da576107c6816106fa565b8552600195909501949386019386016107b5565b5098975050505050505050565b6000602082840312156107f8578081fd5b8151801515811461072b578182fd5b60008060208385031215610819578081fd5b823567ffffffffffffffff80821115610830578283fd5b818501915085601f830112610843578283fd5b813581811115610851578384fd5b866020828501011115610862578384fd5b60209290920196919550909350505050565b6000815180845261088c81602086016020860161090f565b601f01601f19169290920160200192915050565b600082516108b281846020870161090f565b9190910192915050565b6001600160a01b0391909116815260200190565b60008315158252604060208301526108eb6040830184610874565b949350505050565b60006020825261072b6020830184610874565b90815260200190565b60005b8381101561092a578181015183820152602001610912565b83811115610939576000848401525b5050505056fea2646970667358221220584bcdbd005e7d5ca8c39069fb7523605719692b1c8f07f7699f7cef60140eff64736f6c63430007060033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632dc41821146100515780634585e33b1461006f5780636e04ff0d14610084578063ad06337f146100a5575b600080fd5b6100596100ba565b6040516100669190610906565b60405180910390f35b61008261007d366004610807565b6100c0565b005b610097610092366004610807565b6102ee565b6040516100669291906108d0565b6100ad610514565b60405161006691906108bc565b60015481565b60008060009054906101000a90046001600160a01b03166001600160a01b031663a28e62196040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561011157600080fd5b505af1158015610125573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261014d9190810190610732565b60015490915060005b6000821180156101665750825181105b156102e757600083828151811061017957fe5b60200260200101516001600160a01b03166398bf3eb66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156101bb57600080fd5b505af11580156101cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101f39190610711565b9050610207816001600160a01b0316610523565b1561026c57806001600160a01b031663b9ee1e056040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561024757600080fd5b505af115801561025b573d6000803e3d6000fd5b505060001990940193506102de9050565b61027e816001600160a01b03166105bc565b156102de57806001600160a01b031663dfb2f13b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102be57600080fd5b505af11580156102d2573d6000803e3d6000fd5b50506000199094019350505b50600101610156565b5050505050565b6000606060008060009054906101000a90046001600160a01b03166001600160a01b031663a28e62196040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561034357600080fd5b505af1158015610357573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261037f9190810190610732565b905060005b815181101561044357600082828151811061039b57fe5b60200260200101516001600160a01b03166398bf3eb66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156103dd57600080fd5b505af11580156103f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104159190610711565b9050610429816001600160a01b0316610523565b1561043a576001945050505061050d565b50600101610384565b5060005b815181101561050657600082828151811061045e57fe5b60200260200101516001600160a01b03166398bf3eb66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156104a057600080fd5b505af11580156104b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d89190610711565b90506104ec816001600160a01b03166105bc565b156104fd576001945050505061050d565b50600101610447565b5060009250505b9250929050565b6000546001600160a01b031681565b6000610536826343b7ae3f60e11b61060d565b156105b357816001600160a01b031663876f5c7e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561057457600080fd5b505afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac91906107e7565b90506105b7565b5060005b919050565b60006105cf82636a74f10760e01b61060d565b156105b357816001600160a01b0316636a74f1076040518163ffffffff1660e01b815260040160206040518083038186803b15801561057457600080fd5b60408051600481526024810182526020810180516001600160e01b03166001600160e01b03198516179052905160009190829081906001600160a01b038716906175309061065c9086906108a0565b6000604051808303818686fa925050503d8060008114610698576040519150601f19603f3d011682016040523d82523d6000602084013e61069d565b606091505b50915091506020815110156106b857600093505050506106f4565b811580156106c7575060008151115b156106ef578060405162461bcd60e51b81526004016106e691906108f3565b60405180910390fd5b509150505b92915050565b80516001600160a01b03811681146105b757600080fd5b600060208284031215610722578081fd5b61072b826106fa565b9392505050565b60006020808385031215610744578182fd5b825167ffffffffffffffff8082111561075b578384fd5b818501915085601f83011261076e578384fd5b81518181111561077a57fe5b8381026040518582820101818110858211171561079357fe5b604052828152858101935084860182860187018a10156107b1578788fd5b8795505b838610156107da576107c6816106fa565b8552600195909501949386019386016107b5565b5098975050505050505050565b6000602082840312156107f8578081fd5b8151801515811461072b578182fd5b60008060208385031215610819578081fd5b823567ffffffffffffffff80821115610830578283fd5b818501915085601f830112610843578283fd5b813581811115610851578384fd5b866020828501011115610862578384fd5b60209290920196919550909350505050565b6000815180845261088c81602086016020860161090f565b601f01601f19169290920160200192915050565b600082516108b281846020870161090f565b9190910192915050565b6001600160a01b0391909116815260200190565b60008315158252604060208301526108eb6040830184610874565b949350505050565b60006020825261072b6020830184610874565b90815260200190565b60005b8381101561092a578181015183820152602001610912565b83811115610939576000848401525b5050505056fea2646970667358221220584bcdbd005e7d5ca8c39069fb7523605719692b1c8f07f7699f7cef60140eff64736f6c63430007060033", + "solcInputHash": "20d3358fd77b25249d09dbdeb2d71edd", + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_prizePoolRegistry\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_upkeepBatchSize\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"prizePoolRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepBatchSize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"checkUpkeep(bytes)\":{\"params\":{\"checkData\":\"Not used in this implementation.\"},\"returns\":{\"upkeepNeeded\":\"as true if performUpkeep() needs to be called, false otherwise. performData returned empty. \"}},\"performUpkeep(bytes)\":{\"params\":{\"performData\":\"Not used in this implementation.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"checkUpkeep(bytes)\":{\"notice\":\"Checks if PrizePools require upkeep. Call in a static manner every block by the Chainlink Upkeep network.\"},\"performUpkeep(bytes)\":{\"notice\":\"Performs upkeep on the prize pools. \"}},\"notice\":\"Contract implements Chainlink's Upkeep system interface, automating the upkeep of PrizePools in the associated registry. \",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/PrizeStrategyUpkeep.sol\":\"PrizeStrategyUpkeep\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/PrizeStrategyUpkeep.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.6;\\npragma experimental ABIEncoderV2;\\n\\n\\nimport \\\"./interfaces/KeeperCompatibleInterface.sol\\\";\\nimport \\\"./interfaces/PeriodicPrizeStrategyInterface.sol\\\";\\nimport \\\"./interfaces/PrizePoolRegistryInterface.sol\\\";\\nimport \\\"./interfaces/PrizePoolInterface.sol\\\";\\nimport \\\"./utils/SafeAwardable.sol\\\";\\n\\n\\n///@notice Contract implements Chainlink's Upkeep system interface, automating the upkeep of PrizePools in the associated registry. \\ncontract PrizeStrategyUpkeep is KeeperCompatibleInterface {\\n\\n using SafeAwardable for address;\\n\\n address public prizePoolRegistry;\\n\\n uint public upkeepBatchSize;\\n \\n constructor(address _prizePoolRegistry, uint256 _upkeepBatchSize) public {\\n prizePoolRegistry = _prizePoolRegistry;\\n upkeepBatchSize = _upkeepBatchSize;\\n }\\n\\n /// @notice Checks if PrizePools require upkeep. Call in a static manner every block by the Chainlink Upkeep network.\\n /// @param checkData Not used in this implementation.\\n /// @return upkeepNeeded as true if performUpkeep() needs to be called, false otherwise. performData returned empty. \\n function checkUpkeep(bytes calldata checkData) view override external returns (bool upkeepNeeded, bytes memory performData){ // check view\\n\\n address[] memory prizePools = PrizePoolRegistryInterface(prizePoolRegistry).getPrizePools();\\n\\n // check if canStartAward()\\n for(uint256 pool = 0; pool < prizePools.length; pool++){\\n address prizeStrategy = PrizePoolInterface(prizePools[pool]).prizeStrategy();\\n if(prizeStrategy.canStartAward()){\\n return (true, performData);\\n } \\n }\\n // check if canCompleteAward()\\n for(uint256 pool = 0; pool < prizePools.length; pool++){\\n address prizeStrategy = PrizePoolInterface(prizePools[pool]).prizeStrategy();\\n if(prizeStrategy.canCompleteAward()){\\n return (true, performData);\\n } \\n }\\n return (false, performData);\\n }\\n /// @notice Performs upkeep on the prize pools. \\n /// @param performData Not used in this implementation.\\n function performUpkeep(bytes calldata performData) override external{\\n\\n address[] memory prizePools = PrizePoolRegistryInterface(prizePoolRegistry).getPrizePools();\\n \\n uint256 batchCounter = upkeepBatchSize; //counter for batch\\n uint256 poolIndex = 0;\\n \\n while(batchCounter > 0 && poolIndex < prizePools.length){\\n \\n address prizeStrategy = PrizePoolInterface(prizePools[poolIndex]).prizeStrategy();\\n \\n if(prizeStrategy.canStartAward()){\\n PeriodicPrizeStrategyInterface(prizeStrategy).startAward();\\n batchCounter--;\\n }\\n else if(prizeStrategy.canCompleteAward()){\\n PeriodicPrizeStrategyInterface(prizeStrategy).completeAward();\\n batchCounter--;\\n }\\n poolIndex++; \\n }\\n \\n }\\n\\n}\\n\\n\\n\",\"keccak256\":\"0xac4ba5bc9cd9f86b5ae3e2e8a18f8a49fa2606a8035019769ca482ffaed42a4e\",\"license\":\"MIT\"},\"contracts/interfaces/KeeperCompatibleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.7.6;\\n\\ninterface KeeperCompatibleInterface {\\n\\n /**\\n * @notice method that is simulated by the keepers to see if any work actually\\n * needs to be performed. This method does does not actually need to be\\n * executable, and since it is only ever simulated it can consume lots of gas.\\n * @dev To ensure that it is never called, you may want to add the\\n * cannotExecute modifier from KeeperBase to your implementation of this\\n * method.\\n * @param checkData specified in the upkeep registration so it is always the\\n * same for a registered upkeep. This can easily be broken down into specific\\n * arguments using `abi.decode`, so multiple upkeeps can be registered on the\\n * same contract and easily differentiated by the contract.\\n * @return upkeepNeeded boolean to indicate whether the keeper should call\\n * performUpkeep or not.\\n * @return performData bytes that the keeper should call performUpkeep with, if\\n * upkeep is needed. If you would like to encode data to decode later, try\\n * `abi.encode`.\\n */\\n function checkUpkeep(\\n bytes calldata checkData\\n )\\n external\\n returns (\\n bool upkeepNeeded,\\n bytes memory performData\\n );\\n /**\\n * @notice method that is actually executed by the keepers, via the registry.\\n * The data returned by the checkUpkeep simulation will be passed into\\n * this method to actually be executed.\\n * @dev The input to this method should not be trusted, and the caller of the\\n * method should not even be restricted to any single registry. Anyone should\\n * be able call it, and the input should be validated, there is no guarantee\\n * that the data passed in is the performData returned from checkUpkeep. This\\n * could happen due to malicious keepers, racing keepers, or simply a state\\n * change while the performUpkeep transaction is waiting for confirmation.\\n * Always validate the data passed in.\\n * @param performData is the data which was passed back from the checkData\\n * simulation. If it is encoded, it can easily be decoded into other types by\\n * calling `abi.decode`. This data should not be trusted, and should be\\n * validated against the contract's current state.\\n */\\n function performUpkeep(\\n bytes calldata performData\\n ) external;\\n}\",\"keccak256\":\"0x5174919ce142bffa1517f63837e932ce18224d3b4cda828e0d88ff8a5b99d920\",\"license\":\"MIT\"},\"contracts/interfaces/PeriodicPrizeStrategyInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.6;\\n\\ninterface PeriodicPrizeStrategyInterface {\\n function startAward() external;\\n function completeAward() external;\\n function canStartAward() external view returns (bool);\\n function canCompleteAward() external view returns (bool);\\n}\",\"keccak256\":\"0x109f0a01f57f08936e7bb94fe357fa71e7237794f6f8576c37c773a80dcd155f\",\"license\":\"MIT\"},\"contracts/interfaces/PrizePoolInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.6;\\n\\ninterface PrizePoolInterface {\\n function prizeStrategy() external view returns (address);\\n}\",\"keccak256\":\"0x25c3deefae7b4f2270303b5646e28f49922853ae946173ca2032173bd1844210\",\"license\":\"MIT\"},\"contracts/interfaces/PrizePoolRegistryInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.6;\\n\\ninterface PrizePoolRegistryInterface {\\n function getPrizePools() external view returns(address[] memory);\\n}\",\"keccak256\":\"0x620c3e31149cdf62170e43f825aa8802a87ce7e677cd6c0c1c0722e45e6fe8ed\",\"license\":\"MIT\"},\"contracts/utils/SafeAwardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.6;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../interfaces/PeriodicPrizeStrategyInterface.sol\\\";\\n\\n\\n///@notice Wrapper library for address that checks that the address supports canStartAward() and canCompleteAward() before calling\\nlibrary SafeAwardable{\\n\\n ///@return canCompleteAward returns true if the function is supported AND can be completed \\n function canCompleteAward(address self) internal view returns (bool canCompleteAward){\\n if(supportsFunction(self, PeriodicPrizeStrategyInterface.canCompleteAward.selector)){\\n return PeriodicPrizeStrategyInterface(self).canCompleteAward(); \\n }\\n return false;\\n }\\n\\n ///@return canStartAward returns true if the function is supported AND can be started, false otherwise\\n function canStartAward(address self) internal view returns (bool canStartAward){\\n if(supportsFunction(self, PeriodicPrizeStrategyInterface.canStartAward.selector)){\\n return PeriodicPrizeStrategyInterface(self).canStartAward();\\n }\\n return false;\\n }\\n \\n ///@param selector is the function selector to check against\\n ///@return success returns true if function is implemented, false otherwise\\n function supportsFunction(address self, bytes4 selector) internal view returns (bool success){\\n bytes memory encodedParams = abi.encodeWithSelector(selector);\\n (bool success, bytes memory result) = self.staticcall{ gas: 30000 }(encodedParams);\\n if (result.length < 32){\\n return (false);\\n }\\n if(!success && result.length > 0){\\n revert(string(result));\\n }\\n return (success);\\n }\\n}\",\"keccak256\":\"0xf5e2d50a8057812732975074254054c6b7717a97f34ec9be494a4c86663137e5\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610a0a380380610a0a83398101604081905261002f91610058565b600080546001600160a01b0319166001600160a01b039390931692909217909155600155610090565b6000806040838503121561006a578182fd5b82516001600160a01b0381168114610080578283fd5b6020939093015192949293505050565b61096b8061009f6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80632dc41821146100515780634585e33b1461006f5780636e04ff0d14610084578063ad06337f146100a5575b600080fd5b6100596100ba565b60405161006691906108fc565b60405180910390f35b61008261007d3660046107fd565b6100c0565b005b6100976100923660046107fd565b6102ea565b6040516100669291906108c6565b6100ad61050a565b60405161006691906108b2565b60015481565b60008060009054906101000a90046001600160a01b03166001600160a01b031663a28e62196040518163ffffffff1660e01b815260040160006040518083038186803b15801561010f57600080fd5b505afa158015610123573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261014b9190810190610728565b60015490915060005b6000821180156101645750825181105b156102e357600083828151811061017757fe5b60200260200101516001600160a01b03166398bf3eb66040518163ffffffff1660e01b815260040160206040518083038186803b1580156101b757600080fd5b505afa1580156101cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101ef9190610707565b9050610203816001600160a01b0316610519565b1561026857806001600160a01b031663b9ee1e056040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561024357600080fd5b505af1158015610257573d6000803e3d6000fd5b505060001990940193506102da9050565b61027a816001600160a01b03166105b2565b156102da57806001600160a01b031663dfb2f13b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102ba57600080fd5b505af11580156102ce573d6000803e3d6000fd5b50506000199094019350505b50600101610154565b5050505050565b6000606060008060009054906101000a90046001600160a01b03166001600160a01b031663a28e62196040518163ffffffff1660e01b815260040160006040518083038186803b15801561033d57600080fd5b505afa158015610351573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103799190810190610728565b905060005b815181101561043b57600082828151811061039557fe5b60200260200101516001600160a01b03166398bf3eb66040518163ffffffff1660e01b815260040160206040518083038186803b1580156103d557600080fd5b505afa1580156103e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040d9190610707565b9050610421816001600160a01b0316610519565b156104325760019450505050610503565b5060010161037e565b5060005b81518110156104fc57600082828151811061045657fe5b60200260200101516001600160a01b03166398bf3eb66040518163ffffffff1660e01b815260040160206040518083038186803b15801561049657600080fd5b505afa1580156104aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ce9190610707565b90506104e2816001600160a01b03166105b2565b156104f35760019450505050610503565b5060010161043f565b5060009250505b9250929050565b6000546001600160a01b031681565b600061052c826343b7ae3f60e11b610603565b156105a957816001600160a01b031663876f5c7e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561056a57600080fd5b505afa15801561057e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a291906107dd565b90506105ad565b5060005b919050565b60006105c582636a74f10760e01b610603565b156105a957816001600160a01b0316636a74f1076040518163ffffffff1660e01b815260040160206040518083038186803b15801561056a57600080fd5b60408051600481526024810182526020810180516001600160e01b03166001600160e01b03198516179052905160009190829081906001600160a01b0387169061753090610652908690610896565b6000604051808303818686fa925050503d806000811461068e576040519150601f19603f3d011682016040523d82523d6000602084013e610693565b606091505b50915091506020815110156106ae57600093505050506106ea565b811580156106bd575060008151115b156106e5578060405162461bcd60e51b81526004016106dc91906108e9565b60405180910390fd5b509150505b92915050565b80516001600160a01b03811681146105ad57600080fd5b600060208284031215610718578081fd5b610721826106f0565b9392505050565b6000602080838503121561073a578182fd5b825167ffffffffffffffff80821115610751578384fd5b818501915085601f830112610764578384fd5b81518181111561077057fe5b8381026040518582820101818110858211171561078957fe5b604052828152858101935084860182860187018a10156107a7578788fd5b8795505b838610156107d0576107bc816106f0565b8552600195909501949386019386016107ab565b5098975050505050505050565b6000602082840312156107ee578081fd5b81518015158114610721578182fd5b6000806020838503121561080f578081fd5b823567ffffffffffffffff80821115610826578283fd5b818501915085601f830112610839578283fd5b813581811115610847578384fd5b866020828501011115610858578384fd5b60209290920196919550909350505050565b60008151808452610882816020860160208601610905565b601f01601f19169290920160200192915050565b600082516108a8818460208701610905565b9190910192915050565b6001600160a01b0391909116815260200190565b60008315158252604060208301526108e1604083018461086a565b949350505050565b600060208252610721602083018461086a565b90815260200190565b60005b83811015610920578181015183820152602001610908565b8381111561092f576000848401525b5050505056fea2646970667358221220284a45238fc96aca0313f43e0dfaeb7fed8259a5e229b35ba6d07c17c26e8d2564736f6c63430007060033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632dc41821146100515780634585e33b1461006f5780636e04ff0d14610084578063ad06337f146100a5575b600080fd5b6100596100ba565b60405161006691906108fc565b60405180910390f35b61008261007d3660046107fd565b6100c0565b005b6100976100923660046107fd565b6102ea565b6040516100669291906108c6565b6100ad61050a565b60405161006691906108b2565b60015481565b60008060009054906101000a90046001600160a01b03166001600160a01b031663a28e62196040518163ffffffff1660e01b815260040160006040518083038186803b15801561010f57600080fd5b505afa158015610123573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261014b9190810190610728565b60015490915060005b6000821180156101645750825181105b156102e357600083828151811061017757fe5b60200260200101516001600160a01b03166398bf3eb66040518163ffffffff1660e01b815260040160206040518083038186803b1580156101b757600080fd5b505afa1580156101cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101ef9190610707565b9050610203816001600160a01b0316610519565b1561026857806001600160a01b031663b9ee1e056040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561024357600080fd5b505af1158015610257573d6000803e3d6000fd5b505060001990940193506102da9050565b61027a816001600160a01b03166105b2565b156102da57806001600160a01b031663dfb2f13b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102ba57600080fd5b505af11580156102ce573d6000803e3d6000fd5b50506000199094019350505b50600101610154565b5050505050565b6000606060008060009054906101000a90046001600160a01b03166001600160a01b031663a28e62196040518163ffffffff1660e01b815260040160006040518083038186803b15801561033d57600080fd5b505afa158015610351573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103799190810190610728565b905060005b815181101561043b57600082828151811061039557fe5b60200260200101516001600160a01b03166398bf3eb66040518163ffffffff1660e01b815260040160206040518083038186803b1580156103d557600080fd5b505afa1580156103e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040d9190610707565b9050610421816001600160a01b0316610519565b156104325760019450505050610503565b5060010161037e565b5060005b81518110156104fc57600082828151811061045657fe5b60200260200101516001600160a01b03166398bf3eb66040518163ffffffff1660e01b815260040160206040518083038186803b15801561049657600080fd5b505afa1580156104aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ce9190610707565b90506104e2816001600160a01b03166105b2565b156104f35760019450505050610503565b5060010161043f565b5060009250505b9250929050565b6000546001600160a01b031681565b600061052c826343b7ae3f60e11b610603565b156105a957816001600160a01b031663876f5c7e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561056a57600080fd5b505afa15801561057e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a291906107dd565b90506105ad565b5060005b919050565b60006105c582636a74f10760e01b610603565b156105a957816001600160a01b0316636a74f1076040518163ffffffff1660e01b815260040160206040518083038186803b15801561056a57600080fd5b60408051600481526024810182526020810180516001600160e01b03166001600160e01b03198516179052905160009190829081906001600160a01b0387169061753090610652908690610896565b6000604051808303818686fa925050503d806000811461068e576040519150601f19603f3d011682016040523d82523d6000602084013e610693565b606091505b50915091506020815110156106ae57600093505050506106ea565b811580156106bd575060008151115b156106e5578060405162461bcd60e51b81526004016106dc91906108e9565b60405180910390fd5b509150505b92915050565b80516001600160a01b03811681146105ad57600080fd5b600060208284031215610718578081fd5b610721826106f0565b9392505050565b6000602080838503121561073a578182fd5b825167ffffffffffffffff80821115610751578384fd5b818501915085601f830112610764578384fd5b81518181111561077057fe5b8381026040518582820101818110858211171561078957fe5b604052828152858101935084860182860187018a10156107a7578788fd5b8795505b838610156107d0576107bc816106f0565b8552600195909501949386019386016107ab565b5098975050505050505050565b6000602082840312156107ee578081fd5b81518015158114610721578182fd5b6000806020838503121561080f578081fd5b823567ffffffffffffffff80821115610826578283fd5b818501915085601f830112610839578283fd5b813581811115610847578384fd5b866020828501011115610858578384fd5b60209290920196919550909350505050565b60008151808452610882816020860160208601610905565b601f01601f19169290920160200192915050565b600082516108a8818460208701610905565b9190910192915050565b6001600160a01b0391909116815260200190565b60008315158252604060208301526108e1604083018461086a565b949350505050565b600060208252610721602083018461086a565b90815260200190565b60005b83811015610920578181015183820152602001610908565b8381111561092f576000848401525b5050505056fea2646970667358221220284a45238fc96aca0313f43e0dfaeb7fed8259a5e229b35ba6d07c17c26e8d2564736f6c63430007060033", "devdoc": { "kind": "dev", "methods": { diff --git a/deployments/kovan/solcInputs/20d3358fd77b25249d09dbdeb2d71edd.json b/deployments/kovan/solcInputs/20d3358fd77b25249d09dbdeb2d71edd.json new file mode 100644 index 0000000..dd0045c --- /dev/null +++ b/deployments/kovan/solcInputs/20d3358fd77b25249d09dbdeb2d71edd.json @@ -0,0 +1,66 @@ +{ + "language": "Solidity", + "sources": { + "contracts/interfaces/KeeperCompatibleInterface.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.7.6;\n\ninterface KeeperCompatibleInterface {\n\n /**\n * @notice method that is simulated by the keepers to see if any work actually\n * needs to be performed. This method does does not actually need to be\n * executable, and since it is only ever simulated it can consume lots of gas.\n * @dev To ensure that it is never called, you may want to add the\n * cannotExecute modifier from KeeperBase to your implementation of this\n * method.\n * @param checkData specified in the upkeep registration so it is always the\n * same for a registered upkeep. This can easily be broken down into specific\n * arguments using `abi.decode`, so multiple upkeeps can be registered on the\n * same contract and easily differentiated by the contract.\n * @return upkeepNeeded boolean to indicate whether the keeper should call\n * performUpkeep or not.\n * @return performData bytes that the keeper should call performUpkeep with, if\n * upkeep is needed. If you would like to encode data to decode later, try\n * `abi.encode`.\n */\n function checkUpkeep(\n bytes calldata checkData\n )\n external\n returns (\n bool upkeepNeeded,\n bytes memory performData\n );\n /**\n * @notice method that is actually executed by the keepers, via the registry.\n * The data returned by the checkUpkeep simulation will be passed into\n * this method to actually be executed.\n * @dev The input to this method should not be trusted, and the caller of the\n * method should not even be restricted to any single registry. Anyone should\n * be able call it, and the input should be validated, there is no guarantee\n * that the data passed in is the performData returned from checkUpkeep. This\n * could happen due to malicious keepers, racing keepers, or simply a state\n * change while the performUpkeep transaction is waiting for confirmation.\n * Always validate the data passed in.\n * @param performData is the data which was passed back from the checkData\n * simulation. If it is encoded, it can easily be decoded into other types by\n * calling `abi.decode`. This data should not be trusted, and should be\n * validated against the contract's current state.\n */\n function performUpkeep(\n bytes calldata performData\n ) external;\n}" + }, + "contracts/PrizeStrategyUpkeep.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\n\nimport \"./interfaces/KeeperCompatibleInterface.sol\";\nimport \"./interfaces/PeriodicPrizeStrategyInterface.sol\";\nimport \"./interfaces/PrizePoolRegistryInterface.sol\";\nimport \"./interfaces/PrizePoolInterface.sol\";\nimport \"./utils/SafeAwardable.sol\";\n\n\n///@notice Contract implements Chainlink's Upkeep system interface, automating the upkeep of PrizePools in the associated registry. \ncontract PrizeStrategyUpkeep is KeeperCompatibleInterface {\n\n using SafeAwardable for address;\n\n address public prizePoolRegistry;\n\n uint public upkeepBatchSize;\n \n constructor(address _prizePoolRegistry, uint256 _upkeepBatchSize) public {\n prizePoolRegistry = _prizePoolRegistry;\n upkeepBatchSize = _upkeepBatchSize;\n }\n\n /// @notice Checks if PrizePools require upkeep. Call in a static manner every block by the Chainlink Upkeep network.\n /// @param checkData Not used in this implementation.\n /// @return upkeepNeeded as true if performUpkeep() needs to be called, false otherwise. performData returned empty. \n function checkUpkeep(bytes calldata checkData) view override external returns (bool upkeepNeeded, bytes memory performData){ // check view\n\n address[] memory prizePools = PrizePoolRegistryInterface(prizePoolRegistry).getPrizePools();\n\n // check if canStartAward()\n for(uint256 pool = 0; pool < prizePools.length; pool++){\n address prizeStrategy = PrizePoolInterface(prizePools[pool]).prizeStrategy();\n if(prizeStrategy.canStartAward()){\n return (true, performData);\n } \n }\n // check if canCompleteAward()\n for(uint256 pool = 0; pool < prizePools.length; pool++){\n address prizeStrategy = PrizePoolInterface(prizePools[pool]).prizeStrategy();\n if(prizeStrategy.canCompleteAward()){\n return (true, performData);\n } \n }\n return (false, performData);\n }\n /// @notice Performs upkeep on the prize pools. \n /// @param performData Not used in this implementation.\n function performUpkeep(bytes calldata performData) override external{\n\n address[] memory prizePools = PrizePoolRegistryInterface(prizePoolRegistry).getPrizePools();\n \n uint256 batchCounter = upkeepBatchSize; //counter for batch\n uint256 poolIndex = 0;\n \n while(batchCounter > 0 && poolIndex < prizePools.length){\n \n address prizeStrategy = PrizePoolInterface(prizePools[poolIndex]).prizeStrategy();\n \n if(prizeStrategy.canStartAward()){\n PeriodicPrizeStrategyInterface(prizeStrategy).startAward();\n batchCounter--;\n }\n else if(prizeStrategy.canCompleteAward()){\n PeriodicPrizeStrategyInterface(prizeStrategy).completeAward();\n batchCounter--;\n }\n poolIndex++; \n }\n \n }\n\n}\n\n\n" + }, + "contracts/interfaces/PeriodicPrizeStrategyInterface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.6;\n\ninterface PeriodicPrizeStrategyInterface {\n function startAward() external;\n function completeAward() external;\n function canStartAward() external view returns (bool);\n function canCompleteAward() external view returns (bool);\n}" + }, + "contracts/interfaces/PrizePoolRegistryInterface.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.6;\n\ninterface PrizePoolRegistryInterface {\n function getPrizePools() external view returns(address[] memory);\n}" + }, + "contracts/interfaces/PrizePoolInterface.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.6;\n\ninterface PrizePoolInterface {\n function prizeStrategy() external view returns (address);\n}" + }, + "contracts/utils/SafeAwardable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/PeriodicPrizeStrategyInterface.sol\";\n\n\n///@notice Wrapper library for address that checks that the address supports canStartAward() and canCompleteAward() before calling\nlibrary SafeAwardable{\n\n ///@return canCompleteAward returns true if the function is supported AND can be completed \n function canCompleteAward(address self) internal view returns (bool canCompleteAward){\n if(supportsFunction(self, PeriodicPrizeStrategyInterface.canCompleteAward.selector)){\n return PeriodicPrizeStrategyInterface(self).canCompleteAward(); \n }\n return false;\n }\n\n ///@return canStartAward returns true if the function is supported AND can be started, false otherwise\n function canStartAward(address self) internal view returns (bool canStartAward){\n if(supportsFunction(self, PeriodicPrizeStrategyInterface.canStartAward.selector)){\n return PeriodicPrizeStrategyInterface(self).canStartAward();\n }\n return false;\n }\n \n ///@param selector is the function selector to check against\n ///@return success returns true if function is implemented, false otherwise\n function supportsFunction(address self, bytes4 selector) internal view returns (bool success){\n bytes memory encodedParams = abi.encodeWithSelector(selector);\n (bool success, bytes memory result) = self.staticcall{ gas: 30000 }(encodedParams);\n if (result.length < 32){\n return (false);\n }\n if(!success && result.length > 0){\n revert(string(result));\n }\n return (success);\n }\n}" + }, + "contracts/PrizePoolRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./interfaces/KeeperCompatibleInterface.sol\";\nimport \"./interfaces/PeriodicPrizeStrategyInterface.sol\";\nimport \"./interfaces/PrizePoolInterface.sol\";\nimport \"./utils/MappedSinglyLinkedList.sol\";\n\n\n\n///@notice A registry to hold Prize Pool addresses. Underlying data structure is a singly linked list. \ncontract PrizePoolRegistry is Ownable {\n\n using MappedSinglyLinkedList for MappedSinglyLinkedList.Mapping;\n\n event PrizePoolAdded(address indexed prizePool);\n event PrizePoolRemoved(address indexed prizePool);\n\n MappedSinglyLinkedList.Mapping internal prizePoolList;\n\n constructor() Ownable(){\n prizePoolList.initialize();\n }\n\n\n /// @notice Returns an array of all prizePools in the linked list\n ///@return Array of prize pool addresses\n function getPrizePools() view external returns(address[] memory){\n return prizePoolList.addressArray();\n } \n\n /// @notice Adds addresses to the linked list. Will revert if the address is already in the list. Can only be called by the Registry owner.\n /// @param _prizePools Array of prizePool addresses\n function addPrizePools(address[] calldata _prizePools) public onlyOwner {\n for(uint256 prizePool = 0; prizePool < _prizePools.length; prizePool++ ){ \n prizePoolList.addAddress(_prizePools[prizePool]);\n emit PrizePoolAdded(_prizePools[prizePool]);\n }\n }\n\n /// @notice Removes an address from the linked list. Can only be called by the Registry owner.\n /// @param _previousPrizePool The address positionally localed before the address that will be deleted. This may be the SENTINEL address if the list contains one prize pool address\n /// @param _prizePool The address to remove from the linked list. \n function removePrizePool(address _previousPrizePool, address _prizePool) public onlyOwner{\n prizePoolList.removeAddress(_previousPrizePool, _prizePool); \n emit PrizePoolRemoved(_prizePool);\n } \n}" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "contracts/utils/MappedSinglyLinkedList.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.7.6;\n\n/// @notice An efficient implementation of a singly linked list of addresses\n/// @dev A mapping(address => address) tracks the 'next' pointer. A special address called the SENTINEL is used to denote the beginning and end of the list.\nlibrary MappedSinglyLinkedList {\n\n /// @notice The special value address used to denote the end of the list\n address public constant SENTINEL = address(0x1);\n\n /// @notice The data structure to use for the list.\n struct Mapping {\n uint256 count;\n\n mapping(address => address) addressMap;\n }\n\n /// @notice Initializes the list.\n /// @dev It is important that this is called so that the SENTINEL is correctly setup.\n function initialize(Mapping storage self) internal {\n require(self.count == 0, \"Already init\");\n self.addressMap[SENTINEL] = SENTINEL;\n }\n\n function start(Mapping storage self) internal view returns (address) {\n return self.addressMap[SENTINEL];\n }\n\n function next(Mapping storage self, address current) internal view returns (address) {\n return self.addressMap[current];\n }\n\n function end(Mapping storage) internal pure returns (address) {\n return SENTINEL;\n }\n\n function addAddresses(Mapping storage self, address[] memory addresses) internal {\n for (uint256 i = 0; i < addresses.length; i++) {\n addAddress(self, addresses[i]);\n }\n }\n\n /// @notice Adds an address to the front of the list.\n /// @param self The Mapping struct that this function is attached to\n /// @param newAddress The address to shift to the front of the list\n function addAddress(Mapping storage self, address newAddress) internal {\n require(newAddress != SENTINEL && newAddress != address(0), \"Invalid address\");\n require(self.addressMap[newAddress] == address(0), \"Already added\");\n self.addressMap[newAddress] = self.addressMap[SENTINEL];\n self.addressMap[SENTINEL] = newAddress;\n self.count = self.count + 1;\n }\n\n /// @notice Removes an address from the list\n /// @param self The Mapping struct that this function is attached to\n /// @param prevAddress The address that precedes the address to be removed. This may be the SENTINEL if at the start.\n /// @param addr The address to remove from the list.\n function removeAddress(Mapping storage self, address prevAddress, address addr) internal {\n require(addr != SENTINEL && addr != address(0), \"Invalid address\");\n require(self.addressMap[prevAddress] == addr, \"Invalid prevAddress\");\n self.addressMap[prevAddress] = self.addressMap[addr];\n delete self.addressMap[addr];\n self.count = self.count - 1;\n }\n\n /// @notice Determines whether the list contains the given address\n /// @param self The Mapping struct that this function is attached to\n /// @param addr The address to check\n /// @return True if the address is contained, false otherwise.\n function contains(Mapping storage self, address addr) internal view returns (bool) {\n return addr != SENTINEL && addr != address(0) && self.addressMap[addr] != address(0);\n }\n\n /// @notice Returns an address array of all the addresses in this list\n /// @dev Contains a for loop, so complexity is O(n) wrt the list size\n /// @param self The Mapping struct that this function is attached to\n /// @return An array of all the addresses\n function addressArray(Mapping storage self) internal view returns (address[] memory) {\n address[] memory array = new address[](self.count);\n uint256 count;\n address currentAddress = self.addressMap[SENTINEL];\n while (currentAddress != address(0) && currentAddress != SENTINEL) {\n array[count] = currentAddress;\n currentAddress = self.addressMap[currentAddress];\n count++;\n }\n return array;\n }\n\n /// @notice Removes every address from the list\n /// @param self The Mapping struct that this function is attached to\n function clearAll(Mapping storage self) internal {\n address currentAddress = self.addressMap[SENTINEL];\n while (currentAddress != address(0) && currentAddress != SENTINEL) {\n address nextAddress = self.addressMap[currentAddress];\n delete self.addressMap[currentAddress];\n currentAddress = nextAddress;\n }\n self.addressMap[SENTINEL] = SENTINEL;\n self.count = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "contracts/test/MappedSinglyLinkedListExposed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.6;\n\nimport \"../utils/MappedSinglyLinkedList.sol\";\n\ncontract MappedSinglyLinkedListExposed {\n using MappedSinglyLinkedList for MappedSinglyLinkedList.Mapping;\n\n MappedSinglyLinkedList.Mapping public list;\n\n function initialize() external {\n list.initialize();\n }\n\n function addressArray() external view returns (address[] memory) {\n return list.addressArray();\n }\n\n function addAddresses(address[] calldata addresses) external {\n list.addAddresses(addresses);\n }\n\n function addAddress(address newAddress) external {\n list.addAddress(newAddress);\n }\n\n function removeAddress(address prevAddress, address addr) external {\n list.removeAddress(prevAddress, addr);\n }\n\n function contains(address addr) external view returns (bool) {\n return list.contains(addr);\n }\n\n function clearAll() external {\n list.clearAll();\n }\n\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "istanbul", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file