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

fix: [L-01] Return bytes directly in LSP6 _executePayload, to prevent data loss #784

Merged
merged 3 commits into from
Nov 2, 2023

Conversation

CJ42
Copy link
Member

@CJ42 CJ42 commented Nov 2, 2023

What does this PR introduce?

🐛 Bug Fix

Current Behaviour

In the Key Manager, when calling executeBatch function on the LSP0 linked contract via:

  • LSP6KeyManager.execute(...)
  • LSP6KeyManager.executeBatch(...)
  • LSP6KeyManager.executeRelayCall(...)
  • LSP6KeyManager.executeRelayCallBatch(...)

When the callData (or one of the callData in the batch functions) is executeBatch, the internal _executePayload incorrectly decodes it as bytes, while the type returned is bytes[].

For example, when calling executeBatch with two payloads that call a view function that should return:

[
   "Simple Contract Name", // a string
   5 // a number
]

Instead of returning an abi-encoded array of bytes[] as shown in screenshot below:

image

It decodes as bytes, which results in data loss and return the following:

image

The reason for this incorrect decoding is because the abi.decode(result, (bytes)) treats incorrectly the first 2 x 32 bytes word of the return data.

The line with the ternary operator:

return result.length != 0 ? abi.decode(result, (bytes)) : result;

thinks treat as it was decoding a byte of length 2, when in fact 2 is the length of the array of bytes[].
This is the reason why in the screenshot above, 0x0000 is returned, because it takes the 2 bytes that follow which are 0000.

image

New Behaviour

Return the byte as raw abi-encoded bytes.

Decoding immediately as bytes is not possible anymore since the addition of the executeBatch path in the Key Manager. This data should then be decoded on the client side first as bytes or bytes[] if the function executeRelayCall was called on the Key Manager for instance.

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

Copy link
Contributor

github-actions bot commented Nov 2, 2023

Changes to gas cost

Generated at commit: e2c6d880b54ccd3b8499ca3a5cf32397892ba311, compared to commit: 1f92ca530fb56cf2b626b0feae311d6c4737b8a0

🧾 Summary (10% most significant diffs)

Contract Method Avg (+/-) %
LSP6ExecuteRestrictedController transferLYXToEOA
transferLYXToUP
transferNFTToRandomEOA
transferNFTToRandomUP
transferTokensToRandomEOA
transferTokensToRandomUP
-350 ✅
-350 ✅
-352 ✅
-352 ✅
-352 ✅
-440 ✅
-0.56%
-0.63%
-0.25%
-0.14%
-0.47%
-0.21%
LSP6ExecuteUnrestrictedController transferLYXToEOA
transferLYXToUP
transferNFTToRandomEOA
transferNFTToRandomUP
transferTokensToRandomEOA
transferTokensToRandomUP
-350 ✅
-350 ✅
-352 ✅
-352 ✅
-352 ✅
-440 ✅
-0.56%
-0.61%
-0.25%
-0.14%
-0.48%
-0.21%
LSP6SetDataRestrictedController execute
givePermissionsToController
-198 ✅
-45 ✅
-0.57%
-0.04%
LSP6SetDataUnrestrictedController execute
givePermissionsToController
-198 ✅
-45 ✅
-0.57%
-0.03%

