MurePool
Inherits: EIP712Upgradeable, ReentrancyGuardUpgradeable, PausableUpgradeable, ERC165Upgradeable, AccessControlUpgradeable, PoolApp
Author: Mure
Facilitates secure and configurable pool management, supporting operations such as pool creation, deposits, withdrawals, and refunds.
Core implementation contract for pooled investments in the Mure protocol. Utilizes the beacon proxy pattern to deploy multiple proxies, each representing a distinct application within the protocol. The MureFactory contract handles these deployments. Implements the EIP-712 standard for signature validation, preventing unauthorized access. Relies on the MureConfig contract to verify EIP-712 signatures and manage the pool creation process. Interaction with the MureConfig contract allows dynamic configuration and signature validation. Security measures include the OpenZeppelin PausableUpgradeable pattern for emergency pausing, ReentrancyGuardUpgradeable to prevent reentrancy attacks, and role based access control through AccessControlUpgradeable. Flag-based functionality enables features like refundability, passthrough of funds, and more. Provides hooks for custom functionality in pool-related operations Depending on the kind of application, the MurePool proxy instance could be linked to a MureDelegate proxy instance for interacting with various plugins that the protocol provides.
State Variables
MurePoolStorageLocation
Hash for storage location
keccak256(abi.encode(uint256(keccak256("mure.MurePool")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant MurePoolStorageLocation = 0x79bd164051f83036bb52eee1d9b6be5ba887eaf3a9d8907adbaadfa56c970700;
PoolMetricsStorageLocation
Hash for storage location
keccak256(abi.encode(uint256(keccak256("mure.PoolMetrics")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant PoolMetricsStorageLocation = 0x1ca3e723ed845754b3d7cf12c13e1b284ab752e694e983a627f991c98b3a0700;
DEPOSIT_HASH
Struct hash for validating deposits
keccak256("Deposit(uint256 amount,string pool,address depositor,uint8 nonce)")
bytes32 private constant DEPOSIT_HASH = 0xc5b44054231c7194afce4ed4062c5abd2c0cb26e0686f9ba69d2cfc04b490e33;
CREATE_POOL_HASH
Struct hash for validating pool creation
keccak256("CreatePool(string pool,uint32 endTime,uint24 nonce)")
bytes32 private constant CREATE_POOL_HASH = 0x38c6f9238aff6821963f06d84f958ebb018ff9e4343c962882ef7b3308ff1b4d;
MURE_CONFIG
Address for the MureConfig contract
Update config address
address constant MURE_CONFIG = 0x2b727332eF478bAe460ecF0CAb7C1487a87D68B8;
INITIALIZED
Defines if the pool is initialized
uint16 constant INITIALIZED = 0x01;
PAUSED
Defines if the pool is paused from any interaction
uint16 constant PAUSED = 0x02;
PASSTHROUGH_FUNDS
PASSTHROUGH_FUNDS
and REFUNDABLE
cannot be set at the same time
Defines if deposits should pass straight to associtated raising wallet upon deposit
uint16 constant PASSTHROUGH_FUNDS = 0x04;
REFUNDABLE
PASSTHROUGH_FUNDS
and REFUNDABLE
cannot be set at the same time
Defines if the pool is open for claiming refunds
uint16 constant REFUNDABLE = 0x08;
TIERED
Defines if the pool is having tiers and gating
uint16 constant TIERED = 0x10;
CROSS_CHAIN
Defines if the pool is cross-chain enabled, pooling funds across different networks
uint16 constant CROSS_CHAIN = 0x20;
DELEGATED
Defines if the pool allows for use of delegated wallets for security
uint16 constant DELEGATED = 0x40;
Functions
poolValid
modifier poolValid(string calldata poolName);
poolActive
modifier poolActive(string calldata poolName);
poolNotPaused
modifier poolNotPaused(string calldata poolName);
valid
modifier valid(PoolParameters calldata params);
onlyDelegateOrOperator
modifier onlyDelegateOrOperator();
onlyDelegate
modifier onlyDelegate();
notDelegated
modifier notDelegated();
initialize
function initialize(string calldata name, string calldata version, AppMember[] calldata members) external initializer;
createPool
Creates a new pool with the specified parameters.
Requires the pool to not already exist. Can only be called by a pool operator.
function createPool(string calldata poolName, PoolParameters calldata params, bytes memory sig)
external
onlyRole(POOL_OPERATOR_ROLE)
valid(params);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to create |
params | PoolParameters | the parameters for the new pool |
sig | bytes | the signature generated for pool creation for client |
updatePool
Updates the specified pool with the provided parameters.
Requires the pool to exist. Can only be called by a pool operator.
Requires the updated pool size to be greater than or equal to the total amount collected.
function updatePool(string calldata poolName, PoolParameters calldata params)
external
onlyRole(POOL_OPERATOR_ROLE)
valid(params)
poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to update |
params | PoolParameters | the updated parameters for the pool |
updatePoolSize
Updates the size of the specified pool.
Requires the pool to exist. Can only be called by a pool operator.
Requires the new pool size to be greater than or equal to the total amount collected.
function updatePoolSize(string calldata poolName, uint256 poolSize)
external
onlyRole(POOL_OPERATOR_ROLE)
poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to update |
poolSize | uint256 | the updated size of the pool |
updatePoolEndTime
Updates the end time of the specified pool.
Requires the pool to exist. Can only be called by a pool operator.
function updatePoolEndTime(string calldata poolName, uint256 endTime)
external
onlyRole(POOL_OPERATOR_ROLE)
poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to update |
endTime | uint256 | the updated end time for the pool |
updatePoolSigner
Updates the signer of the specified pool.
Requires the pool to exist. Can only be called by a pool operator.
function updatePoolSigner(string calldata poolName, address _signer)
external
onlyRole(POOL_OPERATOR_ROLE)
poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to update |
_signer | address | the updated signer for the pool |
updatePoolPaused
Pauses or unpauses the specified pool.
Requires the pool to exist. Can only be called by a pool operator or delegate.
function updatePoolPaused(string calldata poolName, bool pause) external onlyDelegateOrOperator poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to pause or unpause |
pause | bool | a boolean representing whether to pause or unpause the pool |
updatePoolRefundable
Updates whether the specified pool allows refunds or not.
Requires the pool to exist. Can only be called by a pool operator.
Requires that the pool does not have the PASSTHROUGH_FUNDS
flag set if enabling refunds.
function updatePoolRefundable(string calldata poolName, bool refundable)
external
onlyDelegateOrOperator
poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to update |
refundable | bool | a boolean representing whether refunds should be enabled or not |
updatePoolPassthroughFunds
Updates whether the specified pool passes funds through to the custodian directly or not.
Requires the pool to exist. Can only be called by a pool operator.
Requires that the pool does not have the REFUNDABLE
flag set if enabling passthrough funds.
function updatePoolPassthroughFunds(string calldata poolName, bool passthroughFunds)
external
onlyRole(POOL_OPERATOR_ROLE)
poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to update |
passthroughFunds | bool | a boolean representing whether to enable passthrough funds or not |
withdrawPoolFunds
Withdraws the total collected amount from the specified pool.
Requires the pool to exist. Can only be called by a pool operator or the delegate if it is set.
function withdrawPoolFunds(string calldata poolName) external onlyDelegateOrOperator poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to withdraw from |
withdrawCurrency
Withdraw any token from the contract. This should only be used in emergencies
as this can withdraw capital from any pool, be it active or not. Always prefer using withdrawPoolFunds
over this function, unless you need clean up the contract by, e.g., burning garbage tokens.
function withdrawCurrency(address receiver, address currency) external onlyRole(DEFAULT_ADMIN_ROLE);
Parameters
Name | Type | Description |
---|---|---|
receiver | address | the address to which the token will be transferred |
currency | address | the address of the token contract |
addDeposit
Adds a deposit of the specified amount to the pool for the designated depositor.
Requires the pool to exist. Can only be called by a pool operator.
function addDeposit(string calldata poolName, address depositor, uint256 amount)
external
onlyRole(POOL_OPERATOR_ROLE)
poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to add the deposit to |
depositor | address | the address of the depositor |
amount | uint256 | the amount of the deposit |
deductDeposit
Deducts the specified amount from the deposit of the designated depositor in the pool.
Requires the pool to exist. Can only be called by a pool operator.
function deductDeposit(string calldata poolName, address depositor, uint256 amount)
external
onlyRole(POOL_OPERATOR_ROLE)
poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to deduct the deposit from |
depositor | address | the address of the depositor |
amount | uint256 | the amount to deduct |
moveDeposit
Moves the specified amount from one depositor's deposit to another in the pool.
Requires the pool to exist. Can only be called by a pool operator.
function moveDeposit(string calldata poolName, address from, address to, uint256 amount)
external
onlyRole(POOL_OPERATOR_ROLE)
poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to move the deposit in |
from | address | the address of the depositor to deduct the deposit from |
to | address | the address of the depositor to add the deposit to |
amount | uint256 | the amount to move |
batchDeposit
Adds or deducts balances on a per-depositor basis in batches.
Requires the pool to exist. Can only be called by the contract owner.
function batchDeposit(string calldata poolName, Transaction[] calldata transactions)
external
onlyRole(POOL_OPERATOR_ROLE)
poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to move the deposit in |
transactions | Transaction[] | the set of Transaction s to execute on the provided poolName |
deposit
Deposits amount
of the relevant currency for the pool poolName
.
This operation assumes that the contract is an approved spender of the depositor.
This operation is disabled for delegated pools, use depositFor instead
function deposit(string calldata poolName, uint256 amount, bytes calldata sig) external notDelegated;
Parameters
Name | Type | Description |
---|---|---|
poolName | string | bytes32 representation of the pool name |
amount | uint256 | the amount the user want to invest. Need that for accounting |
sig | bytes | the signatures generated for the user, including the amount. and verifying the signature. |
deposit
Deposits amount
of the relevant currency for the pool poolName
.
This operation assumes that the contract is an approved spender of the depositor.
This operation is disabled for delegated pools, use depositFor instead
function deposit(string calldata poolName, uint256 amount, bytes calldata data, bytes calldata sig)
external
notDelegated;
Parameters
Name | Type | Description |
---|---|---|
poolName | string | bytes32 representation of the pool name |
amount | uint256 | the amount the user want to invest. Need that for accounting |
data | bytes | additional data as contextual data for off-chain validation |
sig | bytes | the signatures generated for the user, including the amount. and verifying the signature. |
depositFor
Deposits amount
of the relevant currency for the pool poolName
.
This operation assumes that the contract is an approved spender of the depositor.
function depositFor(string calldata poolName, uint256 amount, address depositor, bytes calldata sig)
external
onlyDelegate;
Parameters
Name | Type | Description |
---|---|---|
poolName | string | bytes32 representation of the pool name |
amount | uint256 | the amount the user want to invest. Need that for accounting |
depositor | address | address of the depositor. |
sig | bytes | the signatures generated for the user, including the amount. |
refund
Allows a user to refund their deposited amount from the specified pool. This operation is disabled for delegated pools, use refundTo instead.
Requires the pool to exist.
Requires the pool to be not paused and must have the REFUNDABLE
flag set.
function refund(string calldata poolName) external notDelegated;
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool from which to refund |
refund
Allows a user to refund their deposited amount from the specified pool. This operation is disabled for delegated pools, use refundTo instead.
Requires the pool to exist.
Requires the pool to be not paused and must have the REFUNDABLE
flag set.
function refund(string calldata poolName, bytes calldata data) external notDelegated;
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool from which to refund |
data | bytes | additional data as contextual data for off-chain validation |
refundTo
Allows a refund of the deposited amount from the specified pool.
Requires the pool to exist.
Requires the pool to be not paused and must have the REFUNDABLE
flag set.
function refundTo(string calldata poolName, address depositor, uint256 amount) external onlyDelegate;
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool from which to refund |
depositor | address | address of the depositor |
amount | uint256 |
depositPoolFunds
Deposits the withdrawn pool funds back. This operation assumes that the contract is an approved spender of the depositor.
Transfers the original collected funds back to the pool app
function depositPoolFunds(string calldata poolName, address depositor, uint256 amount) external onlyDelegate;
Parameters
Name | Type | Description |
---|---|---|
poolName | string | name of the pool |
depositor | address | the address of the depositor |
amount | uint256 | the amount to be deposited back to the pool |
poolState
Retrieves the state of the specified pool.
Requires the pool to exist.
function poolState(string calldata poolName) external view poolValid(poolName) returns (PoolState memory);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to retrieve the state of |
poolMetrics
Retrieves the metrics of the specified pool.
Requires the pool to exist.
function poolMetrics(string calldata poolName) external view poolValid(poolName) returns (PoolMetrics memory);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to retrieve the metrics of |
deposited
Retrieves the amount deposited by the specified depositor in the specified pool.
Requires the pool to exist.
function deposited(string calldata poolName, address depositor) external view poolValid(poolName) returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to retrieve the deposit from |
depositor | address | the address of the depositor |
nonce
Retrieves the nonce of the specified depositor in the specified pool.
Requires the pool to exist.
function nonce(string calldata poolName, address depositor) external view poolValid(poolName) returns (uint8);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to retrieve the nonce from |
depositor | address | the address of the depositor |
nonce
Retrieves the nonce for create pool signature generation.
function nonce() external view returns (uint24);
poolExists
Checks if the specified pool exists.
function poolExists(string calldata pool) external view returns (bool);
Parameters
Name | Type | Description |
---|---|---|
pool | string | the name of the pool to check for existence |
isPoolActive
Checks if the specified pool is active.
function isPoolActive(string calldata poolName) external view returns (bool);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to check if it is active |
withdrawableAmount
Checks if the specified pool is active.
function withdrawableAmount(string calldata poolName) external view returns (uint112);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool to check if it is active |
supportsInterface
See IERC165-supportsInterface.
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC165Upgradeable, IERC165, AccessControlUpgradeable)
returns (bool);
_grantRolesToMembers
Grants roles to the members based on their specified roles in the struct.
function _grantRolesToMembers(AppMember[] calldata members) private;
Parameters
Name | Type | Description |
---|---|---|
members | AppMember[] | An array of AppMember structs containing the member's address and their role to be granted. |
_deposit
Deposits amount
of the relevant currency for the pool poolName
.
This operation assumes that the contract is an approved spender of the depositor.
function _deposit(string calldata poolName, uint256 amount, address depositor, bytes memory data, bytes calldata sig)
private
whenNotPaused
nonReentrant
poolValid(poolName)
poolActive(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | bytes32 representation of the pool name |
amount | uint256 | the amount the user want to invest. Need that for accounting |
depositor | address | address of the depositor. |
data | bytes | additional data as contextual data for off-chain validation |
sig | bytes | the signatures generated for the user, including the amount. and verifying the signature. |
_refund
Allows a user to refund their deposited amount from the specified pool.
Requires the pool to exist.
Requires the pool to be not paused and must have the REFUNDABLE
flag set.
function _refund(string calldata poolName, address depositor, uint256 amount, bytes memory data)
private
nonReentrant
whenNotPaused
poolNotPaused(poolName)
poolValid(poolName);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool from which to refund |
depositor | address | address of the depositor to refund from |
amount | uint256 | the amount to refund |
data | bytes | additional data as contextual data for off-chain validation |
_depositPoolFunds
Deposits the withdrawn pool funds back.
Transfers the original collected funds back to the pool app
function _depositPoolFunds(string calldata poolName, address depositor, uint256 amount) private nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
poolName | string | name of the pool |
depositor | address | the address of the depositor |
amount | uint256 | the amount to be deposited back to the pool |
_addDeposit
Adds deposit amount
to designated poolName
under depositor
.
As totalCollected
is bound by poolSize
, overflow is not possible unless poolSize
is in a disallowed state to begin with.
function _addDeposit(string calldata poolName, address depositor, uint256 amount, bytes memory data) private;
_unsafeAddDeposit
Adds deposit amount
to designated poolName
under depositor
.
Skips pool size check. To be used for manual overrides like moveDeposit and batchDeposit
function _unsafeAddDeposit(string calldata poolName, address depositor, uint256 amount, bytes memory data) private;
_deductDeposit
Deducts deposit amount
from designated poolName
under depositor
.
As totalCollected
is the cumulative sum of all depositor
s under poolName
,
underflow is not possible unless totalCollected
is in a disallowed state to begin with.
function _deductDeposit(string calldata poolName, address depositor, uint256 amount, bytes memory data) private;
_deductFee
Determines and transfers the mure fee on deposits.
function _deductFee(string calldata poolName, address depositor, address currency, uint256 amount)
private
returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | name of the pool |
depositor | address | the address of the depositor |
currency | address | the address of the currency being transferred |
amount | uint256 | the amount of the currency being transferred |
_transferUpdate
Updates the transfer between two addresses with a specified amount of a given currency.
function _transferUpdate(address from, address to, uint256 amount, address currency) private;
Parameters
Name | Type | Description |
---|---|---|
from | address | the address from which the transfer is initiated |
to | address | the address to which the transfer is made |
amount | uint256 | the amount of the currency being transferred |
currency | address | the address of the currency being transferred |
_poolExists
Checks whether a pool with the specified name exists.
function _poolExists(string calldata pool) private view returns (bool);
Parameters
Name | Type | Description |
---|---|---|
pool | string | the name of the pool being checked |
_verifyParams
Verifies the validity of the specified pool parameters.
function _verifyParams(PoolParameters calldata config) private view;
Parameters
Name | Type | Description |
---|---|---|
config | PoolParameters | the parameters of the pool being verified |
_poolComplete
Checks whether the specified pool has been completed.
function _poolComplete(string calldata poolName) private view returns (bool);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool being checked |
_hashDeposit
Generates a hashed representation of the specified amount and pool name, along with the sender's nonce.
function _hashDeposit(uint256 amount, string calldata poolName, address depositor) private view returns (bytes32);
Parameters
Name | Type | Description |
---|---|---|
amount | uint256 | the amount of the deposit |
poolName | string | the name of the pool |
depositor | address | address of the depositor |
_hashCreatePool
Generates a struct hash of the specified pool name and end time, along with the nonce.
function _hashCreatePool(string calldata poolName, uint32 endTime) private view returns (bytes32);
Parameters
Name | Type | Description |
---|---|---|
poolName | string | the name of the pool |
endTime | uint32 | the endtime block timestamp for the pool |
_verifyPoolSize
Verifies the validity of the pool size for an existing pool.
function _verifyPoolSize(uint112 totalCollected, uint112 newPoolSize) private pure;
Parameters
Name | Type | Description |
---|---|---|
totalCollected | uint112 | total collected amount for the pool being updated |
newPoolSize | uint112 | new pool size for the pool being updated |
_hasFlag
Checks whether a specific flag is activated within a set of flags.
function _hasFlag(uint16 flags, uint16 flag) private pure returns (bool);
Parameters
Name | Type | Description |
---|---|---|
flags | uint16 | the set of flags being checked |
flag | uint16 | the flag being checked for activation |
_activateFlag
Activates the specified flag within a set of flags.
function _activateFlag(uint16 flags, uint16 flag) private pure returns (uint16);
Parameters
Name | Type | Description |
---|---|---|
flags | uint16 | the set of flags being modified |
flag | uint16 | the flag being activated |
_deactivateFlag
Deactivates the specified flag within a set of flags.
function _deactivateFlag(uint16 flags, uint16 flag) private pure returns (uint16);
Parameters
Name | Type | Description |
---|---|---|
flags | uint16 | the set of flags being modified |
flag | uint16 | the flag being deactivated |
_getDelegateAddress
Retrieves the delegate address from config.
function _getDelegateAddress() private returns (address delegate);
_beforeDeposit
Performs delegate operations before deposit operation.
function _beforeDeposit(
address delegateAddress,
string calldata poolName,
uint256 amount,
address depositor,
bytes calldata sig
) private;
Parameters
Name | Type | Description |
---|---|---|
delegateAddress | address | address of the delegate contract |
poolName | string | name of the pool |
amount | uint256 | deposit amount |
depositor | address | |
sig | bytes | deposit signature |
_afterDeposit
Performs delegate operations after deposit operation.
function _afterDeposit(
address delegateAddress,
string calldata poolName,
uint256 amount,
address depositor,
bytes calldata sig
) private;
Parameters
Name | Type | Description |
---|---|---|
delegateAddress | address | address of the delegate contract |
poolName | string | name of the pool |
amount | uint256 | deposit amount |
depositor | address | |
sig | bytes | deposit signature |
_beforeRefund
Performs delegate operations before refund operation.
function _beforeRefund(address delegateAddress, string calldata poolName, address depositor) private;
Parameters
Name | Type | Description |
---|---|---|
delegateAddress | address | address of the delegate contract |
poolName | string | name of the pool |
depositor | address | address of the depositor |
_afterRefund
Performs delegate operations after refund operation.
function _afterRefund(address delegateAddress, string calldata poolName, address depositor, uint256 amount) private;
Parameters
Name | Type | Description |
---|---|---|
delegateAddress | address | address of the delegate contract |
poolName | string | name of the pool |
depositor | address | address of the depositor |
amount | uint256 | the refund amount |
_getStorage
Retrieves the storage for the MurePool contract.
function _getStorage() private pure returns (MurePoolStorage storage $);
_getPoolMetricsStorage
Retrieves the storage for the pool metrics.
function _getPoolMetricsStorage() private pure returns (PoolMetricsStorage storage $);
_verifySignature
function _verifySignature(
uint256 amount,
string calldata poolName,
address depositor,
address signer,
bytes calldata sig
) private view;
Structs
MurePoolStorage
Note: storage-location: erc7201:mure.MurePool
struct MurePoolStorage {
mapping(string => PoolState) pools;
mapping(string => mapping(address => DepositRecord)) deposits;
uint24 nonce;
}
PoolMetricsStorage
Note: storage-location: erc7201:mure.PoolMetrics
struct PoolMetricsStorage {
mapping(string => PoolMetrics) poolMetrics;
}