Skip to content

Commit

Permalink
Feature/pool 108 as the owner i want to configure an exit (#37)
Browse files Browse the repository at this point in the history
* Completed integration of new c15n-based exit fee calc
  • Loading branch information
asselstine committed Jun 10, 2020
1 parent 588fb25 commit 9e220b5
Show file tree
Hide file tree
Showing 44 changed files with 1,105 additions and 773 deletions.
10 changes: 5 additions & 5 deletions .openzeppelin/kovan.json
Expand Up @@ -288,7 +288,7 @@
"uninitializedBaseContracts": []
}
},
"LoyaltyFactory": {
"CollateralFactory": {
"address": "0xad11611B099A13A35245e7Be14C01663337951E4",
"constructorCode": "608060405234801561001057600080fd5b50613cc1806100206000396000f3fe",
"bodyBytecodeHash": "178d4a3c18aa73b2a8ec2e43d96f603e15ef908efe55f0ef8027fd805dec6606",
Expand Down Expand Up @@ -344,8 +344,8 @@
"src": "1982:29:11"
},
{
"contract": "LoyaltyFactory",
"path": "contracts/modules/loyalty/LoyaltyFactory.sol",
"contract": "CollateralFactory",
"path": "contracts/modules/collateral/CollateralFactory.sol",
"label": "instance",
"astId": 15925,
"type": "t_address",
Expand Down Expand Up @@ -743,7 +743,7 @@
{
"contract": "PrizePoolBuilder",
"path": "contracts/builder/PrizePoolBuilder.sol",
"label": "loyaltyFactory",
"label": "collateralFactory",
"astId": 14298,
"type": "t_address",
"src": "1080:36:31"
Expand Down Expand Up @@ -915,7 +915,7 @@
"kind": "Upgradeable"
}
],
"PoolTogether3/LoyaltyFactory": [
"PoolTogether3/CollateralFactory": [
{
"address": "0x7F269B1bcE1B24F373BB30551fF306CF68dDF731",
"version": "0.3.0",
Expand Down
5 changes: 3 additions & 2 deletions .openzeppelin/project.json
Expand Up @@ -9,9 +9,10 @@
"SingleRandomWinnerPrizeStrategyFactory": "SingleRandomWinnerPrizeStrategyFactory",
"CompoundYieldServiceFactory": "CompoundYieldServiceFactory",
"PrizePoolModuleManagerFactory": "PrizePoolModuleManagerFactory",
"LoyaltyFactory": "LoyaltyFactory",
"CreditFactory": "CreditFactory",
"TimelockFactory": "TimelockFactory",
"SponsorshipFactory": "SponsorshipFactory"
"SponsorshipFactory": "SponsorshipFactory",
"InterestTrackerFactory": "InterestTrackerFactory"
},
"dependencies": {},
"name": "PoolTogether3",
Expand Down
22 changes: 2 additions & 20 deletions .solcover.js
@@ -1,25 +1,7 @@
module.exports = {
mocha: { reporter: 'mocha-junit-reporter' },
skipFiles: [
"compound/ICErc20.sol",
"test/maker/MockJoinLike.sol",
"test/maker/MockScdMcdMigration.sol",
"test/CErc20Mock.sol",
"test/ERC777Mintable.sol",
"test/ExposedBlocklock.sol",
"test/ExposedDrawManager.sol",
"test/ExposedUniformRandomNumber.sol",
"test/MockERC777Recipient.sol",
"test/MockERC777Sender.sol",
"test/Token.sol",
"test/CTokenMock.sol",
"test/ERC20Mintable.sol",
"test/Forwarder.sol",
"test/MockGovernor.sol",
"test/MockPrizeStrategy.sol",
"test/MockYieldService.sol",
"test/ModuleManagerHarness.sol",
"test/TicketHarness.sol",
"test/Timestamp.sol"
"external",
"test"
]
};
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -50,7 +50,7 @@ let contracts = await deployContracts(signer)
timelockFactory: factory
ticketFactory: factory
prizeStrategyFactory: factory
loyaltyFactory: factory
collateralFactory: factory
sponsorshipFactory: factory
prizePoolBuilder: The PrizePool builder
singleRandomWinnerPrizePoolBuilder: The SingleRandomWinner prize pool builder
Expand Down
10 changes: 7 additions & 3 deletions contracts/Constants.sol
Expand Up @@ -25,9 +25,13 @@ library Constants {
bytes32 public constant TICKET_INTERFACE_HASH =
0xf22dc5a0b79862d03b1bd7a85ef07c37d8ab6be34838cd9c393ec1d671b9c818;

// keccak256("PoolTogetherV3/LoyaltyInterface")
bytes32 public constant LOYALTY_INTERFACE_HASH =
0x21adbc49851dc9a5421ef4d78427664813502289b1576200510e09bc637502d9;
// keccak256("PoolTogetherV3/InterestTrackerInterface")
bytes32 public constant INTEREST_TRACKER_INTERFACE_HASH =
0xd024f1a00d323e421da1833cf865a55a44409b62b7315e96bce12d82e75eff6e;

// keccak256("PoolTogetherV3/CreditInterface")
bytes32 public constant CREDIT_INTERFACE_HASH =
0xe763560b3de3f53bee3e4b2ec26341deef7b74cbfbe73ac5f88e2ad233f9aaf2;

// keccak256("PoolTogetherV3/SponsorshipInterface")
bytes32 public constant SPONSORSHIP_INTERFACE_HASH =
Expand Down
35 changes: 4 additions & 31 deletions contracts/base/NamedModule.sol
Expand Up @@ -4,17 +4,19 @@ import "@openzeppelin/contracts-ethereum-package/contracts/introspection/IERC182
import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol";
import "@opengsn/gsn/contracts/BaseRelayRecipient.sol";
// import "@gnosis.pm/safe-contracts/contracts/base/Module.sol";

import "../external/gnosis/Module.sol";
import "./NamedModuleManager.sol";
import "../Constants.sol";

abstract contract NamedModule is Initializable, Module, IERC1820Implementer, BaseRelayRecipient {

function construct (
ModuleManager _manager,
NamedModuleManager _manager,
address _trustedForwarder
) public virtual initializer {
setManager(_manager);
enableInterface();
_manager.enableModuleInterface(hashName());
if (_trustedForwarder != address(0)) {
trustedForwarder = _trustedForwarder;
}
Expand All @@ -34,39 +36,10 @@ abstract contract NamedModule is Initializable, Module, IERC1820Implementer, Bas
}
}

function getInterfaceImplementer(bytes32 name) internal virtual view returns (address) {
address result = Constants.REGISTRY.getInterfaceImplementer(address(manager), name);
require(result != address(0), "no implementation registered");
return result;
}

function enableInterface() internal virtual onlyWhenEnabled {
setInterfaceImplementer(hashName(), address(this));
}

function disableInterface() internal virtual onlyWhenEnabled {
setInterfaceImplementer(hashName(), address(0));
}

function setInterfaceImplementer(bytes32 interfaceHash, address target) internal virtual {
bytes memory data = abi.encodeWithSignature(
"setInterfaceImplementer(address,bytes32,address)", address(manager), interfaceHash, target
);
require(
manager.execTransactionFromModule(address(Constants.REGISTRY), 0, data, Enum.Operation.Call),
"could not set interface"
);
}

function _msgSender() internal override virtual view returns (address payable) {
return BaseRelayRecipient._msgSender();
}

modifier onlyWhenEnabled() virtual {
require(manager.isModuleEnabled(this), "module is not enabled");
_;
}

modifier onlyManagerOrModule() virtual {
bool isModule = manager.isModuleEnabled(Module(msg.sender));
require(isModule || msg.sender == address(manager), "Method can only be called from manager or module");
Expand Down
11 changes: 11 additions & 0 deletions contracts/base/NamedModuleManager.sol
@@ -0,0 +1,11 @@
pragma solidity ^0.6.4;

import "../external/gnosis/ModuleManager.sol";
import "../Constants.sol";

contract NamedModuleManager is ModuleManager {
function enableModuleInterface(bytes32 hashName) external {
require(address(msg.sender) != address(0) && address(msg.sender) != SENTINEL_MODULES, "Invalid module address provided");
Constants.REGISTRY.setInterfaceImplementer(address(this),hashName,msg.sender);
}
}
4 changes: 2 additions & 2 deletions contracts/base/OwnableModuleManager.sol
Expand Up @@ -4,9 +4,9 @@ import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol";
import "@opengsn/gsn/contracts/BaseRelayRecipient.sol";

import "../external/gnosis/ModuleManager.sol";
import "./NamedModuleManager.sol";

contract OwnableModuleManager is ModuleManager, OwnableUpgradeSafe, BaseRelayRecipient {
contract OwnableModuleManager is NamedModuleManager, OwnableUpgradeSafe, BaseRelayRecipient {

function initialize(address _trustedForwarder) public initializer {
__Ownable_init();
Expand Down
4 changes: 2 additions & 2 deletions contracts/base/TokenModule.sol
Expand Up @@ -11,7 +11,7 @@ import "../base/NamedModule.sol";
abstract contract TokenModule is Initializable, ERC777UpgradeSafe, NamedModule {

function initialize(
ModuleManager _manager,
NamedModuleManager _manager,
address _trustedForwarder,
string memory name,
string memory symbol
Expand All @@ -21,7 +21,7 @@ abstract contract TokenModule is Initializable, ERC777UpgradeSafe, NamedModule {
}

function initialize(
ModuleManager _manager,
NamedModuleManager _manager,
address _trustedForwarder,
string memory name,
string memory symbol,
Expand Down
52 changes: 33 additions & 19 deletions contracts/builder/PrizePoolBuilder.sol
Expand Up @@ -6,10 +6,11 @@ import "@pooltogether/governor-contracts/contracts/GovernorInterface.sol";
import "../module-manager/PrizePoolModuleManagerFactory.sol";
import "../modules/timelock/TimelockFactory.sol";
import "../modules/sponsorship/SponsorshipFactory.sol";
import "../modules/loyalty/LoyaltyFactory.sol";
import "../modules/credit/CreditFactory.sol";
import "../modules/yield-service/CompoundYieldServiceFactory.sol";
import "../modules/ticket/TicketFactory.sol";
import "../modules/periodic-prize-pool/PeriodicPrizePoolFactory.sol";
import "../modules/interest-tracker/InterestTrackerFactory.sol";
import "../external/compound/CTokenInterface.sol";

contract PrizePoolBuilder is Initializable {
Expand All @@ -25,9 +26,10 @@ contract PrizePoolBuilder is Initializable {
CompoundYieldServiceFactory public compoundYieldServiceFactory;
PeriodicPrizePoolFactory public periodicPrizePoolFactory;
TicketFactory public ticketFactory;
LoyaltyFactory public loyaltyFactory;
CreditFactory public creditFactory;
TimelockFactory public timelockFactory;
SponsorshipFactory public sponsorshipFactory;
InterestTrackerFactory public interestTrackerFactory;
RNGInterface public rng;
address public trustedForwarder;

Expand All @@ -39,25 +41,28 @@ contract PrizePoolBuilder is Initializable {
TicketFactory _ticketFactory,
TimelockFactory _timelockFactory,
SponsorshipFactory _sponsorshipFactory,
LoyaltyFactory _loyaltyFactory,
CreditFactory _creditFactory,
InterestTrackerFactory _interestTrackerFactory,
RNGInterface _rng,
address _trustedForwarder
) public initializer {
require(address(_prizePoolModuleManagerFactory) != address(0), "module factory cannot be zero");
require(address(_governor) != address(0), "governor cannot be zero");
require(address(_compoundYieldServiceFactory) != address(0), "interest pool factory is not defined");
require(address(_periodicPrizePoolFactory) != address(0), "prize pool factory is not defined");
require(address(_ticketFactory) != address(0), "ticket factory is not defined");
require(address(_compoundYieldServiceFactory) != address(0), "interest pool factory cannot be zero");
require(address(_periodicPrizePoolFactory) != address(0), "prize pool factory cannot be zero");
require(address(_ticketFactory) != address(0), "ticket factory cannot be zero");
require(address(_rng) != address(0), "rng cannot be zero");
require(address(_sponsorshipFactory) != address(0), "sponsorship factory cannot be zero");
require(address(_timelockFactory) != address(0), "controlled token factory cannot be zero");
require(address(_loyaltyFactory) != address(0), "loyalty factory is not zero");
require(address(_creditFactory) != address(0), "credit factory cannot be zero");
require(address(_interestTrackerFactory) != address(0), "interest tracker factory cannot be zero");
interestTrackerFactory = _interestTrackerFactory;
prizePoolModuleManagerFactory = _prizePoolModuleManagerFactory;
governor = _governor;
compoundYieldServiceFactory = _compoundYieldServiceFactory;
periodicPrizePoolFactory = _periodicPrizePoolFactory;
ticketFactory = _ticketFactory;
loyaltyFactory = _loyaltyFactory;
creditFactory = _creditFactory;
rng = _rng;
trustedForwarder = _trustedForwarder;
sponsorshipFactory = _sponsorshipFactory;
Expand All @@ -78,10 +83,11 @@ contract PrizePoolBuilder is Initializable {

createPeriodicPrizePoolModule(manager, _prizeStrategy, _prizePeriodSeconds);
createCompoundYieldServiceModule(manager, _cToken);
createLoyaltyModule(manager);
createCreditModule(manager);
createTimelockModule(manager);
createTicketModule(manager, _ticketName, _ticketSymbol);
createSponsorshipModule(manager, _sponsorshipName, _sponsorshipSymbol);
createInterestTrackerModule(manager);

emit PrizePoolCreated(
msg.sender,
Expand All @@ -92,8 +98,16 @@ contract PrizePoolBuilder is Initializable {
return manager;
}

function createInterestTrackerModule(
NamedModuleManager _moduleManager
) internal {
InterestTracker interestTracker = interestTrackerFactory.createInterestTracker();
_moduleManager.enableModule(interestTracker);
interestTracker.initialize(_moduleManager, trustedForwarder);
}

function createPeriodicPrizePoolModule(
ModuleManager _moduleManager,
NamedModuleManager _moduleManager,
PrizeStrategyInterface _prizeStrategy,
uint256 _prizePeriodSeconds
) internal {
Expand All @@ -110,24 +124,24 @@ contract PrizePoolBuilder is Initializable {
}

function createCompoundYieldServiceModule(
ModuleManager moduleManager,
NamedModuleManager moduleManager,
CTokenInterface cToken
) internal {
CompoundYieldService yieldService = compoundYieldServiceFactory.createCompoundYieldService();
moduleManager.enableModule(yieldService);
yieldService.initialize(moduleManager, cToken);
}

function createLoyaltyModule(
ModuleManager moduleManager
function createCreditModule(
NamedModuleManager moduleManager
) internal {
Loyalty loyalty = loyaltyFactory.createLoyalty();
moduleManager.enableModule(loyalty);
loyalty.initialize(moduleManager, trustedForwarder, "", "");
Credit credit = creditFactory.createCredit();
moduleManager.enableModule(credit);
credit.initialize(moduleManager, trustedForwarder, "Credit", "CRDT");
}

function createTicketModule(
ModuleManager moduleManager,
NamedModuleManager moduleManager,
string memory _ticketName,
string memory _ticketSymbol
) internal {
Expand All @@ -137,15 +151,15 @@ contract PrizePoolBuilder is Initializable {
}

function createTimelockModule(
ModuleManager moduleManager
NamedModuleManager moduleManager
) internal {
Timelock timelock = timelockFactory.createTimelock();
moduleManager.enableModule(timelock);
timelock.initialize(moduleManager, trustedForwarder, "", "");
}

function createSponsorshipModule(
ModuleManager moduleManager,
NamedModuleManager moduleManager,
string memory _sponsorshipName,
string memory _sponsorshipSymbol
) internal {
Expand Down
14 changes: 9 additions & 5 deletions contracts/module-manager/PrizePoolModuleManager.sol
Expand Up @@ -4,7 +4,7 @@ import "../base/OwnableModuleManager.sol";
import "../Constants.sol";
import "../modules/yield-service/YieldServiceInterface.sol";
import "../modules/ticket/Ticket.sol";
import "../modules/loyalty/Loyalty.sol";
import "../modules/interest-tracker/InterestTrackerInterface.sol";
import "../modules/sponsorship/Sponsorship.sol";
import "../modules/periodic-prize-pool/PeriodicPrizePoolInterface.sol";

Expand All @@ -18,12 +18,12 @@ contract PrizePoolModuleManager is OwnableModuleManager {
return Ticket(Constants.REGISTRY.getInterfaceImplementer(address(this), Constants.TICKET_INTERFACE_HASH));
}

function loyalty() public view returns (Loyalty) {
return Loyalty(Constants.REGISTRY.getInterfaceImplementer(address(this), Constants.LOYALTY_INTERFACE_HASH));
function credit() public view returns (Credit) {
return Credit(Constants.REGISTRY.getInterfaceImplementer(address(this), Constants.CREDIT_INTERFACE_HASH));
}

function sponsorship() public view returns (Sponsorship) {
return Sponsorship(Constants.REGISTRY.getInterfaceImplementer(address(this), Constants.LOYALTY_INTERFACE_HASH));
return Sponsorship(Constants.REGISTRY.getInterfaceImplementer(address(this), Constants.SPONSORSHIP_INTERFACE_HASH));
}

function timelock() public view returns (Timelock) {
Expand All @@ -34,4 +34,8 @@ contract PrizePoolModuleManager is OwnableModuleManager {
return PeriodicPrizePoolInterface(Constants.REGISTRY.getInterfaceImplementer(address(this), Constants.PRIZE_POOL_INTERFACE_HASH));
}

}
function interestTracker() public view returns (InterestTrackerInterface) {
return InterestTrackerInterface(Constants.REGISTRY.getInterfaceImplementer(address(this), Constants.INTEREST_TRACKER_INTERFACE_HASH));
}

}

0 comments on commit 9e220b5

Please sign in to comment.