MultiAccount (0.8.4)

MultiAccount (0.8.4)

The MultiAccount module enables users to create sub‑accounts that are whitelisted to interact with hedgers. These sub‑accounts allow positions to be either in cross (all positions sharing collateral) or isolated (separate sub‑accounts). In addition to standard account creation and fund management, MultiAccount introduces robust access delegation features. In version 0.8.4, a key update is the two‑step revocation process for delegated access.

New Revocation Process: In earlier versions, users could revoke delegated access instantly. However, this sometimes led hedgers to execute actions (like sending quotes on behalf of users) only to have their access revoked unexpectedly. Now, users must first propose revocation using the proposeToRevokeAccesses method. After a configured cooldown period elapses, they can then revoke the access with the revokeAccesses method. This ensures that hedgers have advanced notice before their access is removed.

Initialization and Setup

initialize()

Initializes the MultiAccount contract with the necessary roles and addresses. It sets the administrator, the address of the Symmio platform, and the bytecode for the account implementation.

Function Signature:

function initialize(address admin, address symmioAddress_, bytes memory accountImplementation_) public initializer;

Parameters:

  • admin: The administrator’s address (granted default admin, pauser, unpauser, and setter roles).

  • symmioAddress_: The address of the Symmio platform.

  • accountImplementation_: The bytecode for the account implementation to be used for deploying sub‑accounts.

Example Usage:

multiAccount.initialize(adminAddress, symmioPlatformAddress, accountImplBytecode);

Account Management

addAccount()

Creates a new sub‑account for the caller with a specified name. Each new account is deployed using the current account implementation and is mapped to the owner’s address.

Function Signature:

function addAccount(string memory name) external whenNotPaused;

Parameters:

  • name: The name of the new sub‑account.

Example Usage:

multiAccount.addAccount("My Trading Account");

Events Emitted:

  • AddAccount(address owner, address account, string name)


editAccountName()

Allows the owner to change the name of an existing sub‑account.

Function Signature:

function editAccountName(address accountAddress, string memory name) external whenNotPaused;

Parameters:

  • accountAddress: The address of the sub‑account to rename.

  • name: The new name for the account.

Example Usage:

multiAccount.editAccountName(accountAddress, "Updated Account Name");

Events Emitted:

  • EditAccountName(address owner, address account, string newName)


depositForAccount()

Deposits funds into a sub‑account from the owner’s balance. It calls the Symmio platform’s deposit function on behalf of the account.

Function Signature:

function depositForAccount(address account, uint256 amount) external onlyOwner(account, msg.sender) whenNotPaused;

Parameters:

  • account: The address of the sub‑account.

  • amount: The amount to deposit.

Example Usage:

multiAccount.depositForAccount(accountAddress, 1000);

Events Emitted:

  • DepositForAccount(address owner, address account, uint256 amount)


depositAndAllocateForAccount()

Deposits funds into a sub‑account and immediately allocates them for trading. The deposited amount is converted to 18 decimals before being allocated.

Function Signature:

function depositAndAllocateForAccount(address account, uint256 amount) external onlyOwner(account, msg.sender) whenNotPaused;

Parameters:

  • account: The address of the sub‑account.

  • amount: The amount to deposit and allocate.

Example Usage:

multiAccount.depositAndAllocateForAccount(accountAddress, 1000);

Events Emitted:

  • DepositForAccount(address owner, address account, uint256 amount)

  • AllocateForAccount(address owner, address account, uint256 amountWith18Decimals)


withdrawFromAccount()

Withdraws funds from a sub‑account back to the owner’s address. It calls the Symmio platform’s withdrawal function.

Function Signature:

function withdrawFromAccount(address account, uint256 amount) external onlyOwner(account, msg.sender) whenNotPaused;

Parameters:

  • account: The address of the sub‑account.

  • amount: The amount to withdraw.

Example Usage:

multiAccount.withdrawFromAccount(accountAddress, 500);

Events Emitted:

  • WithdrawFromAccount(address owner, address account, uint256 amount)


Access Delegation and Revocation

delegateAccess()

Description: Allows the owner of a sub‑account to delegate access to a target address for a specific function. This enables external addresses (such as hedgers) to perform actions on behalf of the sub‑account.

Function Signature:

function delegateAccess(address account, address target, bytes4 selector) external onlyOwner(account, msg.sender);

Parameters:

  • account: The address of the sub‑account.

  • target: The target contract address for which access is delegated.

  • selector: The function selector (first 4 bytes of the function signature) for which access is granted.

Example Usage:

bytes4 selector = bytes4(keccak256("sendQuote(uint256)"));
multiAccount.delegateAccess(accountAddress, hedgerAddress, selector);

Events Emitted:

  • DelegateAccess(address account, address target, bytes4 selector, bool state) (state will be true)


delegateAccesses()

Batch version of delegateAccess. Delegates access for multiple function selectors at once.

Function Signature:

function delegateAccesses(address account, address target, bytes4[] memory selector) external onlyOwner(account, msg.sender);

