MurePool

Git Source

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

NameTypeDescription
poolNamestringthe name of the pool to create
paramsPoolParametersthe parameters for the new pool
sigbytesthe 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

NameTypeDescription
poolNamestringthe name of the pool to update
paramsPoolParametersthe 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

NameTypeDescription
poolNamestringthe name of the pool to update
poolSizeuint256the 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

NameTypeDescription
poolNamestringthe name of the pool to update
endTimeuint256the 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

NameTypeDescription
poolNamestringthe name of the pool to update
_signeraddressthe 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

NameTypeDescription
poolNamestringthe name of the pool to pause or unpause
pauseboola 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

NameTypeDescription
poolNamestringthe name of the pool to update
refundableboola 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

NameTypeDescription
poolNamestringthe name of the pool to update
passthroughFundsboola 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

NameTypeDescription
poolNamestringthe 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

NameTypeDescription
receiveraddressthe address to which the token will be transferred
currencyaddressthe 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

NameTypeDescription
poolNamestringthe name of the pool to add the deposit to
depositoraddressthe address of the depositor
amountuint256the 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

NameTypeDescription
poolNamestringthe name of the pool to deduct the deposit from
depositoraddressthe address of the depositor
amountuint256the 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

NameTypeDescription
poolNamestringthe name of the pool to move the deposit in
fromaddressthe address of the depositor to deduct the deposit from
toaddressthe address of the depositor to add the deposit to
amountuint256the 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

NameTypeDescription
poolNamestringthe name of the pool to move the deposit in
transactionsTransaction[]the set of Transactions 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

NameTypeDescription
poolNamestringbytes32 representation of the pool name
amountuint256the amount the user want to invest. Need that for accounting
sigbytesthe 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

NameTypeDescription
poolNamestringbytes32 representation of the pool name
amountuint256the amount the user want to invest. Need that for accounting
databytesadditional data as contextual data for off-chain validation
sigbytesthe 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

NameTypeDescription
poolNamestringbytes32 representation of the pool name
amountuint256the amount the user want to invest. Need that for accounting
depositoraddressaddress of the depositor.
sigbytesthe 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

NameTypeDescription
poolNamestringthe 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

NameTypeDescription
poolNamestringthe name of the pool from which to refund
databytesadditional 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

NameTypeDescription
poolNamestringthe name of the pool from which to refund
depositoraddressaddress of the depositor
amountuint256

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

NameTypeDescription
poolNamestringname of the pool
depositoraddressthe address of the depositor
amountuint256the 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

NameTypeDescription
poolNamestringthe 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

NameTypeDescription
poolNamestringthe 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

NameTypeDescription
poolNamestringthe name of the pool to retrieve the deposit from
depositoraddressthe 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

NameTypeDescription
poolNamestringthe name of the pool to retrieve the nonce from
depositoraddressthe 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

NameTypeDescription
poolstringthe 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

NameTypeDescription
poolNamestringthe 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

NameTypeDescription
poolNamestringthe 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

NameTypeDescription
membersAppMember[]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

NameTypeDescription
poolNamestringbytes32 representation of the pool name
amountuint256the amount the user want to invest. Need that for accounting
depositoraddressaddress of the depositor.
databytesadditional data as contextual data for off-chain validation
sigbytesthe 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

NameTypeDescription
poolNamestringthe name of the pool from which to refund
depositoraddressaddress of the depositor to refund from
amountuint256the amount to refund
databytesadditional 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

NameTypeDescription
poolNamestringname of the pool
depositoraddressthe address of the depositor
amountuint256the 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;

_deductDeposit

Deducts deposit amount from designated poolName under depositor. As totalCollected is the cumulative sum of all depositors 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

NameTypeDescription
poolNamestringname of the pool
depositoraddressthe address of the depositor
currencyaddressthe address of the currency being transferred
amountuint256the 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

NameTypeDescription
fromaddressthe address from which the transfer is initiated
toaddressthe address to which the transfer is made
amountuint256the amount of the currency being transferred
currencyaddressthe 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

NameTypeDescription
poolstringthe name of the pool being checked

_verifyParams

Verifies the validity of the specified pool parameters.

function _verifyParams(PoolParameters calldata config) private view;

Parameters

NameTypeDescription
configPoolParametersthe 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

NameTypeDescription
poolNamestringthe 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

NameTypeDescription
amountuint256the amount of the deposit
poolNamestringthe name of the pool
depositoraddressaddress 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

NameTypeDescription
poolNamestringthe name of the pool
endTimeuint32the 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

NameTypeDescription
totalCollecteduint112total collected amount for the pool being updated
newPoolSizeuint112new 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

NameTypeDescription
flagsuint16the set of flags being checked
flaguint16the 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

NameTypeDescription
flagsuint16the set of flags being modified
flaguint16the flag being activated

_deactivateFlag

Deactivates the specified flag within a set of flags.

function _deactivateFlag(uint16 flags, uint16 flag) private pure returns (uint16);

Parameters

NameTypeDescription
flagsuint16the set of flags being modified
flaguint16the 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

NameTypeDescription
delegateAddressaddressaddress of the delegate contract
poolNamestringname of the pool
amountuint256deposit amount
depositoraddress
sigbytesdeposit signature

_afterDeposit

Performs delegate operations after deposit operation.

function _afterDeposit(
    address delegateAddress,
    string calldata poolName,
    uint256 amount,
    address depositor,
    bytes calldata sig
) private;

Parameters

NameTypeDescription
delegateAddressaddressaddress of the delegate contract
poolNamestringname of the pool
amountuint256deposit amount
depositoraddress
sigbytesdeposit signature

_beforeRefund

Performs delegate operations before refund operation.

function _beforeRefund(address delegateAddress, string calldata poolName, address depositor) private;

Parameters

NameTypeDescription
delegateAddressaddressaddress of the delegate contract
poolNamestringname of the pool
depositoraddressaddress of the depositor

_afterRefund

Performs delegate operations after refund operation.

function _afterRefund(address delegateAddress, string calldata poolName, address depositor, uint256 amount) private;

Parameters

NameTypeDescription
delegateAddressaddressaddress of the delegate contract
poolNamestringname of the pool
depositoraddressaddress of the depositor
amountuint256the 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

struct MurePoolStorage {
    mapping(string => PoolState) pools;
    mapping(string => mapping(address => DepositRecord)) deposits;
    uint24 nonce;
}

PoolMetricsStorage

struct PoolMetricsStorage {
    mapping(string => PoolMetrics) poolMetrics;
}