Full diff report 👇
Contract Deployment Cost (+/-) Method Min (+/-) % Avg (+/-) % Median (+/-) % Max (+/-) % # Calls (+/-)
LSP6ExecuteRestrictedController 3,036,899 (-7,408) transferLYXToEOA
transferLYXToUP
transferNFTToRandomEOA
transferNFTToRandomUP
transferTokensToRandomEOA
transferTokensToRandomUP
62,058 (-350)
55,389 (-350)
143,016 (-352)
248,636 (-352)
74,965 (-352)
205,750 (-440)
-0.56%
-0.63%
-0.25%
-0.14%
-0.47%
-0.21%
62,058 (-350)
55,389 (-350)
143,016 (-352)
248,636 (-352)
74,965 (-352)
205,750 (-440)
-0.56%
-0.63%
-0.25%
-0.14%
-0.47%
-0.21%
62,058 (-350)
55,389 (-350)
143,016 (-352)
248,636 (-352)
74,965 (-352)
205,750 (-440)
-0.56%
-0.63%
-0.25%
-0.14%
-0.47%
-0.21%
62,058 (-350)
55,389 (-350)
143,016 (-352)
248,636 (-352)
74,965 (-352)
205,750 (-440)
-0.56%
-0.63%
-0.25%
-0.14%
-0.47%
-0.21%
1 (0)
1 (0)
1 (0)
1 (0)
1 (0)
1 (0)
LSP6ExecuteUnrestrictedController 3,036,899 (-7,408) transferLYXToEOA
transferLYXToUP
transferNFTToRandomEOA
transferNFTToRandomUP
transferTokensToRandomEOA
transferTokensToRandomUP
62,585 (-350)
56,989 (-350)
141,788 (-352)
247,409 (-352)
73,738 (-352)
204,216 (-440)
-0.56%
-0.61%
-0.25%
-0.14%
-0.48%
-0.21%
62,585 (-350)
56,989 (-350)
141,788 (-352)
247,409 (-352)
73,738 (-352)
204,216 (-440)
-0.56%
-0.61%
-0.25%
-0.14%
-0.48%
-0.21%
62,585 (-350)
56,989 (-350)
141,788 (-352)
247,409 (-352)
73,738 (-352)
204,216 (-440)
-0.56%
-0.61%
-0.25%
-0.14%
-0.48%
-0.21%
62,585 (-350)
56,989 (-350)
141,788 (-352)
247,409 (-352)
73,738 (-352)
204,216 (-440)
-0.56%
-0.61%
-0.25%
-0.14%
-0.48%
-0.21%
1 (0)
1 (0)
1 (0)
1 (0)
1 (0)
1 (0)
LSP6SetDataRestrictedController 3,024,883 (-7,408) execute
givePermissionsToController
restrictControllerToERC725YKeys
30,328 (-352)
122,641 (-45)
141,428 (-45)
-1.15%
-0.04%
-0.03%
34,316 (-198)
122,641 (-45)
141,428 (-45)
-0.57%
-0.04%
-0.03%
34,316 (-198)
122,641 (-45)
141,428 (-45)
-0.57%
-0.04%
-0.03%
38,304 (-45)
122,641 (-45)
141,428 (-45)
-0.12%
-0.04%
-0.03%
2 (0)
1 (0)
1 (0)
LSP6SetDataUnrestrictedController 3,024,883 (-7,408) execute
givePermissionsToController
restrictControllerToERC725YKeys
30,328 (-352)
128,641 (-45)
149,928 (-45)
-1.15%
-0.03%
-0.03%
34,316 (-198)
128,641 (-45)
149,928 (-45)
-0.57%
-0.03%
-0.03%
34,316 (-198)
128,641 (-45)
149,928 (-45)
-0.57%
-0.03%
-0.03%
38,304 (-45)
128,641 (-45)
149,928 (-45)
-0.12%
-0.03%
-0.03%
2 (0)
1 (0)
1 (0)

Copy link
Contributor

github-actions bot commented Nov 2, 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.

⛽📊 Gas Benchmark Report

Deployment Costs

Deployed contracts ⛽ Deployment cost
UniversalProfile 3130134 (0 )
KeyManager 3647991 (-8,012 📉✅)
LSP1DelegateUP 1630183 (0 )
LSP7Mintable 2350310 (0 )
LSP8Mintable 2443708 (0 )

Runtime Costs

UniversalProfile owned by an 🔑 EOA

🔀 execute scenarios

