Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: mark relay call signature as used #670

Closed
wants to merge 1 commit into from
Closed

Conversation

b00ste
Copy link
Member

@b00ste b00ste commented Aug 9, 2023

What does this PR introduce?

♻️ Refactor

After investigating the way signatures are stored in Safe.sol, it turns out that they have a signMessage(...) function which marks a signature as approved signature. That further is checked in isValidSignature(...) which requires that a signature to be approved.

With this said, they don't quite have the same purpose as in our case. We need to store signatures in order to not allow double use while they store signatures that are approved. In our case we cannot use signMessage(...) as it will block gas-less execution and will require for someone to have gas in order to approve a signature. We need an approach that does not break the ux behind relay calls.

I took the liberty to implement it in the following way:

  • Before executing a relay call, we check that the signature is marked as unused (0) in the signedMessages mapping.
  • After executing a relay call successfully we mark the signature as used (1) in the signedMessages mapping.

That would 100% not allow any signature to be used twice.

PR Checklist

  • Wrote Tests
  • Wrote & Generated Documentation (readme/natspec/dodoc)
  • Ran npm run lint && npm run lint:solidity (solhint)
  • Ran npm run format (prettier)
  • Ran npm run build
  • Ran npm run test

@Hugoo
Copy link
Contributor

Hugoo commented Aug 9, 2023

@b00ste b00ste changed the title refactor: save used relay call signature refactor: mark relay call signature as used Aug 9, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Aug 9, 2023

👋 Hello
⛽ I am the Gas Bot Reporter. I keep track of the gas costs of common interactions using Universal Profiles 🆙 !
📊 Here is a summary of the gas cost with the code introduced by this PR.

⛽📊 See Gas Benchmark report of Using UniversalProfile owned by an EOA

🔀 execute scenarios

execute scenarios - 👑 UP Owner ⛽ Gas Usage
Transfer 1 LYX to an EOA without data 37537
Transfer 1 LYX to a UP without data 36639
Transfer 1 LYX to an EOA with 256 bytes of data 42198
Transfer 1 LYX to a UP with 256 bytes of data 44738
Transfer 0.1 LYX to 3x EOA without data 70862
Transfer 0.1 LYX to 3x UP without data 75680
Transfer 0.1 LYX to 3x EOA with 256 bytes of data 84826
Transfer 0.1 LYX to 3x EOA with 256 bytes of data 100006

🗄️ setData scenarios

setData scenarios - 👑 UP Owner ⛽ Gas Usage
Set a 20 bytes long value 49971
Set a 60 bytes long value 95293
Set a 160 bytes long value 164453
Set a 300 bytes long value 279700
Set a 600 bytes long value 484124
Change the value of a data key already set 32859
Remove the value of a data key already set 27333
Set 2 data keys of 20 bytes long value 78428
Set 2 data keys of 100 bytes long value 260592
Set 3 data keys of 20 bytes long value 105145
Change the value of three data keys already set of 20 bytes long value 45445
Remove the value of three data keys already set 41339

🗄️ Tokens scenarios

Tokens scenarios - 👑 UP Owner ⛽ Gas Usage
Minting a LSP7Token to a UP (No Delegate) from an EOA 91241
Minting a LSP7Token to an EOA from an EOA 59206
Transferring an LSP7Token from a UP to another UP (No Delegate) 98689
Minting a LSP8Token to a UP (No Delegate) from an EOA 158192
Minting a LSP8Token to an EOA from an EOA 126157
Transferring an LSP8Token from a UP to another UP (No Delegate) 147236

📝 Notes

  • The execute and setData scenarios are executed on a fresh UniversalProfile smart contract, deployed as standard contracts (not as proxy behind a base contract implementation).
⛽📊 See Gas Benchmark report of Using UniversalProfile owned by an LSP6KeyManager

This document contains the gas usage for common interactions and scenarios when using UniversalProfile smart contracts.

🔀 execute scenarios

👑 unrestricted controller

execute scenarios - 👑 main controller ⛽ Gas Usage
transfer LYX to an EOA 60395
transfer LYX to a UP 61997
transfer tokens (LSP7) to an EOA (no data) 107118
transfer tokens (LSP7) to a UP (no data) 242646
transfer a NFT (LSP8) to a EOA (no data) 170965
transfer a NFT (LSP8) to a UP (no data) 289821

