First, you must know: if your users are doing things they weren’t supposed to do in your app, it’s mostly your fault.
This space is new and vulnerabilities and hacks are bound to be present. And while I truly believe that, it still has some tech and design best practices to prevent bad stuff from happening.
Let us talk about the mitigation part on the design side.
The biggest security problem is a design problem
There’s a saying around the security circle that the human element is the weakest link to cybersecurity. Lessen the probability that your user will eff up, and you are far ahead on the security scale.
Everything that has to do with signing a transaction, you must show and inform the user about.
Simulating transactions is one way to provide transparency. It lets your users know they’re not gonna get mugged. Rabby does a good job at it:
Showing what the transaction does and who they’re signing to gives your user the ability to identify any issues beforehand.
Transaction details that you can flash and might be important to your user:
Estimated value that is going out their wallet (in USD)
The contract they’re interacting with
Which contract is it
Through which platform
Gas costs (in USD)
Estimated value that will be left on the wallet after transacting
This gives them better heuristics on whether the transaction is ‘safe’ to sign or not.
And if something is unverifiable…
1. Show warnings for critical actions
Is it a contract they never interacted with before? Give a warning message.
Is the call message a non-readable hash that could mean anything? Provide a warning. Better yet, use EIP-712.
Are they doing anything that could harm them or the system? Flash a warning and provide a ‘back to safety’ button or a waiver with confirmation.
Many hacks and fat finger errors could have been prevented by gating critical actions with a warning message.
2. Give feedback as users are filling out form fields
Soft nudges through microcopy are great. They guide your user to the ideal flow without them having to explore and find dead ends.
When your user has entered a value in a deposit amount field, remind them that they need to leave some leeway for transaction fees. If not, then warn them so they can change it.
When they are typing an unexpected value in a field where you need a recipient wallet address, return an error feedback through microcopy instantaneously.
When a transaction is likely to fail with the values they entered, it is possible to warn them before they sign the transaction.
I have a huge pet peeve for protocols that show users how to deposit to them without providing an accessible way to bridge out or withdraw. This is UX from hell, intentionally made to trap users within the protocol. That, or the product was not well thought out.
If the funds will have to stay within the protocol for whatever reason, at least warn the users that the action will be hard to reverse.
For instance, if your vault has a locking period, you have to display a modal to make them confirm that their deposits cannot be withdrawn until a certain date.
Eigenlayer did great at informing the user of the 7-day waiting period that makes their funds secure. We can take this up a notch by writing the earliest date of withdrawal so that the user wouldn’t need to mentally compute for the date (avoiding cognitive overload).
A copy can also be placed on the restaking screen that the tokens will not be withdrawable until 7 days after unstaking. It may look like adding friction to the process but actually it fosters a sense of confidence and freedom that users are able to make informed decisions on how to time their strategies.
In many of the practices mentioned in this post, you will need to understand existing tools like EIP-712 to prevent blind signing, Tenderly for simulating transactions, Blocknative for showing tx statuses, and etc. Some are as simple as adding microcopy and modals or attaching onchange to input fields. But the catch is if you’re a designer, you need the help of your devs, and if you’re a dev, you need to check out a few tools. It’s some effort, but if you compare it to the amount of hacks and human errors that they could have prevented, it’s well worth it.