-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
234 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,99 @@ | ||
# Spend Permissions | ||
|
||
Spend Permissions enable apps/third-party spenders to spend native tokens and ERC-20 tokens on behalf of users in a recurring way. | ||
This unlocks use cases that would otherwise be prohibited by the burden of requiring real-time signatures from users, such as frequent in-game spending, | ||
subscription payments, auto-renewals, asynchronous spends such as automated or event-based trading, and more. Designed to integrate with Coinbase Smart Wallet V1, | ||
a smart wallet adds the single `SpendPermissionManager` contract as an owner of their account, and can then use this gatekeeper to authorize third-party spenders | ||
to spend from their account within their specified parameters. In addition to the spender, spend permissions specify the start and end times that bound a | ||
permission’s validity, as well as an allowance and a recurring period duration, allowing the spender to spend up to this allowance per-period. Users can revoke | ||
existing permissions at any time. While authorized spending of ERC-20s has long been supported by allowance and permit mechanisms in token standards like ERC-20, | ||
the abstract flexibility provided by smart contract wallets enables unlimited creativity around the programmability of these wallets and other logic they may integrate with. | ||
Spend permissions are an early example of functionality that can be achieved within this new paradigm. | ||
Spend Permissions enable apps/third-party spenders to spend native tokens and ERC-20 tokens on behalf of users in a | ||
recurring way. This unlocks use cases that would otherwise be prohibited by the burden of requiring real-time signatures | ||
from users, such as | ||
- frequent in-game spending | ||
- subscription payments | ||
- auto-renewals | ||
- automated or event-based trading | ||
- micropayment streaming | ||
|
||
## What is a spendpermission / what is it parameterized by? | ||
Designed to integrate with Coinbase Smart Wallet V1, a smart wallet adds the | ||
single `SpendPermissionManager` contract as an owner of their account, and can then use this gatekeeper to authorize | ||
third-party spenders to spend from their account within their specified parameters. In addition to the spender, | ||
spend permissions specify the start and end times that bound a permission’s validity, as well as an allowance and a | ||
recurring period duration, allowing the spender to spend up to this allowance per-period. Users can revoke existing | ||
permissions at any time. | ||
|
||
## How to approve? + batching | ||
While authorized spending of ERC-20s has long been supported by allowance and permit mechanisms | ||
in token standards like ERC-20, the arbitrary programmability of smart contract wallets unlocks a vast design space for implementing | ||
controls like spend permissions in a per-wallet way. Spend permissions are an early example of functionality that can be achieved | ||
within this new paradigm. | ||
|
||
## How to revoke? | ||
## The `SpendPermission` details | ||
A spend permission is defined by the following parameters | ||
|
||
```solidity | ||
/// @notice A spend permission for an external entity to be able to spend an account's tokens. | ||
struct SpendPermission { | ||
/// @dev Smart account this spend permission is valid for. | ||
address account; | ||
/// @dev Entity that can spend `account`'s tokens. | ||
address spender; | ||
/// @dev Token address (ERC-7528 native token address or ERC-20 contract). | ||
address token; | ||
/// @dev Maximum allowed value to spend within each `period`. | ||
uint160 allowance; | ||
/// @dev Time duration for resetting used `allowance` on a recurring basis (seconds). | ||
uint48 period; | ||
/// @dev Timestamp this spend permission is valid after (unix seconds). | ||
uint48 start; | ||
/// @dev Timestamp this spend permission is valid until (unix seconds). | ||
uint48 end; | ||
/// @dev An arbitrary salt to differentiate unique spend permissions with otherwise identical data. | ||
uint256 salt; | ||
/// @dev Arbitrary data to include in the signature. | ||
bytes extraData; | ||
} | ||
``` | ||
|
||
|
||
## Approving | ||
|
||
Spend permissions can be approved in two ways. The user can call `approve` directly with the details | ||
of a spend permission to establish an approval for a spender. Alternatively, the user can sign the hash | ||
of a spend permission and anyone can submit that signature and the details of the spend permission to | ||
`approveWithSignature` (or `approveBatchWithSignature` in the case of a batch signature) to authorize | ||
the approval. | ||
|
||
|
||
## Revoking | ||
|
||
Users can revoke permissions at any time by calling `SpendPermissionManager.revoke`, which can also be batched via | ||
`CoinbaseSmartWallet.executeBatch`. Once a spend permission has been revoked, it can never be re-approved. | ||
|
||
If the user wants to re-authorize the spend permission, the spender will need to generate a new spend permission | ||
that has a unique hash from the original spend permission. If the details of the new spend permission are identical | ||
to the revoked permission, the `salt` field of the permission should be used to generate a unique has. | ||
|
||
## Cycle accounting | ||
|
||
--> Known accounting issue with the non-reverting ERC20s | ||
Spend permissions allow an app to request to spend user assets on a recurring basis (e.g. 10 USDC / month). | ||
As apps spend user assets, the `SpendPermissionManager` contract tracks cumulative spend and enforces the allowance for the | ||
current period. Once enough time passes to enter the next period, the allowance usage is reset to zero and | ||
the app can keep spending up to the same allowance. | ||
|
||
This behavior is parameterized by the following properties of a spend permission: | ||
|
||
`start`: time this permission is valid starting at (unix time, seconds) | ||
`end`: time this permission is valid until (unix time, seconds) | ||
`period`: duration of a recurring interval that resets the spender's allowance (seconds) | ||
`allowance`: amount of tokens spendable per period | ||
|
||
Note that spend permissions can be used for one-time allowances, either time-bounded or indefinite, by setting | ||
a period durantion that spans the entire range between start and end. | ||
|
||
A comprehensive example of spend permission accounting can be found [here](https://github.com/coinbase/spend-permissions/blob/main/docs/SpendPermissionAccounting.md). | ||
|
||
## Additional documentation | ||
Contract sourcecode, diagrams, and additional documentation can be found in the open-source [contracts repository](https://github.com/coinbase/spend-permissions). | ||
|
||
## Known issues | ||
ERC20s w non-reverting transfers will lead to inconsistent spend state | ||
Duplicate spend permissions can be approved (and regardless of revocation status) | ||
Unlimited batch size | ||
|
||
## ERC6492 and general notes on SCW signature validation (link to other sig validation docs?) | ||
## Misc | ||
ERC6492 Signatures are supported | ||
|
||
Maybe leave this out entirely unless we find we're getting a lot of questions about it |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters