Skip to content

Commit 196105e

Browse files
authored
feat(WalletLink): unset default wallet on removal of linked wallet (#4521)
### Description This PR modifies the wallet link removal behavior to automatically unset the default wallet when it's being removed, rather than preventing the removal. This improves user experience by allowing wallet removal operations to proceed without requiring a separate step to unset the default wallet first. ### Changes - Modified `WalletLinkBase.sol` to automatically unset the default wallet when it's being removed instead of reverting with `WalletLink__CannotRemoveDefaultWallet` - Added an event emission for `SetDefaultWallet` when the default wallet is automatically unset - Added test cases to verify the new behavior for both `removeLink` and `removeCallerLink` functions ### Checklist - [x] Tests added where required - [x] Documentation updated where applicable - [x] Changes adhere to the repository's contribution guidelines
1 parent 32382c7 commit 196105e

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

packages/contracts/src/factory/facets/wallet-link/WalletLinkBase.sol

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,10 @@ abstract contract WalletLinkBase is IWalletLinkBase, EIP712Base, Nonces {
209209
revert WalletLink__NotLinked(walletToRemove, rootWallet.addr);
210210
}
211211

212-
// Check that the wallet is not the default wallet
212+
// If the wallet is the default wallet, unset it before removal
213213
if (ds.rootWalletByRootKey[rootWallet.addr].defaultWallet == walletToRemove) {
214-
revert WalletLink__CannotRemoveDefaultWallet();
214+
ds.rootWalletByRootKey[rootWallet.addr].defaultWallet = address(0);
215+
emit SetDefaultWallet(rootWallet.addr, address(0));
215216
}
216217

217218
// Verify that the root wallet signature contains the correct nonce and the correct wallet
@@ -246,9 +247,10 @@ abstract contract WalletLinkBase is IWalletLinkBase, EIP712Base, Nonces {
246247
revert WalletLink__NotLinked(walletToRemove, rootWallet);
247248
}
248249

249-
// check that the default wallet is not the wallet to remove
250+
// If the wallet is the default wallet, unset it before removal
250251
if (ds.rootWalletByRootKey[rootWallet].defaultWallet == walletToRemove) {
251-
revert WalletLink__CannotRemoveDefaultWallet();
252+
ds.rootWalletByRootKey[rootWallet].defaultWallet = address(0);
253+
emit SetDefaultWallet(rootWallet, address(0));
252254
}
253255

254256
// Remove the link in the walletToRemove to root keys map

packages/contracts/test/factory/wallet-link/WalletLink.t.sol

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ contract WalletLinkTest is IWalletLinkBase, BaseSetup {
388388
vm.expectRevert(WalletLink__InvalidSignature.selector);
389389
walletLink.linkNonEVMWalletToRootKey(nonEVMWallet, 0);
390390
}
391+
391392
// =============================================================
392393
// linkCallerToRootKey
393394
// =============================================================
@@ -875,6 +876,33 @@ contract WalletLinkTest is IWalletLinkBase, BaseSetup {
875876
});
876877
}
877878

879+
function test_removeLinkUnsetsDefaultWallet() external givenWalletIsLinkedViaCaller {
880+
// Set wallet as default
881+
vm.prank(wallet.addr);
882+
walletLink.setDefaultWallet(wallet.addr);
883+
assertEq(walletLink.getDefaultWallet(rootWallet.addr), wallet.addr);
884+
885+
// Remove the wallet that is set as default
886+
uint256 nonce = walletLink.getLatestNonceForRootKey(rootWallet.addr);
887+
bytes memory signature = _signWalletLink(rootWallet.privateKey, wallet.addr, nonce);
888+
889+
vm.startPrank(smartAccount.addr);
890+
vm.expectEmit(address(walletLink));
891+
emit SetDefaultWallet(rootWallet.addr, address(0));
892+
vm.expectEmit(address(walletLink));
893+
emit RemoveLink(wallet.addr, smartAccount.addr);
894+
walletLink.removeLink({
895+
wallet: wallet.addr,
896+
rootWallet: LinkedWallet(rootWallet.addr, signature, LINKED_WALLET_MESSAGE),
897+
nonce: nonce
898+
});
899+
vm.stopPrank();
900+
901+
// Verify wallet is unlinked and default wallet is unset
902+
assertFalse(walletLink.checkIfLinked(rootWallet.addr, wallet.addr));
903+
assertEq(walletLink.getDefaultWallet(rootWallet.addr), address(0));
904+
}
905+
878906
// =============================================================
879907
// removeCallerLink
880908
// =============================================================
@@ -898,6 +926,27 @@ contract WalletLinkTest is IWalletLinkBase, BaseSetup {
898926
walletLink.removeCallerLink();
899927
}
900928

929+
function test_removeCallerLinkUnsetsDefaultWallet() external givenWalletIsLinkedViaCaller {
930+
// Set wallet as default
931+
vm.prank(wallet.addr);
932+
walletLink.setDefaultWallet(wallet.addr);
933+
assertEq(walletLink.getDefaultWallet(rootWallet.addr), wallet.addr);
934+
935+
// Remove the wallet that is set as default
936+
vm.startPrank(wallet.addr);
937+
vm.expectEmit(address(walletLink));
938+
emit SetDefaultWallet(rootWallet.addr, address(0));
939+
vm.expectEmit(address(walletLink));
940+
emit RemoveLink(wallet.addr, rootWallet.addr);
941+
walletLink.removeCallerLink();
942+
vm.stopPrank();
943+
944+
// Verify wallet is unlinked and default wallet is unset
945+
assertFalse(walletLink.checkIfLinked(rootWallet.addr, wallet.addr));
946+
assertEq(walletLink.getRootKeyForWallet(wallet.addr), address(0));
947+
assertEq(walletLink.getDefaultWallet(rootWallet.addr), address(0));
948+
}
949+
901950
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
902951
/* Metadata */
903952
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

0 commit comments

Comments
 (0)