Skip to content

Commit 00702f5

Browse files
committed
refactor: added pause protocol
1 parent 9218fcc commit 00702f5

10 files changed

Lines changed: 151 additions & 131 deletions

File tree

contracts/assets/AssetOwnership.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ contract AssetOwnership is
125125
/// @dev Requires approval before an asset can be registered.
126126
/// @param to The address that will own the minted NFT.
127127
/// @param assetId The unique identifier for the asset, serving as the NFT ID.
128+
// TODO pause
128129
function register(address to, uint256 assetId) external onlyApprovedAsset(to, assetId) {
129130
_mint(to, assetId);
130131
_enableAsset(assetId);

contracts/core/interfaces/economics/ITreasury.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// SPDX-License-Identifier: BUSL-1.1
22
// NatSpec format convention - https://docs.soliditylang.org/en/v0.5.10/natspec-format.html
33
pragma solidity 0.8.26;
4+
import { IBalanceOperator } from "@synaps3/core/interfaces/base/IBalanceOperator.sol";
45

56
/// @title ITreasury Interface
67
/// @notice Defines the standard functions for a Treasury contract.
7-
interface ITreasury {
8+
interface ITreasury is IBalanceOperator {
89
/// @notice Collects accrued fees for a specified currency from an authorized fee collector.
910
/// @param collector The address of an authorized fee collector.
1011
/// @param currency The address of the currency for which fees are being collected.

contracts/core/interfaces/financial/ILedgerVault.sol

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,11 @@ pragma solidity 0.8.26;
44

55
import { IBalanceOperator } from "@synaps3/core/interfaces/base/IBalanceOperator.sol";
66
import { IAllowanceOperator } from "@synaps3/core/interfaces/base/IAllowanceOperator.sol";
7+
import { ILockOperator } from "@synaps3/core/interfaces/base/ILockOperator.sol";
78

89
/// @title ILedgerVault
910
/// @notice Interface for managing locked funds and their operations.
1011
/// @dev Extends IBalanceOperator for managing user balances in a vault-like system.
11-
interface ILedgerVault is IBalanceOperator, IAllowanceOperator {
12-
/// @notice Locks a specific amount of funds for a given account.
13-
/// @dev The funds are immobilized and cannot be withdrawn or transferred until released or claimed.
14-
/// @param account The address of the account for which the funds will be locked.
15-
/// @param amount The amount of funds to lock.
16-
/// @param currency The currency to associate fees with. Use address(0) for the native coin.
17-
function lock(address account, uint256 amount, address currency) external returns (uint256);
12+
interface ILedgerVault is IBalanceOperator, IAllowanceOperator, ILockOperator {
1813

19-
/// @notice Claims a specific amount of locked funds on behalf of a claimer.
20-
/// @dev The claimer is authorized to withdraw or process the funds from the account.
21-
/// @param account The address of the account whose funds are being claimed.
22-
/// @param amount The amount of funds to claim.
23-
/// @param currency The currency to associate fees with. Use address(0) for the native coin.
24-
function claim(address account, uint256 amount, address currency) external returns (uint256);
25-
26-
/// @notice Release a specific amount of funds from locked pool.
27-
/// @param account The address of the account for which the funds will be released.
28-
/// @param amount The amount of funds to release.
29-
/// @param currency The currency to associate release with. Use address(0) for the native coin.
30-
function release(address account, uint256 amount, address currency) external returns (uint256);
3114
}

contracts/core/primitives/upgradeable/AccessControlledUpgradeable.sol

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
pragma solidity 0.8.26;
44

55
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
6+
import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
67
// solhint-disable-next-line max-line-length
78
import { AccessManagedUpgradeable } from "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol";
89
import { IAccessManager } from "@synaps3/core/interfaces/access/IAccessManager.sol";
@@ -11,7 +12,7 @@ import { C } from "@synaps3/core/primitives/Constants.sol";
1112
/// @title AccessControlledUpgradeable
1213
/// @dev Abstract contract that provides role-based access control functionality to upgradeable contracts.
1314
/// This contract requires an AccessManager to manage roles.
14-
abstract contract AccessControlledUpgradeable is Initializable, AccessManagedUpgradeable {
15+
abstract contract AccessControlledUpgradeable is Initializable, AccessManagedUpgradeable, PausableUpgradeable {
1516
/// @custom:storage-location erc7201:accesscontrolledupgradeable
1617
struct AccessControlStorage {
1718
address _accessManager;
@@ -36,7 +37,21 @@ abstract contract AccessControlledUpgradeable is Initializable, AccessManagedUpg
3637
_;
3738
}
3839

39-
// @dev Initializes the contract and ensures it is upgradeable.
40+
/// @notice Pauses the contract, disabling state-changing operations.
41+
/// @dev Can only be called by an account with the operator/admin role (`restricted`).
42+
/// Once paused, functions guarded by `whenNotPaused` will revert until `unpause` is called.
43+
function pause() external restricted {
44+
_pause();
45+
}
46+
47+
/// @notice Unpauses the contract, re-enabling state-changing operations.
48+
/// @dev Can only be called by an account with the operator/admin role (`restricted`).
49+
/// Once unpaused, functions guarded by `whenNotPaused` will operate normally again.
50+
function unpause() external restricted {
51+
_unpause();
52+
}
53+
54+
/// @dev Initializes the contract and ensures it is upgradeable.
4055
/// Even if the initialization is harmless, this ensures the contract follows upgradeable contract patterns.
4156
/// This is the method to initialize this contract and any other extended contracts.
4257
/// @param accessManager The address of the AccessManager contract.

contracts/core/primitives/upgradeable/AllowanceOperatorUpgradeable.sol

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ abstract contract AllowanceOperatorUpgradeable is Initializable, LedgerUpgradeab
2323
/// @dev Storage slot for AllowanceOperatorUpgradeable, calculated using a unique namespace to avoid conflicts.
2424
/// The `ALLOWANCE_OPERATOR_SLOT` constant is used to point to the location of the storage.
2525
bytes32 private constant ALLOWANCE_OPERATOR_SLOT =
26-
0xa8707513830ffbd3c47e0c83d1f5f0270db240ae37bb1f9a13f077f85b949c00;
26+
0x60503404921b66adfd164bd2cecacde1d9102b9421dba47f75ca95001753aa00;
2727

2828
/// @dev Initializes the contract and ensures it is upgradeable.
2929
/// Even if the initialization is harmless, this ensures the contract follows upgradeable contract patterns.
@@ -53,11 +53,11 @@ abstract contract AllowanceOperatorUpgradeable is Initializable, LedgerUpgradeab
5353
/// @param to The address of the recipient for whom the funds are being approved.
5454
/// @param amount The amount of funds to approve.
5555
/// @param currency The address of the ERC20 token to approve. Use `address(0)` for native tokens.
56-
function approve(
56+
function _approve(
5757
address to,
5858
uint256 amount,
5959
address currency
60-
) public virtual onlyValidOperation(to, amount) returns (uint256) {
60+
) internal onlyValidOperation(to, amount) returns (uint256) {
6161
if (msg.sender == to) revert InvalidOperationParameters();
6262
_sumApprovedAmount(msg.sender, to, amount, currency);
6363
emit FundsApproved(msg.sender, to, amount, currency);
@@ -68,11 +68,11 @@ abstract contract AllowanceOperatorUpgradeable is Initializable, LedgerUpgradeab
6868
/// @param to The address of the recipient whose approval is being revoked.
6969
/// @param currency The address of the ERC20 token associated with the approval. Use `address(0)` for native tokens.
7070
/// @return The amount of funds that were revoked from the approval.
71-
function revoke(
71+
function _revoke(
7272
address to,
7373
uint256 amount,
7474
address currency
75-
) public virtual onlyValidOperation(to, amount) returns (uint256) {
75+
) internal onlyValidOperation(to, amount) returns (uint256) {
7676
if (getApprovedAmount(msg.sender, to, currency) < amount) revert NoFundsToRevoke();
7777
_subApprovedAmount(msg.sender, to, amount, currency);
7878
emit FundsRevoked(msg.sender, to, amount, currency);
@@ -83,11 +83,11 @@ abstract contract AllowanceOperatorUpgradeable is Initializable, LedgerUpgradeab
8383
/// @param from The address of the account from which the approved funds are being collected.
8484
/// @param amount The amount of funds to collect.
8585
/// @param currency The address of the ERC20 token to collect. Use `address(0)` for native tokens.
86-
function collect(
86+
function _collect(
8787
address from,
8888
uint256 amount,
8989
address currency
90-
) public virtual onlyValidOperation(from, amount) returns (uint256) {
90+
) internal onlyValidOperation(from, amount) returns (uint256) {
9191
if (getApprovedAmount(from, msg.sender, currency) < amount) revert NoFundsToCollect(); //
9292
if (getLedgerBalance(from, currency) < amount) revert NoFundsToCollect(); // no balance
9393

contracts/core/primitives/upgradeable/BalanceOperatorUpgradeable.sol

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ pragma solidity 0.8.26;
44

55
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
66
// solhint-disable-next-line max-line-length
7-
import { ReentrancyGuardTransientUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardTransientUpgradeable.sol";
87
import { LedgerUpgradeable } from "@synaps3/core/primitives/upgradeable/LedgerUpgradeable.sol";
98
import { IBalanceOperator } from "@synaps3/core/interfaces/base/IBalanceOperator.sol";
109
import { FinancialOps } from "@synaps3/core/libraries/FinancialOps.sol";
@@ -13,12 +12,7 @@ import { FinancialOps } from "@synaps3/core/libraries/FinancialOps.sol";
1312
/// @dev Abstract contract for managing deposits and withdrawals with ledger tracking capabilities.
1413
/// Provides core functionalities to handle funds in an upgradeable system.
1514
/// This contract integrates with the ledger system to record balances and transactions.
16-
abstract contract BalanceOperatorUpgradeable is
17-
Initializable,
18-
LedgerUpgradeable,
19-
ReentrancyGuardTransientUpgradeable,
20-
IBalanceOperator
21-
{
15+
abstract contract BalanceOperatorUpgradeable is Initializable, LedgerUpgradeable, IBalanceOperator {
2216
using FinancialOps for address;
2317

2418
/// @custom:storage-location erc7201:balanceoperatorupgradeable
@@ -36,7 +30,6 @@ abstract contract BalanceOperatorUpgradeable is
3630
/// This is the method to initialize this contract and any other extended contracts.
3731
function __BalanceOperator_init() internal onlyInitializing {
3832
__Ledger_init();
39-
__ReentrancyGuardTransient_init();
4033
}
4134

4235
/// @dev Function to initialize the contract without chaining, typically used in child contracts.
@@ -54,11 +47,11 @@ abstract contract BalanceOperatorUpgradeable is
5447
/// @param recipient The address of the account to credit with the deposit.
5548
/// @param amount The amount of currency to deposit.
5649
/// @param currency The address of the ERC20 token to deposit.
57-
function deposit(
50+
function _deposit(
5851
address recipient,
5952
uint256 amount,
6053
address currency
61-
) public virtual onlyValidOperation(recipient, amount) returns (uint256) {
54+
) internal onlyValidOperation(recipient, amount) returns (uint256) {
6255
uint256 confirmed = msg.sender.safeDeposit(amount, currency);
6356
_sumLedgerEntry(recipient, confirmed, currency);
6457
emit FundsDeposited(recipient, msg.sender, confirmed, currency);
@@ -69,11 +62,11 @@ abstract contract BalanceOperatorUpgradeable is
6962
/// @param recipient The address that will receive the withdrawn tokens.
7063
/// @param amount The amount of tokens to withdraw.
7164
/// @param currency The currency to associate fees with. Use address(0) for the native coin.
72-
function withdraw(
65+
function _withdraw(
7366
address recipient,
7467
uint256 amount,
7568
address currency
76-
) public virtual onlyValidOperation(recipient, amount) nonReentrant returns (uint256) {
69+
) internal onlyValidOperation(recipient, amount) returns (uint256) {
7770
if (getLedgerBalance(msg.sender, currency) < amount) revert NoFundsToWithdraw();
7871
_subLedgerEntry(msg.sender, amount, currency);
7972
recipient.transfer(amount, currency); // transfer fund to recipient
@@ -85,11 +78,11 @@ abstract contract BalanceOperatorUpgradeable is
8578
/// @param recipient The address of the account to credit with the transfer.
8679
/// @param amount The amount of tokens to transfer.
8780
/// @param currency The address of the currency to transfer. Use `address(0)` for the native coin.
88-
function transfer(
81+
function _transfer(
8982
address recipient,
9083
uint256 amount,
9184
address currency
92-
) public virtual onlyValidOperation(recipient, amount) returns (uint256) {
85+
) internal onlyValidOperation(recipient, amount) returns (uint256) {
9386
if (msg.sender == recipient) revert InvalidOperationParameters();
9487
if (getLedgerBalance(msg.sender, currency) < amount) revert NoFundsToTransfer();
9588

contracts/custody/CustodianReferendum.sol

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ contract CustodianReferendum is
7979
// in that way the custodian is omitted during load balancing.
8080
// in this line we can check if the custodian contract is active custodian.isActive()
8181
// this is important feature if the custodians want to avoid harm reputation
82-
8382
return _status(uint160(custodian)) == T.Status.Active;
8483
}
8584

@@ -99,7 +98,7 @@ contract CustodianReferendum is
9998

10099
/// @notice Registers a custodian to be approved by council.
101100
/// @param custodian The address of the custodian to register.
102-
function register(address custodian) external onlyValidCustodian(custodian) {
101+
function register(address custodian) external whenNotPaused onlyValidCustodian(custodian) {
103102
// register custodian as pending approval
104103
_register(uint160(custodian));
105104
// set the custodian active enrollment period..

contracts/economics/Treasury.sol

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pragma solidity 0.8.26;
55
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
66
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
77
import { AccessControlledUpgradeable } from "@synaps3/core/primitives/upgradeable/AccessControlledUpgradeable.sol";
8+
import { ReentrancyGuardTransientUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardTransientUpgradeable.sol";
89
import { BalanceOperatorUpgradeable } from "@synaps3/core/primitives/upgradeable/BalanceOperatorUpgradeable.sol";
910

1011
import { ITreasury } from "@synaps3/core/interfaces/economics/ITreasury.sol";
@@ -19,6 +20,7 @@ contract Treasury is
1920
Initializable,
2021
UUPSUpgradeable,
2122
AccessControlledUpgradeable,
23+
ReentrancyGuardTransientUpgradeable,
2224
BalanceOperatorUpgradeable,
2325
ITreasury
2426
{
@@ -41,6 +43,7 @@ contract Treasury is
4143
function initialize(address accessManager) public initializer {
4244
__UUPSUpgradeable_init();
4345
__BalanceOperator_init();
46+
__ReentrancyGuardTransient_init();
4447
__AccessControlled_init(accessManager);
4548
}
4649

@@ -52,18 +55,49 @@ contract Treasury is
5255
// function allocate(address pool, uint256 amount) restricted;
5356
// eg: proposal: deposit N fees to staking pool, deposit N fees to development pool, rewards, etc
5457

55-
/// @notice Deposits a specified amount of currency into the treasury for a given recipient.
56-
/// @param pool The address of the pool to credit with the deposit.
58+
/// @notice Deposits a specified amount of currency into the treasury for a given recipient (pool).
59+
/// @dev Only whitelisted accounts (via `restricted`) can interact with this method.
60+
/// This prevents arbitrary accounts from injecting funds into the treasury.
61+
/// @param pool The address of the pool credited with the deposit.
5762
/// @param amount The amount of currency to deposit.
58-
/// @param currency The address of the ERC20 token to deposit.
63+
/// @param currency The address of the ERC20 token to deposit (use `address(0)` for native).
64+
/// @return The confirmed deposited amount.
5965
function deposit(
6066
address pool,
6167
uint256 amount,
6268
address currency
63-
) public override(BalanceOperatorUpgradeable) restricted returns (uint256) {
64-
// restricted deposit to avoid invalid operations
65-
// only allowed accounts can interact with this method
66-
return super.deposit(pool, amount, currency);
69+
) external whenNotPaused restricted returns (uint256) {
70+
return _deposit(pool, amount, currency);
71+
}
72+
73+
/// @notice Withdraws tokens from the treasury to a specified recipient.
74+
/// @dev Restricted to authorized accounts (via `restricted`).
75+
/// Ensures treasury funds are only withdrawn under governance-approved flows.
76+
/// @param recipient The address receiving the withdrawn tokens.
77+
/// @param amount The amount of tokens to withdraw.
78+
/// @param currency The token address for the withdrawal (use `address(0)` for native).
79+
/// @return The confirmed withdrawn amount.
80+
function withdraw(
81+
address recipient,
82+
uint256 amount,
83+
address currency
84+
) external whenNotPaused restricted returns (uint256) {
85+
return _withdraw(recipient, amount, currency);
86+
}
87+
88+
/// @notice Transfers tokens internally in the treasury ledger from the caller to a recipient.
89+
/// @dev Restricted to authorized accounts (via `restricted`).
90+
/// Unlike `withdraw`, this does not move funds externally but shifts balances inside the ledger.
91+
/// @param recipient The address credited with the transfer.
92+
/// @param amount The amount to transfer.
93+
/// @param currency The token being transferred (use `address(0)` for native).
94+
/// @return The confirmed transferred amount.
95+
function transfer(
96+
address recipient,
97+
uint256 amount,
98+
address currency
99+
) external whenNotPaused restricted returns (uint256) {
100+
return _transfer(recipient, amount, currency);
67101
}
68102

69103
/// @notice Collects accrued fees for a specified currency from an authorized fee collector. (visitable)
@@ -72,7 +106,7 @@ contract Treasury is
72106
/// Only the governor can execute this function, ensuring controlled fee collection.
73107
/// @param collector The address of an authorized fee collector.
74108
/// @param currency The address of the ERC20 token for which fees are being collected.
75-
function collectFees(address collector, address currency) external restricted nonReentrant {
109+
function collectFees(address collector, address currency) external restricted whenNotPaused nonReentrant {
76110
// TODO update adding amount param on disburse call
77111
// IFeesCollector feesCollector = IFeesCollector(collector);
78112
// uint256 collected = feesCollector.disburse(currency);

0 commit comments

Comments
 (0)