πLedger
Asset Rights Decoupling for Virtualized Wallets
Design Ethos
Having an extensible asset storage interface drives some important goals:
Decouple storage from Rights. The on-chain storage location shouldn't have to care about the internal logic of sub-account distribution. Decoupling these concerns enables other programs to move assets between keys for various reasons without requiring the collateral provider's involvement.
Asset and Use Case Diversity. Support different types of assets, storage, and yield schemes. Specialty NFT vaults, staking providers, exchanges, and bridges can all provide collateral management equally.
Unified Management. View and manage sub-account access, recover locked up assets, and transfer rights for all of your funds, wherever they are stored to anyone within your trust with a key. If there was a RocketPool provider, a loved one recovering the wallet after a death could locate the staked ETH easily within the wallet.
Ledger and Collateral Relationship
To do this we must separate the Collateral Provider asset storage from the ledgered account. A trusted relationship between the ICollateralProvider and theLedger is managed by the Notary. The notary respects the root key holder and only enables the Collateral Provider to deposit funds for a proper key, or withdrawal from a key if the key-holder has allowed it.
A couple of trust assumptions are being made in this established relationship:
The collateral provider trusts, verifies, and obeys the key allocation on the associated ledger.
The root key holder trusts the collateral provider to faithfully service deposits and withdrawals.
By default, a Locksmith wallet comes with trusted relationships established with both the EtherVault and TokenVault. These contracts are simple asset storage vaults that service key deposits and withdrawals against the ledger.
Asset Identity Protocol
Since the Ledger is not actually holding the assets, it identifies the assets with what is called an Asset Resource Name (ARN). It is defined as such:
struct AssetType {
// all EVM tokens originate from a contract, gas is zero.
address contractAddress;
// identifies the token standard for this asset
// '0' is considered the native gas token,
// or is otherwise considered 20, 721, 777, 1155, etc.
uint256 tokenStandard;
// for token types that have a non-fungible ID, this
// field is used to denote that type of asset.
uint256 id;
}A short form ARN can be derived out of a simple hash scheme to guarantee uniqueness and identifiability. It is represented as a bytes32.
The assets are tracked in a three-tiered Ledger object that keeps an account of key access rights for each asset actively stored for each collateral provider. The ledger balances are tracked, reconciled, and aggregated for each asset across each key, wallet, and Ledger during each entry. In this way, proof of solvency can be proven when the transaction is successfully added to a block.

The three-tiered structure provides the following immediate transaction guarantees:
The Ledger verifies the collateral on the ledger is solvent for the provider, wallet owner, and key holder.
The collateral provider has verified the ledger's account balance to satisfy it's ledger obligations.
Moving funds within a wallet does not change collateral obligations for any provider.
Storage
The storage for the ledger is condensed into the three tiered objects that all store the same data structure, a CollateralProviderContext.
notary
The Ledger is deloyed with the contract address of the Notary. This cannot be changed. Each operation that mutates the Ledger's balances in any way must be approved by the notary.
CollateralProviderContext
The following data structure describes each context.
ledgerContext
This context keeps track of the each per-asset obligation on each collateral provider for the entire ledger across all accounts. Both the Ledger and Collateral Provider check this resulting balance during a deposit or withdrawal to verify accurate books and revert with solvency isn't met.
trustContext
The trust model context keeps a tabulation of wallet-level balances per provider and asset summed across all keys in the collection. The ledger context should always be equal to or bigger than all wallet balances summed together.
keyContext
The key context keeps track of the balance rights for a specific key ID on a per asset and collateral provider basis. The summation of all keys rights within a wallet's collection should equal exactly the wallet's balance for each asset.
Operations
There are a fair mix of introspection operations on top of the core ledger mutations. These include getContextArnRegistry(), getContextProviderRegistry(), getContextArnBalances(), getContextBalanceSheet(), and getContextArnAllocations().Each of these take a context level (0, 1, 2), and provide back ledger, wallet, or key level assets, providers, and balances in various forms.
deposit
A collateral provider will call deposit when funds are deposited into a wallet owner's key account, either by a key-holder themselves in a vault-like situation, or as part of the operating agreement between the provider and the wallet owner (for instance, as part of a yield construct).
All deposits for a given trust model must be approved by the Ledger's Notary. This ultimately means that the root key holder trusts the provider to store collateral.
The returned vector can be used for inspection and reversion by the collateral provider for solvency guarantees.
The deposit method on the context objects are library functions on the struct:
withdrawal
Similarly, when a collateral provider is servicing a withdrawal and wants to register the removal of funds with the ledger they call withdrawal. The notary must approve the withdrawal, which requires that the provider is trusted and that the key holder rights in question previously attested to this withdrawal amount.
And similarly, the library function:
distribute
Scribes call distribute when they want to re-arrange key rights for existing assets on the ledger. In this way, distributions are not withdrawals. Distributions must be notarized, which requires that the scribe is trusted by the root key holder, and that the distribution keys all belong to the same trust model.
Note that the distribution API takes a provider. Assets can only be atomically re-distributed inside of a given collateral provider. Moving collateral between providers requires a full withdrawal and a deposit at the new custody location. This use can be supported in a single transaction through a VirtualKeyAddress agent multi-call.
Last updated