execute scenarios - UP owned by 🔑 EOA ⛽ Gas Usage
Transfer 1 LYX to an EOA without data 37560 (0 )
Transfer 1 LYX to a UP without data 46253 (0 )
Transfer 1 LYX to an EOA with 256 bytes of data 42209 (-24 📉✅)
Transfer 1 LYX to a UP with 256 bytes of data 57310 (-24 📉✅)
Transfer 0.1 LYX to 3x EOA without data 70862 (0 )
Transfer 0.1 LYX to 3x UP without data 104453 (0 )
Transfer 0.1 LYX to 3x EOA with 256 bytes of data 84862 (24 📈❌)
Transfer 0.1 LYX to 3x UPs with 256 bytes of data 137689 (36 📈❌)

🗄️ setData scenarios

setData scenarios - UP owned by 🔑 EOA ⛽ Gas Usage
Set a 20 bytes long value 49971 (0 )
Set a 60 bytes long value 95293 (0 )
Set a 160 bytes long value 164465 (0 )
Set a 300 bytes long value 279700 (24 📈❌)
Set a 600 bytes long value 484148 (-12 📉✅)
Change the value of a data key already set 32859 (0 )
Remove the value of a data key already set 27333 (0 )
Set 2 data keys of 20 bytes long value 78442 (-12 📉✅)
Set 2 data keys of 100 bytes long value 260606 (-12 📉✅)
Set 3 data keys of 20 bytes long value 105171 (12 📈❌)
Change the value of three data keys already set of 20 bytes long value 45459 (-12 📉✅)
Remove the value of three data keys already set 41360 (0 )

🗄️ Tokens scenarios

Tokens scenarios - UP owned by 🔑 EOA ⛽ Gas Usage
Minting a LSP7Token to a UP (No Delegate) from an EOA 92724 (0 )
Minting a LSP7Token to an EOA from an EOA 59377 (0 )
Transferring an LSP7Token from a UP to another UP (No Delegate) 101577 (0 )
Minting a LSP8Token to a UP (No Delegate) from an EOA 159593 (0 )
Minting a LSP8Token to an EOA from an EOA 126247 (0 )
Transferring an LSP8Token from a UP to another UP (No Delegate) 150271 (0 )
UniversalProfile owned by a 🔒📄 LSP6KeyManager

🔀 execute scenarios

execute scenarios 👑 main controller 🛃 restricted controller
LYX transfer --> to an EOA 64336 (0 ) 75148 (0 )
LYX transfer --> to a UP 78488 (0 ) 93210 (0 )
LSP7 token transfer --> to an EOA 116353 (0 ) 131067 (0 )
LSP7 token transfer --> to a UP 249627 (0 ) 264341 (0 )
LSP8 NFT transfer --> to an EOA 180440 (0 ) 195154 (0 )
LSP8 NFT transfer --> to a UP 296916 (0 ) 311630 (0 )

🗄️ setData scenarios

setData scenarios 👑 main controller 🛃 restricted controller
Update Profile details (LSP3Profile Metadata) 67338 (0 ) 77360 (0 )
Add a new controller with permission to SET_DATA + 3x allowed data keys:
AddressPermissions[]
+ AddressPermissions[index]
+ AddressPermissions:Permissions:<controller>
+ AddressPermissions:AllowedERC725YDataKeys:<controller)
209610 (0 ) 219767 (0 )
Update permissions of previous controller. Allow it now to SUPER_SETDATA 52366 (0 ) 55372 (0 )
Remove a controller:
1. decrease AddressPermissions[] Array length
2. remove the controller address at AddressPermissions[index]
3. set "0x" for the controller permissions under AddressPermissions:Permissions:
78842 (0 ) 90140 (0 )
Write 5x new LSP12 Issued Assets 67032 (0 ) 101659 (0 )
Update 3x data keys (first 3) 125476 (0 ) 159580 (0 )
Update 3x data keys (middle 3) 105564 (0 ) 143734 (0 )
Update 3x data keys (last 3) 125476 (0 ) 169067 (0 )
Set 2 x new data keys + add 3x new controllers 810447 (0 ) 872247 (0 )

@CJ42 CJ42 merged commit fd23a24 into develop Nov 2, 2023
25 checks passed
@CJ42 CJ42 deleted the fix/lsp6-return-bytes branch November 2, 2023 13:39
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.

4 participants