🛃 restricted controller

execute scenarios - 🛃 restricted controller ⛽ Gas Usage
transfer some LYXes to an EOA - restricted to 1 x allowed address only (TRANSFERVALUE + 1x AllowedCalls) 72604
transfers some tokens (LSP7) to an EOA - restricted to LSP7 + 2x allowed contracts only (CALL + 2x AllowedCalls) (no data) 122897
transfers some tokens (LSP7) to an other UP - restricted to LSP7 + 2x allowed contracts only (CALL + 2x AllowedCalls) (no data) 258425
transfers a NFT (LSP8) to an EOA - restricted to LSP8 + 2x allowed contracts only (CALL + 2x AllowedCalls) (no data) 186732
transfers a NFT (LSP8) to an other UP - restricted to LSP8 + 2x allowed contracts only (CALL + 2x AllowedCalls) (no data) 305588

🗄️ setData scenarios

👑 unrestricted controller

setData scenarios - 👑 main controller ⛽ Gas Usage
updates profile details (LSP3Profile metadata) 136831
give permissions to a controller (AddressPermissions[] + AddressPermissions[index] + AddressPermissions:Permissions:) 132862
restrict a controller to some specific ERC725Y Data Keys 139238
restrict a controller to interact only with 3x specific addresses 161942
remove a controller (its permissions + its address from the AddressPermissions[] array) 67827
write 5x LSP12 Issued Assets 233209

🛃 restricted controller

setData scenarios - 🛃 restricted controller ⛽ Gas Usage
setData(bytes32,bytes) -> updates 1x data key 102582
setData(bytes32[],bytes[]) -> updates 3x data keys (first x3) 161396
setData(bytes32[],bytes[]) -> updates 3x data keys (middle x3) 145475
setData(bytes32[],bytes[]) -> updates 3x data keys (last x3) 170708
setData(bytes32[],bytes[]) -> updates 2x data keys + add 3x new controllers (including setting the array length + indexes under AddressPermissions[index]) 249828

📝 Notes

  • The execute and setData scenarios are executed on a fresh UniversalProfile and LSP6KeyManager smart contracts, deployed as standard contracts (not as proxy behind a base contract implementation).

@github-actions
Copy link
Contributor

github-actions bot commented Aug 9, 2023

Changes to gas cost

Generated at commit: c13aa98d867456fc690ab0d6115ebed16e7eed7e, compared to commit: 9db488aad9065f88cfc3c5f43f47b1fab35fc5f0

🧾 Summary (10% most significant diffs)

Contract Method Avg (+/-) %
LSP6ExecuteRestrictedController lsp20VerifyCall
transferLYXToUP
transferTokensToRandomEOA
+22 ❌
-67 ✅
-66 ✅
+0.13%
-0.21%
-0.09%
LSP6ExecuteUnrestrictedController lsp20VerifyCall
transferLYXToUP
transferTokensToRandomEOA
+22 ❌
-67 ✅
-66 ✅
+0.13%
-0.20%
-0.09%
LSP6SetDataRestrictedController restrictControllerToERC725YKeys +45 ❌ +0.03%

