-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add n of m multisignature #864
base: main
Are you sure you want to change the base?
Conversation
Reviewer's Guide by SourceryThis pull request introduces a multi-signature access control mechanism for key functions in the Sequence diagram for mintWithMultisig functionsequenceDiagram
participant User
participant dApp
participant Signer1
participant Signer2
participant BondContract
User->>dApp: Initiates mintWithMultisig(to, amount)
dApp->>dApp: Generates operationId
dApp->>dApp: Computes operationHash (keccak256(abi.encode("MINT", to, amount)))
dApp->>Signer1: Requests signature for (operationId, operationHash)
activate Signer1
Signer1-->>dApp: Signs typed data (domain, types, value)
deactivate Signer1
dApp->>Signer2: Requests signature for (operationId, operationHash)
activate Signer2
Signer2-->>dApp: Signs typed data (domain, types, value)
deactivate Signer2
dApp->>BondContract: mintWithMultisig(to, amount, signatures, operationId)
activate BondContract
BondContract->>BondContract: Checks if operationId is used
BondContract->>BondContract: Validates signatures and role
BondContract->>BondContract: _mint(to, amount)
BondContract-->>dApp: Success
deactivate BondContract
dApp-->>User: Success
Updated class diagram for Bond contractclassDiagram
class Bond {
-uint256 maturityDate
-uint256 faceValue
-address underlyingAsset
-bool isMatured
-mapping(address => uint256) redeemedAmount
+constructor(string name, string symbol, uint8 decimals, address initialOwner, string isin, uint256 _cap, uint256 _maturityDate, uint256 _faceValue, address _underlyingAsset, uint256 signatureThreshold, address forwarder)
+mint(address to, uint256 amount)
+mintWithMultisig(address to, uint256 amount, bytes[] calldata signatures, bytes32 operationId)
+mature()
+matureWithMultisig(bytes[] calldata signatures, bytes32 operationId)
+_mature()
+redeem(uint256 amount)
+withdrawUnderlyingAsset(address to, uint256 amount)
+withdrawUnderlyingAssetWithMultisig(address to, uint256 amount, bytes[] calldata signatures, bytes32 operationId)
+withdrawExcessUnderlyingAssets(address to)
+withdrawExcessUnderlyingAssetsWithMultisig(address to, bytes[] calldata signatures, bytes32 operationId)
+withdrawableUnderlyingAmount() uint256
}
Bond --|> ERC20MultiSigAccessControl : inherits
Bond --|> ERC20Burnable
Bond --|> ERC20Pausable
Bond --|> ERC20Permit
Bond --|> ERC20Capped
Bond --|> ERC20Blocklist
Bond --|> ERC20Custodian
Bond --|> ERC2771Context
note for Bond "Added mintWithMultisig, matureWithMultisig, withdrawUnderlyingAssetWithMultisig, withdrawExcessUnderlyingAssetsWithMultisig functions and signatureThreshold constructor parameter"
Updated class diagram for Fund contractclassDiagram
class Fund {
-uint16 managementFeeBps
-string fundClass
-string fundCategory
+constructor(string name, string symbol, uint8 decimals, address initialOwner, string isin, uint16 managementFeeBps_, string memory fundClass_, string memory fundCategory_, uint256 signatureThreshold, address forwarder)
+mint(address to, uint256 amount)
+mintWithMultisig(address to, uint256 amount, bytes[] calldata signatures, bytes32 operationId)
+withdrawToken(address token, address to, uint256 amount)
+withdrawTokenWithMultisig(address token, address to, uint256 amount, bytes[] calldata signatures, bytes32 operationId)
+_withdrawToken(address token, address to, uint256 amount)
}
Fund --|> ERC20MultiSigAccessControl : inherits
Fund --|> ERC20Burnable
Fund --|> ERC20Pausable
Fund --|> ERC20Permit
Fund --|> ERC20Blocklist
Fund --|> ERC20Custodian
Fund --|> ERC20Votes
Fund --|> ERC2771Context
note for Fund "Added mintWithMultisig, withdrawTokenWithMultisig functions and signatureThreshold constructor parameter"
Updated class diagram for StableCoin contractclassDiagram
class StableCoin {
-CollateralProof _collateralProof
-string isin
+constructor(string name, string symbol, uint8 decimals, address initialOwner, string isin_, uint48 collateralLivenessSeconds, uint256 signatureThreshold, address forwarder)
+mint(address to, uint256 amount)
+mintWithMultisig(address to, uint256 amount, bytes[] calldata signatures, bytes32 operationId)
+updateCollateral(uint256 amount)
+updateCollateralWithMultisig(uint256 amount, bytes[] calldata signatures, bytes32 operationId)
+_updateCollateral(uint256 amount)
}
StableCoin --|> ERC20MultiSigAccessControl : inherits
StableCoin --|> ERC20Burnable
StableCoin --|> ERC20Pausable
StableCoin --|> ERC20Permit
StableCoin --|> ERC20Blocklist
StableCoin --|> ERC20Collateral
StableCoin --|> ERC20Custodian
StableCoin --|> ERC20Votes
StableCoin --|> ERC2771Context
note for StableCoin "Added mintWithMultisig, updateCollateralWithMultisig functions and signatureThreshold constructor parameter"
Updated class diagram for Equity contractclassDiagram
class Equity {
-string isin
-string equityClass
-string equityCategory
+constructor(string name, string symbol, uint8 decimals, address initialOwner, string isin_, string equityClass_, string equityCategory_, uint256 signatureThreshold, address forwarder)
+mint(address to, uint256 amount)
+mintWithMultisig(address to, uint256 amount, bytes[] calldata signatures, bytes32 operationId)
}
Equity --|> ERC20MultiSigAccessControl : inherits
Equity --|> ERC20Burnable
Equity --|> ERC20Pausable
Equity --|> ERC20Permit
Equity --|> ERC20Blocklist
Equity --|> ERC20Custodian
Equity --|> ERC20Votes
Equity --|> ERC2771Context
note for Equity "Added mintWithMultisig function and signatureThreshold constructor parameter"
Class diagram for ERC20MultiSigAccessControl contractclassDiagram
class ERC20MultiSigAccessControl {
-uint256 signatureThreshold
-mapping(bytes32 => bool) _usedOperationIds
+constructor(uint256 signatureThreshold_)
+MULTISIG_TYPEHASH
+withMultisig(bytes32 role, bytes[] calldata signatures, bytes32 operationId, bytes32 operationHash) modifier
+setSignatureThreshold(uint256 newThreshold)
+isOperationUsed(bytes32 operationId) external view returns (bool)
}
ERC20MultiSigAccessControl --|> AccessControl : inherits
ERC20MultiSigAccessControl --|> EIP712 : inherits
note for ERC20MultiSigAccessControl "Introduces multi-signature access control mechanism"
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @roderik - I've reviewed your changes - here's some feedback:
Overall Comments:
- Consider adding a function to query the
signatureThreshold
during contract creation in the factory contracts. - The
operationHash
inwithMultisig
should include the contract address to prevent cross-contract replay attacks.
Here's what I looked at during the review
- 🟢 General issues: all looks good
- 🟢 Security: all looks good
- 🟢 Review instructions: all looks good
- 🟢 Testing: all looks good
- 🟢 Complexity: all looks good
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
R&D for v2 - Multisig actions
Tests need to be updated!
In the dAPP
For this, the signer should expose signTypedData json-rpc calls (i think they exist in the evm rc schema somehwere)
Summary by Sourcery
Implements a multi-signature access control mechanism for Equity, StableCoin, Bond, and Fund contracts, requiring multiple signatures for sensitive operations like minting, maturing, and withdrawing assets. This enhances security by preventing unauthorized actions and ensuring that critical decisions require consensus among authorized parties.
New Features:
mintWithMultisig
,matureWithMultisig
,withdrawUnderlyingAssetWithMultisig
,withdrawExcessUnderlyingAssetsWithMultisig
, andwithdrawTokenWithMultisig
functions to enable multi-signature authorization for minting, maturing, withdrawing assets, and withdrawing tokens.Enhancements:
AccessControl
with a newERC20MultiSigAccessControl
contract that implements the multi-signature logic.signatureThreshold
to the Equity, StableCoin, Bond, and Fund contracts, allowing the contract creator to specify the number of signatures required for multi-signature operations.signatureThreshold
parameter in the contract creation process.