Update SubscriptionManager to latest version

See https://github.com/nucypher/nucypher-contracts/pull/2
pull/2860/head
David Núñez 2022-02-07 17:23:36 +01:00 committed by Kieran Prasch
parent 62291021ba
commit f7f892602a
1 changed files with 63 additions and 28 deletions

View File

@ -2,38 +2,56 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
contract SubscriptionManager { import "@openzeppelin-upgradeable/contracts/access/AccessControlUpgradeable.sol";
import "@openzeppelin-upgradeable/contracts/proxy/utils/Initializable.sol";
uint256 private constant RATE_PER_DAY = 50 gwei; contract SubscriptionManager is Initializable, AccessControlUpgradeable {
uint256 public constant RATE_PER_SECOND = RATE_PER_DAY / 1 days;
struct Policy { // TODO: Optimize struct layout bytes32 public constant SET_RATE_ROLE =
keccak256("Power to set the fee rate");
bytes32 public constant WITHDRAW_ROLE =
keccak256("Power to withdraw funds from SubscriptionManager");
// The layout of policy struct is optimized, so sponsor, timestamps and size
// fit in a single 256-word.
struct Policy {
address payable sponsor; address payable sponsor;
uint32 startTimestamp;
uint32 endTimestamp;
uint16 size; // also known as `N`
address owner; address owner;
uint64 startTimestamp;
uint64 endTimestamp;
} }
event PolicyCreated( event PolicyCreated(
bytes16 indexed policyId, bytes16 indexed policyId,
address indexed sponsor, address indexed sponsor,
address indexed owner, address indexed owner,
uint64 startTimestamp, uint16 size,
uint64 endTimestamp uint32 startTimestamp,
uint32 endTimestamp
); );
address payable public owner; event FeeRateUpdated(uint256 oldFeeRate, uint256 newFeeRate);
mapping (bytes16 => Policy) public policies;
constructor(){ // Per-second service fee rate
owner = payable(msg.sender); uint256 public feeRate;
// Mapping that stores policy structs, keyed by policy ID
mapping (bytes16 => Policy) internal _policies;
function initialize(uint256 _feeRate) public initializer {
_setFeeRate(_feeRate);
_setupRole(SET_RATE_ROLE, msg.sender);
_setupRole(WITHDRAW_ROLE, msg.sender);
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
} }
function createPolicy( function createPolicy(
bytes16 _policyId, bytes16 _policyId,
address _policyOwner, address _policyOwner,
uint64 _startTimestamp, uint16 _size,
uint64 _endTimestamp uint32 _startTimestamp,
uint32 _endTimestamp
) )
external payable external payable
{ {
@ -42,31 +60,33 @@ contract SubscriptionManager {
block.timestamp < _endTimestamp, block.timestamp < _endTimestamp,
"Invalid timestamps" "Invalid timestamps"
); );
uint64 duration = _endTimestamp - _startTimestamp; uint32 duration = _endTimestamp - _startTimestamp;
require( require(
duration > 0 && duration > 0 && _size > 0 &&
msg.value == RATE_PER_SECOND * uint64(duration) msg.value == feeRate * _size * uint32(duration)
); );
//Policy storage policy =
_createPolicy(_policyId, _policyOwner, _startTimestamp, _endTimestamp); _createPolicy(_policyId, _policyOwner, _size, _startTimestamp, _endTimestamp);
} }
/** /**
* @notice Create policy * @notice Create policy
* @param _policyId Policy id * @param _policyId Policy id
* @param _policyOwner Policy owner. Zero address means sender is owner * @param _policyOwner Policy owner. Zero address means sender is owner
* @param _size Number of nodes involved in the policy
* @param _startTimestamp Start timestamp of the policy in seconds * @param _startTimestamp Start timestamp of the policy in seconds
* @param _endTimestamp End timestamp of the policy in seconds * @param _endTimestamp End timestamp of the policy in seconds
*/ */
function _createPolicy( function _createPolicy(
bytes16 _policyId, bytes16 _policyId,
address _policyOwner, address _policyOwner,
uint64 _startTimestamp, uint16 _size,
uint64 _endTimestamp uint32 _startTimestamp,
uint32 _endTimestamp
) )
internal returns (Policy storage policy) internal returns (Policy storage policy)
{ {
policy = policies[_policyId]; policy = _policies[_policyId];
require( require(
policy.endTimestamp < block.timestamp, policy.endTimestamp < block.timestamp,
"Policy is currently active" "Policy is currently active"
@ -75,6 +95,7 @@ contract SubscriptionManager {
policy.sponsor = payable(msg.sender); policy.sponsor = payable(msg.sender);
policy.startTimestamp = _startTimestamp; policy.startTimestamp = _startTimestamp;
policy.endTimestamp = _endTimestamp; policy.endTimestamp = _endTimestamp;
policy.size = _size;
if (_policyOwner != msg.sender && _policyOwner != address(0)) { if (_policyOwner != msg.sender && _policyOwner != address(0)) {
policy.owner = _policyOwner; policy.owner = _policyOwner;
@ -84,17 +105,31 @@ contract SubscriptionManager {
_policyId, _policyId,
msg.sender, msg.sender,
_policyOwner == address(0) ? msg.sender : _policyOwner, _policyOwner == address(0) ? msg.sender : _policyOwner,
_size,
_startTimestamp, _startTimestamp,
_endTimestamp _endTimestamp
); );
} }
function isPolicyActive(bytes16 _policyID) public view returns(bool){ function getPolicy(bytes16 _policyID) public view returns(Policy memory){
return policies[_policyID].endTimestamp > block.timestamp; return _policies[_policyID];
} }
function sweep(address payable recipient) external { function isPolicyActive(bytes16 _policyID) public view returns(bool){
require(msg.sender == owner); return _policies[_policyID].endTimestamp > block.timestamp;
}
function _setFeeRate(uint256 newFee) internal {
uint256 oldFee = feeRate;
feeRate = newFee;
emit FeeRateUpdated(oldFee, newFee);
}
function setFeeRate(uint256 _rate_per_second) onlyRole(SET_RATE_ROLE) external {
_setFeeRate(_rate_per_second);
}
function sweep(address payable recipient) onlyRole(WITHDRAW_ROLE) external {
uint256 balance = address(this).balance; uint256 balance = address(this).balance;
(bool sent, ) = recipient.call{value: balance}(""); (bool sent, ) = recipient.call{value: balance}("");
require(sent, "Failed transfer"); require(sent, "Failed transfer");