Security Model for Depositors / Point Sellers
As a point seller, how do I know that my principal assets, the funds I deposit into my Rumpel wallet, are safe? This page provides the answer.
Last updated
Was this helpful?
As a point seller, how do I know that my principal assets, the funds I deposit into my Rumpel wallet, are safe? This page provides the answer.
Last updated
Was this helpful?
Rumpel Wallet is built on top of . Each user wallet is simply a standard Safe with a special Rumpel and Rumpel added on. Therefore, our approach to security is largely inherited from Safe, and to understand the scope of an admin’s power, you need only look at these two main added components.
– restricts Rumpel user actions to specific calls added onto the allowlist
– enables the admin to make calls on a user's behalf, unless the calls are on the blocklist
are claims on future reward tokens, so when the reward tokens are released, the admin must be able to sweep them from user wallets into the Point Token Vault for pToken redemption. If a user were to withdraw the rewards first, pTokens would go unbacked.
However, there are many assets that we can be confident will never be reward tokens, and therefore, we can permanently enable many actions for users, and disable them for admins. Our contracts are designed with this in mind.
The module blocklist and the guard allowlist block and allow calls. Calls are specific function selectors at specific addresses such as USDC.transfer
or RSUSDE.deposit
. While users are the only owners of their 1-of-1 Safe, the Guard allowlist blocks all calls by default, preventing users from making any malicious contract calls. Therefore, only “allowed” calls can be executed by the user.
When a call is added to the module blocklist, an admin can no longer make it on behalf of the user’s Safe. This list is one-way/immutable, meaning once a call is added, it cannot be removed.
🔒 During deployment, enableModule
and disableModule
are added to the blocklist (, ), so admins are prevented from changing the module itself to get around the blocklist.
When a call is added to the guard allowlist, users are able to make that call via their Safe. An admin can add and remove these allowed calls, except if they’re set to PERMANENTLY_ON
, in which case an admin can no longer remove them.
To put it simply, in the case of assets:
Blocklist: If an asset is on the blocklist, the admin cannot withdraw it from users
Allowlist: If an asset is on the allowlist, users can withdraw the asset
Permanent Allowlist: When active for an asset, an admin cannot remove it from the allowlist
As defined above, there are three possible actions an admin can take:
add a call to the guard allowlist as ON
and add a call to the allowlist as PERMANENTLY_ON
add a call to the module blocklist
Add a call to the guard allowlist as ON
This first log shows a call added to the guard allowlist with a list state of 1
, corresponding to ON
. The target is WBTC and the function selector is transfer(address,uint256)
, so this action adds WBTC.transfer
to the allowlist – but an admin has the ability to remove it in the future.
Add a call to the module blocklist
This last one shows a call added to the module blocklist. The target is RE7LRT and the function selector is approve(address,uint256)
, so the action adds RE7LRT.approve
to the blocklist. Per the list’s design, an admin cannot remove it, so an admin will never be able to make that call on behalf of a user.
As a result of these 3 changes:
Users can transfer WBTC
from their Safe
Users can transfer RE7LRT
from their Safe, and an admin can never disallow it
An admin can never give another address approvals on the RE7LRT
in a user’s Safe
The blocklist & allowlist can easily be verified using events. Here is a Python script that does so:
is a recent batch transaction where each of the three state transitions takes place. Let’s examine it by going through the logs.
Add a call to the guard allowlist as PERMANENTLY_ON
This next one shows a call added to the guard allowlist with a list state of 2
, corresponding to PERMANENTLY_ON
. The target is and the function selector is transfer(address,uint256)
, so this action adds RE7LRT.transfer
to the allowlist – and an admin has no way of removing it.
The Rumpel Wallet contracts have been to verify that they behave as outlined above.
We also maintain an ongoing .