Skip to content

Commit

Permalink
Remove pausing (#343)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeSandwich committed Feb 28, 2024
1 parent d7b089f commit addca25
Show file tree
Hide file tree
Showing 23 changed files with 67 additions and 644 deletions.
10 changes: 5 additions & 5 deletions src/AddressDriver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ contract AddressDriver is DriverTransferUtils, Managed {
/// If you use such tokens in the protocol, they can get stuck or lost.
/// @param transferTo The address to send collected funds to
/// @return amt The collected amount
function collect(IERC20 erc20, address transferTo) public whenNotPaused returns (uint128 amt) {
function collect(IERC20 erc20, address transferTo) public returns (uint128 amt) {
return _collectAndTransfer(drips, _callerAccountId(), erc20, transferTo);
}

Expand All @@ -70,7 +70,7 @@ contract AddressDriver is DriverTransferUtils, Managed {
/// or impose any restrictions on holding or transferring tokens are not supported.
/// If you use such tokens in the protocol, they can get stuck or lost.
/// @param amt The given amount
function give(uint256 receiver, IERC20 erc20, uint128 amt) public whenNotPaused {
function give(uint256 receiver, IERC20 erc20, uint128 amt) public {
_giveAndTransfer(drips, _callerAccountId(), receiver, erc20, amt);
}

Expand Down Expand Up @@ -131,7 +131,7 @@ contract AddressDriver is DriverTransferUtils, Managed {
uint32 maxEndHint1,
uint32 maxEndHint2,
address transferTo
) public whenNotPaused returns (int128 realBalanceDelta) {
) public returns (int128 realBalanceDelta) {
return _setStreamsAndTransfer(
drips,
_callerAccountId(),
Expand Down Expand Up @@ -164,15 +164,15 @@ contract AddressDriver is DriverTransferUtils, Managed {
/// This is usually unwanted, because if splitting is repeated,
/// funds split to themselves will be again split using the current configuration.
/// Splitting 100% to self effectively blocks splitting unless the configuration is updated.
function setSplits(SplitsReceiver[] calldata receivers) public whenNotPaused {
function setSplits(SplitsReceiver[] calldata receivers) public {
drips.setSplits(_callerAccountId(), receivers);
}

/// @notice Emits the account metadata for the message sender.
/// The keys and the values are not standardized by the protocol, it's up to the users
/// to establish and follow conventions to ensure compatibility with the consumers.
/// @param accountMetadata The list of account metadata.
function emitAccountMetadata(AccountMetadata[] calldata accountMetadata) public whenNotPaused {
function emitAccountMetadata(AccountMetadata[] calldata accountMetadata) public {
if (accountMetadata.length != 0) {
drips.emitAccountMetadata(_callerAccountId(), accountMetadata);
}
Expand Down
14 changes: 4 additions & 10 deletions src/Drips.sol
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ contract Drips is Managed, Streams, Splits {
/// It should be a smart contract capable of dealing with the Drips API.
/// It shouldn't be an EOA because the API requires making multiple calls per transaction.
/// @return driverId The registered driver ID.
function registerDriver(address driverAddr) public whenNotPaused returns (uint32 driverId) {
function registerDriver(address driverAddr) public returns (uint32 driverId) {
require(driverAddr != address(0), "Driver registered for 0 address");
DripsStorage storage dripsStorage = _dripsStorage();
driverId = dripsStorage.nextDriverId++;
Expand All @@ -195,7 +195,7 @@ contract Drips is Managed, Streams, Splits {
/// @param newDriverAddr The new address of the driver.
/// It should be a smart contract capable of dealing with the Drips API.
/// It shouldn't be an EOA because the API requires making multiple calls per transaction.
function updateDriverAddress(uint32 driverId, address newDriverAddr) public whenNotPaused {
function updateDriverAddress(uint32 driverId, address newDriverAddr) public {
_assertCallerIsDriver(driverId);
_dripsStorage().driverAddresses[driverId] = newDriverAddr;
emit DriverAddressUpdated(driverId, msg.sender, newDriverAddr);
Expand Down Expand Up @@ -371,7 +371,6 @@ contract Drips is Managed, Streams, Splits {
/// @return receivedAmt The received amount
function receiveStreams(uint256 accountId, IERC20 erc20, uint32 maxCycles)
public
whenNotPaused
returns (uint128 receivedAmt)
{
receivedAmt = Streams._receiveStreams(accountId, erc20, maxCycles);
Expand Down Expand Up @@ -407,7 +406,7 @@ contract Drips is Managed, Streams, Splits {
uint256 senderId,
bytes32 historyHash,
StreamsHistory[] memory streamsHistory
) public whenNotPaused returns (uint128 amt) {
) public returns (uint128 amt) {
amt = Streams._squeezeStreams(accountId, erc20, senderId, historyHash, streamsHistory);
if (amt != 0) {
_moveBalanceFromStreamsToSplits(erc20, amt);
Expand Down Expand Up @@ -496,7 +495,6 @@ contract Drips is Managed, Streams, Splits {
/// @return splitAmt The amount split to the account's splits receivers
function split(uint256 accountId, IERC20 erc20, SplitsReceiver[] memory currReceivers)
public
whenNotPaused
returns (uint128 collectableAmt, uint128 splitAmt)
{
return Splits._split(accountId, erc20, currReceivers);
Expand Down Expand Up @@ -528,7 +526,6 @@ contract Drips is Managed, Streams, Splits {
/// @return amt The collected amount
function collect(uint256 accountId, IERC20 erc20)
public
whenNotPaused
onlyDriver(accountId)
returns (uint128 amt)
{
Expand All @@ -552,7 +549,6 @@ contract Drips is Managed, Streams, Splits {
/// @param amt The given amount
function give(uint256 accountId, uint256 receiver, IERC20 erc20, uint128 amt)
public
whenNotPaused
onlyDriver(accountId)
{
if (amt != 0) _increaseSplitsBalance(erc20, amt);
Expand Down Expand Up @@ -671,7 +667,7 @@ contract Drips is Managed, Streams, Splits {
// slither-disable-next-line similar-names
uint32 maxEndHint1,
uint32 maxEndHint2
) public whenNotPaused onlyDriver(accountId) returns (int128 realBalanceDelta) {
) public onlyDriver(accountId) returns (int128 realBalanceDelta) {
if (balanceDelta > 0) _increaseStreamsBalance(erc20, uint128(balanceDelta));
realBalanceDelta = Streams._setStreams(
accountId, erc20, currReceivers, balanceDelta, newReceivers, maxEndHint1, maxEndHint2
Expand Down Expand Up @@ -734,7 +730,6 @@ contract Drips is Managed, Streams, Splits {
/// Splitting 100% to self effectively blocks splitting unless the configuration is updated.
function setSplits(uint256 accountId, SplitsReceiver[] memory receivers)
public
whenNotPaused
onlyDriver(accountId)
{
Splits._setSplits(accountId, receivers);
Expand Down Expand Up @@ -766,7 +761,6 @@ contract Drips is Managed, Streams, Splits {
/// @param accountMetadata The list of account metadata.
function emitAccountMetadata(uint256 accountId, AccountMetadata[] calldata accountMetadata)
public
whenNotPaused
onlyDriver(accountId)
{
unchecked {
Expand Down
2 changes: 1 addition & 1 deletion src/Giver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ contract GiversRegistry is Managed {
/// If it's the zero address, `Giver` wraps all the native tokens it holds using
/// `nativeTokenWrapper`, and then `give`s to the account all the wrapped tokens it holds.
/// @param amt The amount of tokens that were `give`n.
function give(uint256 accountId, IERC20 erc20) public whenNotPaused returns (uint256 amt) {
function give(uint256 accountId, IERC20 erc20) public returns (uint256 amt) {
address giver_ = giver(accountId);
if (!Address.isContract(giver_)) {
// slither-disable-next-line unused-return
Expand Down
2 changes: 1 addition & 1 deletion src/ImmutableSplitsDriver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ contract ImmutableSplitsDriver is Managed {
function createSplits(
SplitsReceiver[] calldata receivers,
AccountMetadata[] calldata accountMetadata
) public whenNotPaused returns (uint256 accountId) {
) public returns (uint256 accountId) {
accountId = nextAccountId();
StorageSlot.getUint256Slot(_counterSlot).value++;
uint256 weightSum = 0;
Expand Down
124 changes: 11 additions & 113 deletions src/Managed.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,79 +6,28 @@ import {ERC1967Proxy} from "openzeppelin-contracts/proxy/ERC1967/ERC1967Proxy.so
import {EnumerableSet} from "openzeppelin-contracts/utils/structs/EnumerableSet.sol";
import {StorageSlot} from "openzeppelin-contracts/utils/StorageSlot.sol";

using EnumerableSet for EnumerableSet.AddressSet;

/// @notice A mix-in for contract pausing, upgrading and admin management.
/// @notice A mix-in for contract upgrading and admin management.
/// It can't be used directly, only via a proxy. It uses the upgrade-safe ERC-1967 storage scheme.
///
/// Managed uses the ERC-1967 admin slot to store the admin address.
/// All instances of the contracts have admin address `0x00` and are forever paused.
/// When a proxy uses such contract via delegation, the proxy should define
/// the initial admin address and the contract is initially unpaused.
/// All instances of the contracts have admin address `0x00`.
abstract contract Managed is UUPSUpgradeable {
/// @notice The pointer to the storage slot holding a single `ManagedStorage` structure.
bytes32 private immutable _managedStorageSlot = _erc1967Slot("eip1967.managed.storage");
/// @notice The pointer to the storage slot holding the proposed admin.
bytes32 private immutable _proposedAdminStorageSlot =
_erc1967Slot("eip1967.managed.proposedAdmin");

/// @notice Emitted when a new admin of the contract is proposed.
/// The proposed admin must call `acceptAdmin` to finalize the change.
/// @param currentAdmin The current admin address.
/// @param newAdmin The proposed admin address.
event NewAdminProposed(address indexed currentAdmin, address indexed newAdmin);

/// @notice Emitted when the pauses role is granted.
/// @param pauser The address that the pauser role was granted to.
/// @param admin The address of the admin that triggered the change.
event PauserGranted(address indexed pauser, address indexed admin);

/// @notice Emitted when the pauses role is revoked.
/// @param pauser The address that the pauser role was revoked from.
/// @param admin The address of the admin that triggered the change.
event PauserRevoked(address indexed pauser, address indexed admin);

/// @notice Emitted when the pause is triggered.
/// @param pauser The address that triggered the change.
event Paused(address indexed pauser);

/// @notice Emitted when the pause is lifted.
/// @param pauser The address that triggered the change.
event Unpaused(address indexed pauser);

struct ManagedStorage {
bool isPaused;
EnumerableSet.AddressSet pausers;
address proposedAdmin;
}

/// @notice Throws if called by any caller other than the admin.
modifier onlyAdmin() {
require(admin() == msg.sender, "Caller not the admin");
_;
}

/// @notice Throws if called by any caller other than the admin or a pauser.
modifier onlyAdminOrPauser() {
require(admin() == msg.sender || isPauser(msg.sender), "Caller not the admin or a pauser");
_;
}

/// @notice Modifier to make a function callable only when the contract is not paused.
modifier whenNotPaused() {
require(!isPaused(), "Contract paused");
_;
}

/// @notice Modifier to make a function callable only when the contract is paused.
modifier whenPaused() {
require(isPaused(), "Contract not paused");
_;
}

/// @notice Initializes the contract in paused state and with no admin.
/// The contract instance can be used only as a call delegation target for a proxy.
constructor() {
_managedStorage().isPaused = true;
}

/// @notice Returns the current implementation address.
function implementation() public view returns (address) {
return _getImplementation();
Expand All @@ -91,7 +40,7 @@ abstract contract Managed is UUPSUpgradeable {

/// @notice Returns the proposed address to change the admin to.
function proposedAdmin() public view returns (address) {
return _managedStorage().proposedAdmin;
return _proposedAdmin().value;
}

/// @notice Proposes a change of the admin of the contract.
Expand All @@ -101,7 +50,7 @@ abstract contract Managed is UUPSUpgradeable {
/// @param newAdmin The proposed admin address.
function proposeNewAdmin(address newAdmin) public onlyAdmin {
emit NewAdminProposed(msg.sender, newAdmin);
_managedStorage().proposedAdmin = newAdmin;
_proposedAdmin().value = newAdmin;
}

/// @notice Applies a proposed change of the admin of the contract.
Expand All @@ -122,54 +71,13 @@ abstract contract Managed is UUPSUpgradeable {
/// @notice Sets the current admin of the contract and clears the proposed admin.
/// @param newAdmin The admin address being set. Can be the zero address.
function _updateAdmin(address newAdmin) internal {
emit AdminChanged(admin(), newAdmin);
_managedStorage().proposedAdmin = address(0);
_proposedAdmin().value = address(0);
StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
emit AdminChanged(admin(), newAdmin);
}

/// @notice Grants the pauser role to an address. Callable only by the admin.
/// @param pauser The granted address.
function grantPauser(address pauser) public onlyAdmin {
require(_managedStorage().pausers.add(pauser), "Address already is a pauser");
emit PauserGranted(pauser, msg.sender);
}

/// @notice Revokes the pauser role from an address. Callable only by the admin.
/// @param pauser The revoked address.
function revokePauser(address pauser) public onlyAdmin {
require(_managedStorage().pausers.remove(pauser), "Address is not a pauser");
emit PauserRevoked(pauser, msg.sender);
}

/// @notice Checks if an address is a pauser.
/// @param pauser The checked address.
/// @return isAddrPauser True if the address is a pauser.
function isPauser(address pauser) public view returns (bool isAddrPauser) {
return _managedStorage().pausers.contains(pauser);
}

/// @notice Returns all the addresses with the pauser role.
/// @return pausersList The list of all the pausers, ordered arbitrarily.
/// The list's order may change after granting or revoking the pauser role.
function allPausers() public view returns (address[] memory pausersList) {
return _managedStorage().pausers.values();
}

/// @notice Returns true if the contract is paused, and false otherwise.
function isPaused() public view returns (bool) {
return _managedStorage().isPaused;
}

/// @notice Triggers stopped state. Callable only by the admin or a pauser.
function pause() public onlyAdminOrPauser whenNotPaused {
_managedStorage().isPaused = true;
emit Paused(msg.sender);
}

/// @notice Returns to normal state. Callable only by the admin or a pauser.
function unpause() public onlyAdminOrPauser whenPaused {
_managedStorage().isPaused = false;
emit Unpaused(msg.sender);
function _proposedAdmin() private view returns (StorageSlot.AddressSlot storage) {
return StorageSlot.getAddressSlot(_proposedAdminStorageSlot);
}

/// @notice Calculates the quasi ERC-1967 slot pointer.
Expand All @@ -183,16 +91,6 @@ abstract contract Managed is UUPSUpgradeable {
return bytes32(uint256(keccak256(bytes(name))) - 1024);
}

/// @notice Returns the Managed storage.
/// @return storageRef The storage.
function _managedStorage() internal view returns (ManagedStorage storage storageRef) {
bytes32 slot = _managedStorageSlot;
// slither-disable-next-line assembly
assembly {
storageRef.slot := slot
}
}

/// @notice Authorizes the contract upgrade. See `UUPSUpgradeable` docs for more details.
function _authorizeUpgrade(address /* newImplementation */ ) internal view override onlyAdmin {
return;
Expand Down
Loading

0 comments on commit addca25

Please sign in to comment.