Parameters:

  • account: The sub‑account address.

  • target: The target contract address.

  • selector: An array of function selectors to delegate access for.

Example Usage:

bytes4[] memory selectors = new bytes4[](2);
selectors[0] = bytes4(keccak256("sendQuote(uint256)"));
selectors[1] = bytes4(keccak256("withdraw(uint256)"));
multiAccount.delegateAccesses(accountAddress, hedgerAddress, selectors);

Events Emitted:

  • DelegateAccesses(address account, address target, bytes4[] selectors, bool state) (state will be true)


proposeToRevokeAccesses()

Proposes revoking delegated access from a target address for one or more function selectors. The proposal timestamp is recorded. Revocation does not take effect immediately; it only becomes actionable after the cooldown period.

Function Signature:

function proposeToRevokeAccesses(address account, address target, bytes4[] memory selector) external onlyOwner(account, msg.sender);

Parameters:

  • account: The sub‑account address.

  • target: The target contract address from which access is to be revoked.

  • selector: An array of function selectors for which revocation is proposed.

Example Usage:

multiAccount.proposeToRevokeAccesses(accountAddress, hedgerAddress, selectors);

Events Emitted:

  • ProposeToRevokeAccesses(address account, address target, bytes4[] selectors)


revokeAccesses()

After the revoke cooldown period has elapsed, this function allows the owner to revoke delegated access for the specified function selectors from a target address.

Function Signature:

function revokeAccesses(address account, address target, bytes4[] memory selector) external onlyOwner(account, msg.sender);

Parameters:

  • account: The sub‑account address.

  • target: The target contract address from which access will be revoked.

  • selector: An array of function selectors to revoke.

Example Usage:

multiAccount.revokeAccesses(accountAddress, hedgerAddress, selectors);

Events Emitted:

  • DelegateAccesses(address account, address target, bytes4[] selectors, bool state) (state will be false)


setRevokeCooldown()

Sets the cooldown period for the revocation process. This determines how long after proposing revocation the owner must wait before actually revoking access.

Function Signature:

function setRevokeCooldown(uint256 cooldown) external onlyRole(SETTER_ROLE);

Parameters:

  • cooldown: The new cooldown period in seconds.

Example Usage:

multiAccount.setRevokeCooldown(300); // Set cooldown to 300 seconds (5 minutes)

Events Emitted:

  • SetRevokeCooldown(uint256 oldCooldown, uint256 newCooldown)


Configuration and Address Management

setAccountImplementation()

Updates the bytecode for the account implementation used to deploy new sub‑accounts.

Function Signature:

function setAccountImplementation(bytes memory accountImplementation_) external onlyRole(SETTER_ROLE);

Parameters:

  • accountImplementation_: The new account implementation bytecode.

Example Usage:

multiAccount.setAccountImplementation(newAccountImplBytecode);

Events Emitted:

  • SetAccountImplementation(bytes oldImplementation, bytes newImplementation)


setSymmioAddress()

Updates the address of the Symmio platform with which the MultiAccount contract interacts.

Function Signature:

function setSymmioAddress(address addr) external onlyRole(SETTER_ROLE);

Parameters:

  • addr: The new Symmio platform address.

Example Usage:

multiAccount.setSymmioAddress(newSymmioAddress);

Events Emitted:

  • SetSymmioAddress(address oldAddress, address newAddress)


Internal Functions

_deployPartyA()

Deploys a new Party A sub‑account using the current account implementation and a unique salt (via create2).

Function Signature:

function _deployPartyA() internal returns (address account);

Example: This function is called internally by addAccount.


_deployContract()

Deploys a contract using the create2 opcode with the specified bytecode and salt.

Function Signature:

function _deployContract(bytes memory bytecode, bytes32 salt) internal returns (address contractAddress);

Example: Called by _deployPartyA to deploy a new sub‑account.


Pausable Functionality

pause() / unpause()

Allows authorized users (with PAUSER_ROLE/UNPAUSER_ROLE) to pause or unpause the MultiAccount contract, halting or resuming all operations.

Function Signatures:

function pause() external onlyRole(PAUSER_ROLE);
function unpause() external onlyRole(UNPAUSER_ROLE);

Example Usage:

multiAccount.pause();
multiAccount.unpause();

View Functions

getAccountsLength()

Description: Returns the number of sub‑accounts owned by a specific user.

Function Signature:

function getAccountsLength(address user) external view returns (uint256);

Example Usage:

uint256 numAccounts = multiAccount.getAccountsLength(userAddress);

getAccounts()

Retrieves an array of sub‑accounts owned by a user, with pagination parameters.

Function Signature:

function getAccounts(address user, uint256 start, uint256 size) external view returns (Account[] memory);

Parameters:

  • user: The owner’s address.

  • start: The starting index.

  • size: The number of accounts to return.

Example Usage:

Account[] memory userAccounts = multiAccount.getAccounts(userAddress, 0, 10);

Last updated