Skip to content

Commit

Permalink
Added ERC165 to PeriodicPrizeStrategyListenerInterface
Browse files Browse the repository at this point in the history
  • Loading branch information
asselstine committed Dec 7, 2020
1 parent ccf05d8 commit fc4a436
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 9 deletions.
11 changes: 7 additions & 4 deletions contracts/prize-strategy/PeriodicPrizeStrategy.sol
Expand Up @@ -19,6 +19,7 @@ import "../prize-pool/PrizePool.sol";
import "../Constants.sol";
import "../utils/RelayRecipient.sol";
import "./PeriodicPrizeStrategyListenerInterface.sol";
import "./PeriodicPrizeStrategyListenerLibrary.sol";

/* solium-disable security/no-block-members */
abstract contract PeriodicPrizeStrategy is Initializable,
Expand Down Expand Up @@ -210,8 +211,7 @@ abstract contract PeriodicPrizeStrategy is Initializable,
/// @notice Allows the owner to set the token listener
/// @param _tokenListener A contract that implements the token listener interface.
function setTokenListener(TokenListenerInterface _tokenListener) external onlyOwner requireAwardNotInProgress {
require(address(0) == address(_tokenListener) || address(_tokenListener).isContract(), "PeriodicPrizeStrategy/token-listener-not-contract");
require(address(0) == address(_tokenListener) || address(_tokenListener).supportsInterface(TokenListenerLibrary.ERC165_INTERFACE_ID_TOKEN_LISTENER), "PrizePool/token-listener-invalid");
require(address(0) == address(_tokenListener) || address(_tokenListener).supportsInterface(TokenListenerLibrary.ERC165_INTERFACE_ID_TOKEN_LISTENER), "PeriodicPrizeStrategy/token-listener-invalid");

tokenListener = _tokenListener;

Expand Down Expand Up @@ -396,7 +396,7 @@ abstract contract PeriodicPrizeStrategy is Initializable,

_distribute(randomNumber);
if (address(periodicPrizeStrategyListener) != address(0)) {
periodicPrizeStrategyListener.afterDistributeAwards(randomNumber, prizePeriodStartedAt);
periodicPrizeStrategyListener.afterPrizePoolAwarded(randomNumber, prizePeriodStartedAt);
}

// to avoid clock drift, we should calculate the start time based on the previous period start time.
Expand All @@ -409,7 +409,10 @@ abstract contract PeriodicPrizeStrategy is Initializable,
/// @notice Allows the owner to set a listener for prize strategy callbacks.
/// @param _periodicPrizeStrategyListener The address of the listener contract
function setPeriodicPrizeStrategyListener(PeriodicPrizeStrategyListenerInterface _periodicPrizeStrategyListener) external onlyOwner requireAwardNotInProgress {
require(address(0) == address(_periodicPrizeStrategyListener) || address(_periodicPrizeStrategyListener).isContract(), "PeriodicPrizeStrategy/listener-not-contract");
require(
address(0) == address(_periodicPrizeStrategyListener) || address(_periodicPrizeStrategyListener).supportsInterface(PeriodicPrizeStrategyListenerLibrary.ERC165_INTERFACE_ID_PERIODIC_PRIZE_STRATEGY_LISTENER),
"PeriodicPrizeStrategy/prizeStrategyListener-invalid"
);

periodicPrizeStrategyListener = _periodicPrizeStrategyListener;

Expand Down
14 changes: 14 additions & 0 deletions contracts/prize-strategy/PeriodicPrizeStrategyListener.sol
@@ -0,0 +1,14 @@
pragma solidity ^0.6.12;

import "./PeriodicPrizeStrategyListenerInterface.sol";
import "./PeriodicPrizeStrategyListenerLibrary.sol";
import "../Constants.sol";

abstract contract PeriodicPrizeStrategyListener is PeriodicPrizeStrategyListenerInterface {
function supportsInterface(bytes4 interfaceId) external override view returns (bool) {
return (
interfaceId == Constants.ERC165_INTERFACE_ID_ERC165 ||
interfaceId == PeriodicPrizeStrategyListenerLibrary.ERC165_INTERFACE_ID_PERIODIC_PRIZE_STRATEGY_LISTENER
);
}
}
Expand Up @@ -2,7 +2,9 @@

pragma solidity >=0.6.0 <0.7.0;

import "@openzeppelin/contracts-ethereum-package/contracts/introspection/IERC165.sol";

/* solium-disable security/no-block-members */
interface PeriodicPrizeStrategyListenerInterface {
function afterDistributeAwards(uint256 randomNumber, uint256 prizePeriodStartedAt) external;
interface PeriodicPrizeStrategyListenerInterface is IERC165 {
function afterPrizePoolAwarded(uint256 randomNumber, uint256 prizePeriodStartedAt) external;
}
@@ -0,0 +1,8 @@
pragma solidity ^0.6.12;

library PeriodicPrizeStrategyListenerLibrary {
/*
* bytes4(keccak256('afterPrizePoolAwarded(uint256,uint256)')) == 0x575072c6
*/
bytes4 public constant ERC165_INTERFACE_ID_PERIODIC_PRIZE_STRATEGY_LISTENER = 0x575072c6;
}
10 changes: 7 additions & 3 deletions test/PeriodicPrizeStrategy.test.js
Expand Up @@ -72,6 +72,10 @@ describe('PeriodicPrizeStrategy', function() {

await externalERC721Award.mock.supportsInterface.returns(true)
await externalERC721Award.mock.supportsInterface.withArgs('0xffffffff').returns(false)

await periodicPrizeStrategyListener.mock.supportsInterface.returns(true)
await periodicPrizeStrategyListener.mock.supportsInterface.withArgs('0xffffffff').returns(false)

await rng.mock.getRequestFee.returns(rngFeeToken.address, toWei('1'));

debug('deploying prizeStrategy...')
Expand Down Expand Up @@ -549,7 +553,7 @@ describe('PeriodicPrizeStrategy', function() {

it('should not allow setting an EOA as a listener', async () => {
await expect(prizeStrategy.setPeriodicPrizeStrategyListener(wallet2._address))
.to.be.revertedWith("PeriodicPrizeStrategy/listener-not-contract");
.to.be.revertedWith("PeriodicPrizeStrategy/prizeStrategyListener-invalid");
})

it('should allow setting the listener to null', async () => {
Expand All @@ -573,7 +577,7 @@ describe('PeriodicPrizeStrategy', function() {

it('should not allow setting an EOA as a listener', async () => {
await expect(prizeStrategy.setTokenListener(wallet2._address))
.to.be.revertedWith("PeriodicPrizeStrategy/token-listener-not-contract");
.to.be.revertedWith("PeriodicPrizeStrategy/token-listener-invalid");
})

it('should allow setting the listener to null', async () => {
Expand All @@ -590,7 +594,7 @@ describe('PeriodicPrizeStrategy', function() {
await distributor.mock.distribute.withArgs('48849787646992769944319009300540211125598274780817112954146168253338351566848').returns()

await prizeStrategy.setPeriodicPrizeStrategyListener(periodicPrizeStrategyListener.address)
await periodicPrizeStrategyListener.mock.afterDistributeAwards.withArgs('48849787646992769944319009300540211125598274780817112954146168253338351566848', await prizeStrategy.prizePeriodStartedAt()).returns()
await periodicPrizeStrategyListener.mock.afterPrizePoolAwarded.withArgs('48849787646992769944319009300540211125598274780817112954146168253338351566848', await prizeStrategy.prizePeriodStartedAt()).returns()

// no external award
await externalERC20Award.mock.balanceOf.withArgs(prizePool.address).returns('0')
Expand Down

0 comments on commit fc4a436

Please sign in to comment.