Full diff report 👇
Contract Deployment Cost (+/-) Method Min (+/-) % Avg (+/-) % Median (+/-) % Max (+/-) % # Calls (+/-)
LSP6ExecuteRestrictedController 2,923,945 (+69,885) lsp20VerifyCall
transferLYXToUP
transferNFTToRandomEOA
transferNFTToRandomUP
transferTokensToRandomEOA
transferTokensToRandomUP
14,921 (+22)
31,398 (-67)
130,899 (+35)
238,748 (+36)
77,025 (-66)
211,723 (+44)
+0.15%
-0.21%
+0.03%
+0.02%
-0.09%
+0.02%
17,057 (+22)
31,398 (-67)
130,899 (+35)
238,748 (+36)
77,025 (-66)
211,723 (+44)
+0.13%
-0.21%
+0.03%
+0.02%
-0.09%
+0.02%
17,770 (+22)
31,398 (-67)
130,899 (+35)
238,748 (+36)
77,025 (-66)
211,723 (+44)
+0.12%
-0.21%
+0.03%
+0.02%
-0.09%
+0.02%
17,770 (+22)
31,398 (-67)
130,899 (+35)
238,748 (+36)
77,025 (-66)
211,723 (+44)
+0.12%
-0.21%
+0.03%
+0.02%
-0.09%
+0.02%
8 (0)
1 (0)
1 (0)
1 (0)
1 (0)
1 (0)
LSP6ExecuteUnrestrictedController 2,923,945 (+69,885) lsp20VerifyCall
transferLYXToUP
transferNFTToRandomEOA
transferNFTToRandomUP
transferTokensToRandomEOA
transferTokensToRandomUP
14,921 (+22)
33,398 (-67)
128,736 (+36)
236,584 (+35)
74,321 (-66)
209,019 (+44)
+0.15%
-0.20%
+0.03%
+0.01%
-0.09%
+0.02%
17,057 (+22)
33,398 (-67)
128,736 (+36)
236,584 (+35)
74,321 (-66)
209,019 (+44)
+0.13%
-0.20%
+0.03%
+0.01%
-0.09%
+0.02%
17,770 (+22)
33,398 (-67)
128,736 (+36)
236,584 (+35)
74,321 (-66)
209,019 (+44)
+0.12%
-0.20%
+0.03%
+0.01%
-0.09%
+0.02%
17,770 (+22)
33,398 (-67)
128,736 (+36)
236,584 (+35)
74,321 (-66)
209,019 (+44)
+0.12%
-0.20%
+0.03%
+0.01%
-0.09%
+0.02%
8 (0)
1 (0)
1 (0)
1 (0)
1 (0)
1 (0)
LSP6SetDataRestrictedController 2,911,930 (+73,085) givePermissionsToController
restrictControllerToERC725YKeys
120,505 (-22)
138,874 (+45)
-0.02%
+0.03%
120,505 (-22)
138,874 (+45)
-0.02%
+0.03%
120,505 (-22)
138,874 (+45)
-0.02%
+0.03%
120,505 (-22)
138,874 (+45)
-0.02%
+0.03%
1 (0)
1 (0)
LSP6SetDataUnrestrictedController 2,911,930 (+73,085) givePermissionsToController
restrictControllerToERC725YKeys
126,505 (-22)
147,374 (+45)
-0.02%
+0.03%
126,505 (-22)
147,374 (+45)
-0.02%
+0.03%
126,505 (-22)
147,374 (+45)
-0.02%
+0.03%
126,505 (-22)
147,374 (+45)
-0.02%
+0.03%
1 (0)
1 (0)

@b00ste b00ste marked this pull request as ready for review August 9, 2023 09:53
@b00ste b00ste force-pushed the DEV-7688 branch 2 times, most recently from 1dc2dc3 to 413ca43 Compare August 9, 2023 10:24
@YamenMerhi
Copy link
Member

Few things I had in mind:

  • Need to decide what is best for the visibility of the mapping (should it be public or internal)
  • Why not store the signature itself instead of a hash, lowering the possibilities of a hash collision.

@b00ste b00ste force-pushed the DEV-7688 branch 7 times, most recently from 1b5c793 to 650b25d Compare August 9, 2023 15:17
@skimaharvey
Copy link
Member

LGTM.

  • Just not sure we should not save the hash the econdedMessage in a stack variable.
  • Using bool instead of 1

@b00ste b00ste force-pushed the DEV-7688 branch 3 times, most recently from a9daf90 to fb9c199 Compare August 14, 2023 16:56
@CJ42
Copy link
Member

CJ42 commented Aug 15, 2023

@b00ste @skimaharvey

I suggest we put this PR as draft.
Also could you check how much gas difference there is for the deployment cost by comparing the gas benchmark of the Github actions?

(Looks like the gas diff for Foundry does not show this)

@b00ste
Copy link
Member Author

b00ste commented Aug 21, 2023

I will close the PR as hash collisions need more investigation.

@b00ste b00ste closed this Aug 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants