Dharma smart wallet used contract permissions that governed access after its app closed
Dharma smart wallet used contract authorization that determined access to funds after the retirement of its consumer app. The app closed in 2022 after OpenSea acquired Dharma Labs. A saved address identifies the contract, while moving assets requires the authority that its deployed code accepts. Ordinary withdrawals required shared approval; a registered escape account provided a separate path for supported balances. The Adharma contingency design changed authorization again, if the relevant implementation was active. An old login, a replacement wallet app or a visible token balance does not by itself establish spending access. The missing prerequisite may be control of an authorized key.
Last updated:
Bottom line: Dharma's V7 escape function could skip failed transfers, so recipient balances determined which assets had actually arrived.
Shared approval and emergency access had different prerequisites
Ordinary approval, a registered escape account and Adharma contingency access depended on different permissions in the wallet contracts. Shared approval needed the user authority and the Dharma authority. Escape access required a registered account whose controller could still authorize its calls. Contingency access required the applicable Adharma implementation to be active. These paths offered different ways to authorize calls, with one common constraint: the caller had to satisfy the contract's rules. Replacing the interface did not supply missing authority.
What must a replacement interface support to access Dharma funds?
A replacement interface must support the deployed contract's functions and authorization format, with control of an accepted signer. A contract address identifies an account controlled by code. It does not have an associated private key that another app can import to take ownership.
For ordinary wallet actions, compatible software needed to construct the required contract call and obtain its authorizations. Dharma's relaying arrangement separated signing from transaction submission. A different sender could pay for a transaction without gaining permission to spend the wallet's assets.
The V1 Key Ring used the legacy isValidSignature(bytes,bytes) interface for contract signature validation. The finalized ERC-1271 standard uses isValidSignature(bytes32,bytes). Their argument layouts and expected return values differ. Software must match the actual implementation; a general claim of smart wallet support does not establish compatibility.
Software that supported only direct signing from a private-key account could inspect a contract address without constructing its protected withdrawal calls. Read access, signature validation and transaction submission therefore answered different questions about compatibility. None established that the recipient had received funds.
Additional device keys depended on existing authorization
Adding a device to the V1 Dharma Key Ring required a signature from an existing registered key. The contract added a new Dual key with both admin and standard permissions. It kept the approval threshold at one registered key. This supplied another authorized device without changing ordinary wallet approval requirements. V1 could add keys but could not remove them. Adding a replacement therefore did not revoke an older device's authority. The key ring address and the device signing address also identified different accounts. Knowing the ring's address could help inspect membership, but it could not recreate a lost device key.
Contract settings that shaped backup and access
The published implementations placed these limits on device replacement and emergency access. Their version labels matter because upgrades could change the logic.
| Contract setting | Implementation value | Consequence for access |
|---|---|---|
| Ordinary withdrawal approval | User authority and Dharma authority, 2/2 | Another device did not remove shared approval |
| V1 Key Ring threshold | One registered key | A registered replacement could supply the user signature |
| V1 key permissions | Dual: admin and standard | An added key could authorize actions and further additions |
| V1 key removal | Unsupported | Adding a device did not revoke an older key |
| Escape-hatch registration | Optional per-wallet account | The configured account had to authorize escape access |
| Escape-hatch disablement | Irreversible registry flag | Disablement removed any registered escape account and permanently prevented further registration |
| Adharma wallet authority | Escape account, otherwise stored user authority | A Key Ring authority needed its own authorized caller |
A backup device only helped when its key belonged to the relevant authorization structure. A separate escape account served a different purpose. Neither its presence nor its permissions followed from the app login.
Adharma contingency changed who could make calls
The Adharma wallet implementation gave calling authority to the registered escape account, or otherwise to the stored user authority. That rule differed from ordinary shared approval. Access under contingency therefore depended on which account the wallet recognized.
When the stored authority was a Key Ring, the contingency Key Ring allowed an Admin or Dual key to call takeAction. That contract could then invoke the wallet's performCall. A device key and the wallet's immediate caller were distinct participants.
The published manager allowed non-owners to arm and activate contingency after more than 90 days without a heartbeat. Activation required the manager to retain ownership of both upgrade beacon controllers. Elapsed time alone did not execute the upgrade.
Later upgrades or rollbacks could replace the contingency implementations. The app's closure did not establish that every wallet had entered this state. A deployed contingency contract could exist without the wallet or Key Ring using its code.
Could account recovery restore access without a device key?
A recovery manager could replace a lost user signing authority only when its permissions, timelock and account settings allowed recovery. This route required an authorized operation through the manager. Email credentials alone did not authorize the contract change. Permanent recovery opt-out excluded that mechanism. After the app retired, the historical recovery feature did not establish an available operator.
The V7 escape function covered specified balances
The V7 escape function attempted redemption and transfer for specified assets, including Dharma's legacy savings tokens. It attempted to redeem dDAI and dUSDC, then transfer supported underlying and residual token balances to the registered escape account. This scope did not establish a sweep function for every arbitrary token or collectible. A failed component could leave assets behind while the remaining escape operation continued. The Escaped event alone therefore did not prove that every balance had moved. Remaining balances and the destination's receipts mattered individually. This limitation affected access to existing savings positions without changing their underlying lending mechanics.
Gas funding and asset receipt remained separate requirements
Direct contract transactions required network fees even though Dharma historically subsidized relayed wallet actions. The account submitting a transaction needed the network's fee-paying asset. A balance inside the smart wallet did not automatically fund that sender. Read-only contract queries did not require a broadcast transaction, so inspecting permissions did not itself move funds or incur an on-chain transaction fee.
A transaction identifier recorded an attempt; inclusion and execution established later states. For an asset transfer, completion meant that the intended recipient actually received the relevant asset. Remaining balances required separate interpretation when a function tolerated partial failures. If no authorized caller or applicable recovery path is available, displaying the wallet address leaves its funds unmoved.
Dharma smart wallet questions, answered
Can a new deposit reactivate the retired Dharma app?
A new deposit cannot reactivate the retired app or create missing spending authority. Receiving funds changes the balance, while the contract's permissions govern outgoing calls. Depositing into an inaccessible wallet can increase the funds that you cannot move. Gas funding for a transaction sender serves a separate purpose.
How private is an address-only check of a legacy Dharma wallet?
An address-only check does not require disclosure of a device's private key. Public blockchain records allow inspection of balances and transactions associated with the address. Sharing that address can expose the account's financial history to the recipient. It identifies the account, so treat it as public account information rather than a secret recovery credential.
Which address belongs in a Dharma escape-hatch registry query?
The query needs the smart wallet address whose escape configuration you want to inspect. The registry provided getEscapeHatchForSmartWallet with a wallet-address argument. Its argument-free getEscapeHatch function returned the calling account's configuration instead. The Key Ring address, a device address and the smart wallet address identified different accounts; substituting one could inspect the wrong registry entry.
Does the Ethereum wallet design establish identical access on another network?
An Ethereum implementation does not establish another network's contract permissions. Separate networks maintain separate balances, transaction histories and contract state. Even matching address text does not demonstrate matching deployed code or escape configuration. Access to a legacy balance requires the permissions and implementation on the network where that balance exists.
Are old Dharma withdrawal signatures usable after the wallet state changes?
An old signature remains usable only if it matches the action that the contract currently accepts. V7 bound the signed action to the wallet address, implementation version, signing authorities, nonce, gas requirement and action arguments. A changed nonce or authority could invalidate an earlier authorization. A stored signature did not provide unrestricted permission for later withdrawals.
Why could a direct-token balance show zero while Dharma savings assets remained?
A direct underlying-token balance did not include tokens representing a savings position. V7's getBalances distinguished directly held Dai and USDC from underlying balances represented by dDAI and dUSDC. Inspecting only the underlying token could miss a legacy position that a supported withdrawal or escape call could attempt to redeem.