Skip to content

Commit

Permalink
move content into contracts section + improve descriptions
Browse files Browse the repository at this point in the history
Co-authored-by: b00ste.lyx <[email protected]>
  • Loading branch information
CJ42 and b00ste committed Sep 21, 2023
1 parent cfaee9b commit a88bbe9
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 38 deletions.
25 changes: 23 additions & 2 deletions docs/contracts/overview/LSP17ContractExtension.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@ The list of extensions for specific functions are stored under the specific data

You can inherit the `LSP17Extendable.sol` contract to create an extendable contract.

### Checking for the existence of an extension
:::warning

TBD
Be aware that adding an extension that can `selfdestruct` itself can be dangerous. This can make the `LSP17Extendable` contract vulnerable to [metamorphic contracts](https://twitter.com/samczsun/status/1660012956632104960).

If this extension contract has been deployed at a pre-determined address with `CREATE2`, an attacker could `selfdestruct` it and deploy a new one with different runtime bytecode using `CREATE2` and the same salt and initialization code as on the first deployment.

This can result in the new contract to have the same address but different functionality. An attacker can now use these new functionalities to perform malicious actions.

:::

### Forwarding native tokens received to extensions

Expand All @@ -25,12 +31,27 @@ The `LSP17Extendable` contract implementation does not forward by default the na
If you want your extension to receive native tokens, by forwarding them to the extension contract (for instance, for extensions that require native tokens as part of their logic, or to make the extendable contract to fully work as a _"proxy forwarder contract"_), you can override the `_fallbackLSP17Extendable(...)` function.




## Extensions Contracts

Extension contracts are contracts deployed on the network that aim to be used for extending functionalities that use the LSP17 standard.

You can inherit the `LSP17Extension.sol` contract to create a contract extension.

:::warning

The extendable contract might forward the value that it received on extension call.

If the extension you are creating is not intended to receive value, make sure to revert by adding a simple check:

```solidity
if (msg.value == 0) revert(...)
```

**If your extension does not have a way to withdraw the native tokens, they will be stuck in the contract**.

:::

### Checking the amount of native tokens received by the extended contract

Expand Down
36 changes: 35 additions & 1 deletion docs/contracts/overview/UniversalProfile.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,39 @@ The magic value can also determine if there should be any post-execution check o

The structure allows the account to have a more dynamic and adaptable approach for managing function execution logic, using the **LSP20-CallVerification** standard.

## Extensions

An `LSP0ERC725Account` has the functionalities of `LSP17Extendable` built-in. This allows extending its behavior with functions it does not support natively in its interface.

However, calls to the `fallback` function will revert if no extension is registered for the function selector that was called.

:::tip

The only exception is the `0x00000000` function selector, which returns in order to allow the Universal Profile to act similarly to an EOA, and receive _"graffiti"_ data (when receiving native tokens or not) without executing anything else.

:::

:::caution

If your Universal Profile calls an extension to perform some security check, verification or validation, you should not rely on the extension to revert to ensure
the validation failed, but check the `bytes` returned by the extension through `_fallbackLSP17Extendable`.

:::

:::caution

Be aware of phantom functions for functions in extensions with the `0x00000000` selector.

For example, a contract might perform some kind of validation in an extension (_e.g: checking for permissions_), and expect the function to revert if the user is not authorized.

However, since the function's selector is `0x00000000` and the LSP0 account doesn't have this extension registered, the `fallback` function will `return` instead of reverting, giving the contract the impression that the user is authorized.

> See `_fallbackLSP17Extendable` for more details.
In such case, make sure to double that an extension is registered first for the `0x00000000` selector via `_getExtension`.

:::

## Adding metadata

Unlike private keys and EOAs that cannot hold any metadata, a UniversalProfile is a blockchain based account that can have any info attached to it.
Expand All @@ -42,4 +75,5 @@ You can do so using the `setData(bytes32,bytes)` and `setDataBatch(bytes32[],byt

### Updating your `LSP3Profile` metadata.

The [`LSP3Profile`](../../standards/universal-profile/lsp3-profile-metadata.md#lsp3profile) data key has a special meaning. It enables you to edit your profile details
The [`LSP3Profile`](../../standards/universal-profile/lsp3-profile-metadata.md#lsp3profile) data key has a special meaning. It enables you to edit your profile details

14 changes: 0 additions & 14 deletions docs/standards/generic-standards/lsp17-contract-extension.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,6 @@ This approach leads to fewer contracts being deployed on the blockchain with the

### Security Considerations

:::warning

If the extansion that you are creating is not supposed to receive value, make sure to revert when receiving value by adding a simple check, `msg.value == 0`. The extendable contract forwards the value that it receives on extansion call, if your extansion does not revert or does not have a way to withdraw the tokens, those tokens will be stuck in the contract.

:::

:::warning

Adding an extension with the ability to `selfdestruct` is dangerous as it opens the possibility of the `LSP17Extension` contract do deploy a contract with `CREATE2`, with a pre-determined address.
Further if you add it as an extension, the attacker can use `selfdestruct` and deploy a new one with different runtime bytecode using `CREATE2` and the same salt and initialization code as on the first deployment, resulting in the new contract to have the same contract but different functionality.
The attacker can now use this contract to perform malicious actions.

:::

As the extensions are called using the **CALL** opcode not **DELEGATECALL**, it' safe to assume that there is no risk of destroying the extendable smart contract through `selfdestruct`.

However, it is important to be aware that **adding random contracts as extensions carelessly** can be problematic as the extensions will have the extendable contract as their caller (`msg.sender`), which can lead to impersonating the extendable contract in certain situations.
Expand Down
7 changes: 0 additions & 7 deletions docs/standards/universal-profile/lsp0-erc725account.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,6 @@ Check the [**fallback function**](../../contracts/contracts/LSP0ERC725Account/LS

:::

:::warning

In the `LSP0ERC725Account` contract, calls to the fallback function revert if no matching function selector is found. However, the `0x00000000` function selector returns in order to allow the Unviersal Profile to act similarly to EOAs, you can send data to the Universal Profile without executing anything else.
If any security check involves calling an `LSP17Extension` do not rely on extensions to revert, but check its return value instead.

:::

Once a smart contract based account is deployed on the blockchain, it is not possible to modify the contract to add new native functions or change the behavior of existing ones. This can be a limitation for these accounts, that may need to support new use cases, functions, and standards that may be adopted in the future.

**[LSP17-ContractExtension](../generic-standards/lsp17-contract-extension.md)** defines a mechanism for extending a contract to support new standard and functions through the use of **extensions**.
Expand Down
28 changes: 14 additions & 14 deletions docs/standards/universal-profile/lsp6-key-manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,20 @@ Permissions for addresses are not stored on the Key Manager. Instead, they are *

## Permissions

:::warning
:::tip

While the Key Manager allows for a very fine-grained control over the Universal Profile by using the `CALL` permission combined with [`AllowedCalls`](#allowed-calls) or `SETDATA` permission combined with [`AllowedERC725YDataKeys`](#allowed-erc725y-data-keys), it also allows for a very coarse-grained control over the Universal Profile, due to the [`SUPER`](#super-permissions) permissions. This makes the Key Manager very flexible, but that flexibility comes with a slightly higher responsibility from the users.
You can use the [`encodePermissions(...)`](../../../../tools/erc725js/classes/ERC725#encodepermissions) and [`decodePermissions(...)`](../../../../tools/erc725js/classes/ERC725#decodepermissions) functions from the [_erc725.js_](../../../../tools/erc725js/getting-started) tool to easily **encode and decode permissions values** or **combine multiple permissions together**.

Good practices:
:::

1. Split the permissions over the Universal Profile accross different devices, hardware wallets or a combination of both.
2. Make sure to double or triple check when granting permissions to 3rd parties. (other Universal Profiles, DApps, etc.)
:::info Best Practices

:::
While the Key Manager allows for a very fine-grained control over the Universal Profile (_eg: `CALL` permission combined with [`AllowedCalls`](#allowed-calls), `SETDATA` permission combined with [`AllowedERC725YDataKeys`](#allowed-erc725y-data-keys)_), it also allows for a very coarse-grained control over the Universal Profile, due to the [`SUPER`](#super-permissions) permissions. This makes the Key Manager very flexible, but that flexibility comes with a slightly higher responsibility from the users.

:::tip
**Good practices:**

You can use the [`encodePermissions(...)`](../../../../tools/erc725js/classes/ERC725#encodepermissions) and [`decodePermissions(...)`](../../../../tools/erc725js/classes/ERC725#decodepermissions) functions from the [_erc725.js_](../../../../tools/erc725js/getting-started) tool to easily **encode and decode permissions values** or **combine multiple permissions together**.
1. Split the permissions over the Universal Profile accross different devices, hardware wallets or a combination of both.
2. Make sure to double or triple check when granting permissions to 3rd parties (other Universal Profiles, DApps, etc.).

:::

Expand Down Expand Up @@ -794,19 +794,19 @@ The main difference between direct vs relay vs LSP20-CallVerification execution

![Direct vs Relay Execution](/img/standards/lsp6/lsp6-direct-vs-relay-execution.jpeg)

### Relay Execution
### Gas-Less Transactions

:::warning
:::info Best Practices

While `executeRelayCall(..)` is a very conviniet way of using your Universal Profile to surf the blockchain, it comes with its risks.
While gas-less transactions / relay-execution is a very convenient way of using your Universal Profile to surf the blockchain, it comes with its risks.

- A relay call does not enfore a gas price to execute a transaction, meaning a Relay Service can potentially send your transaction with a lower gas price in order to cut costs which might take a long time to execute.
- A relay call does not enforce a gas price to execute a transaction, meaning a Relay Service can potentially send your transaction with a lower gas price in order to cut costs which might take a long time to execute.
- A Relay Service can also frontrun your transaction.

Best practices:
**Best practices:**

- Make sure to only use audited, transparent, community trusted Relay Services that have passed the test of time.
- Stay away from Relay Services that try to aquire users by offering cheapper prices. In the end any Relay Service must have a bussines model in order to work. If it does not profit from users it profits from other ways, might be shady or not.
- Stay away from Relay Services that try to acquire users by offering cheaper prices. In the end any Relay Service must have a business model in order to work. If it does not profit from users it profits from other ways, might be shady or not.

:::

Expand Down

0 comments on commit a88bbe9

Please sign in to comment.