-
Notifications
You must be signed in to change notification settings - Fork 70
Token Withdrawal Module for token withdrawals on behalf of IPAccount #131
Conversation
Token Management Module for token transfers on behalf of IPAccount
🚨 Report Summary
For more details view the full report in OpenZeppelin Code Inspector |
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.
add proper comments please, also please call out the security risk in the code and PR messages.
If we consider this is a potential risk, then why not just refactor the Module to restrict the module can only transfer the tokens from IPAccount to the IPAccount owner address? in implementation, just removed the parameter function transferERC20(
address payable ipAccount,
address tokenContract,
uint256 amount
) external verifyPermission(ipAccount) {
IIPAccount(ipAccount).execute(
tokenContract,
0,
abi.encodeWithSignature("transfer(address,uint256)", IIPAccount(ipAccount).owner(), amount)
);
} |
This module should not be in the core repo, it should be created in periphery repo: https://github.com/storyprotocol/protocol-periphery/ |
re: periphery @kingster-will re: |
re-re: periphery I definitely agree this should go on periphery, but it's mostly how much extra work we need to do:
|
Only mitigation for that is to use the whitelist Royalty has for ERC20s. |
This Transfer Module also enforces "whitelist" by making each IPAccount approve for a token. Note, this becomes problematic for Royalty NFTs because each RNFT is a different ERC-1155 contract (0xSplits requirement). Every IPAccount has to approve a different 1155 address for itself, really bad UX and DX. Consider a case: Frontend App manages 1 million IPAccounts (users) for royalty-related licensing. For each IPAccount, it must request the user to sign (or call directly) to approve Transfer Module to transfer its RNFT, and then another tx to delegate Transfer Module to Frontend App. |
With this solution, we can rename the module to reflect better what it does. |
like this suggestion to reduce risk with simple solution |
Okay, pushing a commit to reflect changes in the discussions made above. We seem to be settled on our final decision @Spablob @LeoHChen @kingster-will @Ramarti We are still facing UX/DX issue of "every IPAccount needs to approve a unique 1155 token address for their RNFTs, if commercial." This is a business problem, not a technical one, but I predict this will make the life of external devs much worse when it comes to royalty (which is already quite a lot). |
Additionally, IPAssets (NFT + IPAccount) are much less programmable if there's only a withdrawal function for tokens. This should not be our solution for the post-beta decision, in my opinion. |
Agree with the short-term decision. It is the same as a SeaPort conduit, which also abstracts transfers based on the type of transfer being invoked. We could take more inspiration from them in the future. Longer term, however, I agree we should solve the UX problem of having to independently approve every new royalty NFT that is used by an IP account. |
MockTokenManagementModule tokenManagementModule = new MockTokenManagementModule( | ||
TokenWithdrawalModule tokenWithdrawalModule = new TokenWithdrawalModule( |
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.
We need to keep the MockTokenManagementModule
, the TokenWithdrawalModule` will be moved to the periphery repo. And we should cover such tests in core repo.
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.
LGTM.
Do we need to add the Modules into deployment scripts so that we can deploy the module with other components?
…toryprotocol#131) * feat: Token Management Module (Withdrawal) for token transfers on behalf of IPAccounts * feat: ERC Withdrawal module with restriction on receiver as IPA owner
Beta-release patch that allows IPAccounts to call some external ERC-20/721/1155 contracts to transfer out the tokens it received, e.g. from the Royalty Module.
Because #127 requires either the signer or to be a registered module, we must use a module to transfer tokens from IPAccount. Thus, we propose the Token Management Module.
Currently, there is a bug:
An IPAccount can delegate to a frontend contract (not a registered module) to transfer tokens on behalf of the IPAccount via the Token Management Module. This can be a Web2-native user who doesn't know how to transfer tokens, thus grants the Web2 app to move around tokens on blockchain.
The bug is that this frontend contract can transfer any tokens that are approved by the IPAccount for the Token Management Module. Let's go with an example:
In other words, there's no mechanism for the Token Management Module to granularly control which token a caller can move. If a caller is an IPAccount owner (crypto native), then it's fine. But if it's a frontend contract that is acting on behalf of an IPAccout (because the owner is lazy or not crypto-native), then it can get quite dangerous to due this catch-all permission for token transfers.
See test "test_TokenManagementModule_transferERC20_revert_malicious_anotherERC20Transfer", which doesn't actually revert as expected (so malicious frontend transfers both tokens).