Skip to content

Commit

Permalink
V2 (#64)
Browse files Browse the repository at this point in the history
* index event params by vault, delegate, contract

* version bump

* chore: update links for new deployments in README (#29)

* chore: update links for new deployments

* fix: sanitize links

* fix: formatting

* comment spacing

* fix event emission

* solidity 0.8.18, named mappings

* comment cleanup

* comment cleanup

* forge fmt

* bump to solc 0.8.19

* version bump

* forge fmt

* gas benchmarking

* add getDelegationsByVault() method

* comment out all the get() tests, need to replace

* remove getContractLevelDelegations and getTokenLevelDelegations

* rename getDelegationsBy to getDelegationsFor

* remove ContractDelegation and TokenDelegation structs

* batch delegation

* remove extraneous boolean

* invert param order on _revokeDelegate

* todo notes

* get rid of unchecked, not worth the additional illegibility

* 4k gas savings from storage cleanup in revokeAllDelegates

* gas report for getDelegationsForVault

* batch delegation test

* cleaner internal variable names

* todo

* rewrite tests to use new enumerations, refactor into _filterHash() function

* remove revokeDelegate(), revokeSelf(), and delegateVersion internal mapping

* revokeAllDelegates() -> revokeAllDelegations()

* test cleanup, event renaming

* forge fmt

* remove revokeAllDelegations()

* cleanup _lookupHashes()

* forge fmt

* wip

* tests passing with new bytes32 data param

* line length 160

* smaller comments

* gas optimization

* Implemented delegateForBalance idea

* Pushing some comments fo reference

* Pushing some comments for reference

* Changed to ∃ delegatedBalance + return that method

* Updated formatting

* Ideas for supporting tokenId with balance case

* Pushing work on test Airdrop contract

* forge install: murky

* Minor bug fixes

* Started creating end to end airdrop test

* Ran forge fmt

* Created foundry airdrop test for delegate case

* Fixing remappings

* Add remappings.txt to .gitignore

* Untracking remappings.txt

* Descriptive naming, empties delegate airdrop test

* Modified Claim event to include claimable

* Add claimAmount to calldata params

* Inherit delegate logic using DelegateAirdrop

* More renaming changes, added NatSpec

* Implements "continuous" token balance delegation, updated tests, and airdrop example + test (#34)

* Implemented delegateForBalance idea

* Pushing some comments fo reference

* Pushing some comments for reference

* Changed to ∃ delegatedBalance + return that method

* Updated formatting

* Ideas for supporting tokenId with balance case

* Pushing work on test Airdrop contract

* forge install: murky

* Minor bug fixes

* Started creating end to end airdrop test

* Ran forge fmt

* Created foundry airdrop test for delegate case

* Fixing remappings

* Add remappings.txt to .gitignore

* Untracking remappings.txt

* Descriptive naming, empties delegate airdrop test

* Modified Claim event to include claimable

* Add claimAmount to calldata params

* Inherit delegate logic using DelegateAirdrop

* More renaming changes, added NatSpec

* bump solc to 0.8.20

* rename to ERC20/721/1155 methods

* bump dependencies

* comment cleanup

* rename DelegationRegistry to DelegateRegistry

* remove openzeppelin ERC165 dependency, hardcode interface constant

* remove bytecode hash, some foundry.toml benchmarking

* Resolving conflicts with v2

* Resolved inline TODOs

* Committing v2 modifications to v2_wip

* Reducing gas by increasing gas for getDelegations

* Inverted checks to optimize for ALL delegations

* Rights only stored if non-default, removed structs

* Collisions between types now impossible

* Subdelegations added to checkDelegateForERC20

* Standardized storage positions, remove rights loop

* Simplified getDelegationsFromHashes, repeated code

* Subdelegation support for all tiers, natspec

* Code refactor, added private function section

* Removed none type, distinct delegation structs

* Added supports interface test

* gasreport

* Keep NONE type

* checkDelegateForERC721 made external

* Stopped duplicate hash pushes, 10x enumeration

* Removed enable, moved positions to registry

* Added getDelegationHashes methods, enables retrieval for vault / delegate hash arrays up to 100k in size and increased getDelegations capacity up to 13k (via infura). Reverted to v1 ordering.

* Separated get method gas tests

* Subdelegations, airdrop example is now a subdelegation example, up to 30% less gas for delegate methods (#36)


DelegateRegistry.sol changes
Replaced OpenZeppelin enumerable sets with bytes32[] array in vault and delegate hash mappings

Hashes for a particular vault / delegate are now pushed to a bytes32[] array in their hash mappings instead of adding (and removing) them from a set. This reduces gas by > 40k every time a delegation is added to the registry due to the storage writes in the enumerable set backend. Suppose that a vault / delegate accumulates 500 delegation hashes in their array, the increased computation of the getDelegationsFor methods is well within acceptable gas limits for most RPC providers.

Consumable methods are unaffected as they now use the _delegations mapping only to establish whether a delegation is valid and enabled / disabled.
Changed bytes to bytes32[6] in _delegations mapping

Reduces > 20k gas every time a delegation is added since variable sized storage data also need to store their length.
Updated delegate methods to write minimal storage and removed _setDelegationValues

Delegate methods now only write data if it exists in their type and does not write rights to storage if it's the default "". _computeDelegationLocation(hash) is used to obtain the storage location for a given hash, and writeDelegation(location, StoragePositions.delegate, data); is used to write particular delegation data. For example, this saves > 80k gas for a delegateForAll call with all rights. Storage positions of data types are standardised with the new StoragePositions struct. _setDelegationValues has been removed since these changes make it redundant.
Delegation type now encoded in the last byte of the hash

This solves both the problem of collisions and being able to identify the type of delegation without writing its type to storage.
Check methods now support subdelegations

All check methods now accept a bytes32 rights parameter (previously data). If this parameter is not the default "", the check will bubble through the default case and then the rights case unless it returns true before exhausting the search (in the case of erc721, contract, all) or unless it returns type(uint256).max before exhausting the search (in the erc20, erc1155 cases). The _loadDelegationAddress(location, StoragePositions.vault) and _loadDelegationUint(location, StoragePositions.balance) methods are used to load vault and balance values directly from storage. A check on vault is now used to determine if the hash exists and is valid (since it is set to zero when disabled, and set to vault when enabled).
Removed occurrences of IDelegationRegistry.[object]

These objects are inherited explicitly anyway, and omitting IDelegationRegistry from these object references increases readability of the code.
Created Consumable and Private methods sections

Mostly a code refactor to keep the write and read sections clean. Added consumable as a section since we have distinct classes of on chain functions that can be consumed on and off chain.
IDelegateRegistry.sol changes

    Removed NONE from DelegationType enum as it's never used.
    Added StoragePositions enum to standardise storage position of delegation data.
    Renamed DelegationInfo to Delegation struct to be used for returning an arbitrary delegation.
    Created BatchDelegation struct to be used for batch delegations

Airdrop Example Updated to a Subdelegation Example

The airdrop example now accepts sub delegations with rights = "airdrop" in addition to default delegations, configured with a acceptableRight variable in the airdrop contract.
New tests

    Fuzz test for supportsInterface method
    testVultEnumerationGas tests an edge case where a vault has enabled 500 delegations.

* make interface support >=0.8.13, remove comment ramblings

* rename balance to amount

* move erc165 function around

* replace delegateForX method names with delegateX, easier to read on etherscan

* Test to isolate write / consumable function gas

* Formatting correction

* Added multicall, removed batchDelegate (#38)

Modest gas benefits, and much cleaner / simpler (smaller function, removes need for BatchDelegation struct). Also allows projects to multicall other registry functions without going through an external multicall contract. Encoding is very simple on the front end as well e.g.:

```
var batch = [];

const delegation1 = delegateRegistry.methods.delegateAll([delegate1, "", true]).encodeABI();

const delegation2 = delegateRegistry.methods.delegateERC20([delegate2, contract2, 10, "", true]).encodeABI();

batch.push(delegation1);

batch.push(delegation2);

try {
  await delegateRegistry.methods.multicall(batch).send(); 
} catch(err) {
  console.log(err);
}
```

* Registry harness, integration test for delegateAll

* Create new registry in each _delegateAll test call

* gasdiff (#39)

* gasdiff

* touch pr

* only run on gasbenchmark

* test gasdiff, add nonsense storage write

* V2 gasdiff test (#41)

* add nonsense storage write to boost delegateAll() gas by 20k

* remove storage write

* run gasreport on v2 branch

* cleanup gasdiff test, port gasreport over to gasbenchmark

* Sub-delegation example: IP License Check

* Added mappings to registry harness

* DelegateForContract integration test

* delegateERC721 integration test

* Merged singular integration tests into one file

* Started creating unit tests for registry functions

* Fixed missing hashes if delegation set false first

* Loop unit tests: repeated case and amount updates

* Vault storage flags, added _validDelegation method (#44)

* Vault storage flags, added _validDelegation method

* Added explicit internal declaration to storage flags

* Unclassified type decoding, multicall unit test

* Unit tests for consumables

* gas optimizations (#45)

* gas optimizations, rename events, add multicall error, return NONE if delegation unknown/existed

* add rest of files

* clean up storage flag naming

* rename DelegationsForDelegate to IncomingDelegations, DelegationsForVault to OutgoingDelegations

* forge fmt

* rename delegate/vault -> to/from in events and function calls

* rename StoragePositions

* more renaming

* more unchecked

* gasreport

* more renaming

* more renaming

* add nonexistent checks to gasbenchmark to highlight double-bubble issue (#46)

* linearize checks (#48)

* linearize checkContract, shaved 800 gas off failure case

* linearize checkERC721, chop off 1k gas there

* gasbenchmark

* all check functions now external, no bubbling, linearization, shaved 3k gas off erc20/1155

* format

* compress increment

* rename test file

* Slither report action, minor style convention edits (#49)

* Moved internal pure to library, ext storage access (#50)

* Storage compression, private f(x) > harness, tests (#51)

* Storage compression, private f(x) > harness, tests

* Additional shifts to clean any dirty bits

* fmt

* INTERNAL,  slither comment, removed whitespace

* 10-17% Gas reduction for checks, hash tests (#52)

* Storage method library, reduced visual complexity (#53)

* Location collision test, storage library tests

* Moved HashHarness to benchmark, added more tests

* Moved RegistryHarness to test, equivalence tests

* style nits

* Open zep to v4.9, delete slither report

* Slither action, naming conventions,  long digits

* bump solc to 0.8.21 (#54)

* correct comment

* Casing nits

* fix gas reports

* add write permission to PR (#57)

* Gasoptvect, bool cleaning rules, storage positions, readSlots, forge update (#58)


Follow up to the Vectorized pr / merge into Gasoptvect
Solidity compiler stack cleaning rules

SolidityCleaningRulespng

Source: https://docs.soliditylang.org/en/v0.8.21/internals/variable_cleanup.html
Direct returns of booleans and boolean cleaning

From what I can see from the solidity docs, the compiler rule for cleaning booleans on the stack is done by setting them to 1 if they contain any dirty bits (see table and reference above). The iszero opcodes used in the direct valid returns and RegistryOps should conform to that cleaning rule. There is some ambiguity as to whether that should be done in assembly blocks when accessing variables, but I didn't manage to find any documentation where cleaning to their last bit or byte, for example, is an appropriate cleaning method. They don't mention in the table that this cleaning rule is going to change, but it will be worth checking when using future compiler versions. tldr. seems fine to do this given the only obvious other method is just to not use assembly for booleans.
RegistryHashes.sol

The assembly blocks should be implemented according to the solidity memory model and are marked; accordingly, this will allow projects to use these libraries without the downside of globally disabled compiler memory optimisation at a very slight gas cost to the registry.
Other important changes
Replaced Positions enum in RegistryStorage with POSITIONS_[name] uint256 constants

    This means we don't have to navigate the correct cleaning (reverting flow) of enums on the stack in the assembly blocks. We were directly using enums in assembly blocks before without cleaning them which was incorrect. uint256 means we don't need to clean at all as the type spans 32 bytes.
    All the functions that had the positions enum as a parameter now expect a uint256 instead.
    _writeDelegationAddresses and _loadDelegationAddresses no longer expects positions as a parameter and the packed position constants are hard coded into the function.
    _loadFrom no longer expects the first packed position as a parameter and the first packed constant is now hard codeded into the function.
    Tests have been updated to reflect this change as the positions enum was used in several places.

readSlots

Now has a simplified implementation where assembly is only used for the sload operation.
forge update

Updated foundry submodule and OpenZeppelin submodule to their latest v4.9.3 release

* Payable delegate funcs for possible tip functionality (#59)

* make delegate funcs payable

* add slither ignore, add singlesig prototype

* add slither detector ignore to sweep

* two step ownership transfer

* error code cleanup

* add receive and fallback funcs to singlesig

* use revert strings for broad version and chain explorer compat

* add test

* remove slither error ignore

* gasreport

* forge fmt

* remove delegatecall from singlesig

* forge update

* Removed enable for fungibles, preserve storage. (#60)



    Removed enable for fungibles, control of revoking / delegating a fungible is now done entirely through amount; corresponding events and functions updated with enable removed, interface also updated.
    We are still emitting delegation events regardless of whether the state was actually changed.
    Delegate functions updated to preserve storage. Before: everything but the from storage flag was deleted. Now: Once a delegation has been created once, it is only possible to toggle the from storage flag and change the amount for fungibles, the rest of the storage is preserved.
    loadedFrom cached given its extended use in limiting the amount of storage interactions on calling one of the delegate methods.
    _updateFrom storage helper added to assist with the updates of from whilst preserving the rest of the packed slot.
    _validateDelegation replaced with _validateFrom since the check on from > address(1) is redundant since DELEGATION_EMPTY = address(0) and DELEGATION_REVOKED = address(1) cannot reasonably write to the registry.
    Removed redundant checks on validateDelegation in checkDelegateForERC20 and checkDelegateForERC1155 since amount will now always return zero if the fungible delegations are revoked.
    Added _invalidFrom helper function to reduce repeated code of checking if a from input is DELEGATION_REVOKED or DELEGATION_EMPTY.
    Moved DELEGATION_EMPTY and DELEGATION_REVOKED flags to RegistryStorage as projects might want to use these when performing manual storage read operations on the registry.
    Removed CLEAN_LAST12_BYTES_ADDRESS, not actually used anywhere.
    Updated tests and harness to reflect change in how the fungibles are enabled / disabled.

* Skip bubble up in checks for invalidFrom to avoid confusion. (#61)

Skips bubble up for _invalidFrom in the checks to avoid confusion with address(0) and / or address(1) having 'delegated' things, and also to be consistent with their omission in the enumeration functions.

* wip (#62)

* submodule update

* C4 audit fixes and mainnet deployment (#63)

C4 audit fixes and mainnet deployment to 0x00000000000000447e69651d841bD8D104Bed493

---------

Co-authored-by: lambda-0x <[email protected]>
Co-authored-by: Michael Reynolds <[email protected]>
  • Loading branch information
3 people authored Sep 23, 2023
1 parent 38576a7 commit 40d367d
Show file tree
Hide file tree
Showing 37 changed files with 4,390 additions and 1,132 deletions.
55 changes: 55 additions & 0 deletions .github/workflows/foundry-gas-diff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Report gas diff

on:
push:
branches:
- main
- v2
pull_request:
# Optionally configure to run only for changes in specific files. For example:
# paths:
# - src/**
# - test/**
# - foundry.toml
# - remappings.txt
# - .github/workflows/foundry-gas-diff.yml

jobs:
compare_gas_reports:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Install Foundry
uses: onbjerg/foundry-toolchain@v1
with:
version: nightly

# Add any step generating a gas report to a temporary file named gasreport.ansi. For example:
- name: Run tests
run: forge test --match-contract GasBenchmark --gas-report > gasreport.ansi # <- this file name should be unique in your repository!
env:
# make fuzzing semi-deterministic to avoid noisy gas cost estimation
# due to non-deterministic fuzzing (but still use pseudo-random fuzzing seeds)
FOUNDRY_FUZZ_SEED: 0x${{ github.event.pull_request.base.sha || github.sha }}

- name: Compare gas reports
uses: Rubilmax/[email protected]
with:
summaryQuantile: 0.0 # display all the most significant gas diffs in the summary (defaults to 20%)
sortCriteria: avg,max # sort diff rows by criteria
sortOrders: desc,asc # and directions
ignore: test-foundry/**/* # filter out gas reports from specific paths (test/ is included by default)
id: gas_diff

- name: Add gas diff to sticky comment
if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target'
uses: marocchino/sticky-pull-request-comment@v2
with:
# delete the comment in case changes no longer impact gas costs
delete: ${{ !steps.gas_diff.outputs.markdown }}
message: ${{ steps.gas_diff.outputs.markdown }}
12 changes: 12 additions & 0 deletions .github/workflows/slither-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Slither Report
on: [push, pull_request]
jobs:
slither-report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: crytic/[email protected]
with:
target: "src/"
slither-args: "--checklist"
fail-on: "low"
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
cache/
out/
broadcast/
broadcast/
Makefile
abi.json
.vscode/
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
branch = master
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/openzeppelin/openzeppelin-contracts
branch = release-v4.9 # Master branch is not safe to use
[submodule "lib/murky"]
path = lib/murky
url = https://github.com/dmfxyz/murky
branch = main
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@
|Fantom (testnet)|[0x00000000000076A84feF008CDAbe6409d2FE638B](https://testnet.ftmscan.com/address/0x00000000000076a84fef008cdabe6409d2fe638b)|


If you'd like to get the DelegationRegistry on another EVM chain, anyone in the community can deploy to the same address! Simply run the script in [Deploy.s.sol](script/Deploy.s.sol) with the specified salt. The CREATE2 factory must be deployed at `0x0000000000FFe8B47B3e2130213B802212439497`, but this factory exists on 19 separate chains so shouldn't be an issue. If you've run a community deployment, open a PR adding the link to the above table.
If you'd like to get the DelegateRegistry on another EVM chain, anyone in the community can deploy to the same address! Simply run the script in [Deploy.s.sol](script/Deploy.s.sol) with the specified salt. The CREATE2 factory must be deployed at `0x0000000000FFe8B47B3e2130213B802212439497`, but this factory exists on 19 separate chains so shouldn't be an issue. If you've run a community deployment, open a PR adding the link to the above table.

## Overview

Welcome! If you're a programmer, view [the specific registry code here](src/DelegationRegistry.sol). If you want to discuss specific open questions, click on the "Issues" tab to leave a comment. If you're interested in integrating this standard into your token project or marketplace, we're in the process of creating example templates - or reach out directly via a [Twitter DM](https://twitter.com/0xfoobar).
Welcome! If you're a programmer, view [the specific registry code here](src/DelegateRegistry.sol). If you want to discuss specific open questions, click on the "Issues" tab to leave a comment. If you're interested in integrating this standard into your token project or marketplace, we're in the process of creating example templates - or reach out directly via a [Twitter DM](https://twitter.com/0xfoobar).

We have an exciting group of initial people circling around this standard, including foobar (hi!), punk6529 (open metaverse), loopify (loopiverse), andy8052 (fractional), purplehat (artblocks), emiliano (nftrentals), arran (proof), james (collabland), john (gnosis safe), wwhchung (manifoldxyz) tally labs and many more. The dream is to move from a fragmented world where no individual deployment gets serious use to a global registry where users can register their vault once and use it safely for a variety of airdrops & other claims! Please reach out if interested in helping make this a reality on either the technical, social, or integration side.

Expand Down Expand Up @@ -77,13 +77,13 @@ wenew's approach via [HotWalletProxy](https://github.com/wenewlabs/public/blob/m

## How do I use it?

Check out the [IDelegationRegistry.sol](src/IDelegationRegistry.sol) file. This is the interface to interact with, and contains the following methods:
Check out the [IDelegateRegistry.sol](src/IDelegateRegistry.sol) file. This is the interface to interact with, and contains the following methods:

```code
/// WRITE ///
function delegateForAll(address delegate, bool value) external;
function delegateForContract(address delegate, address contract_, bool value) external;
function delegateForToken(address delegate, address contract_, uint256 tokenId, bool value) external;
function delegateAll(address delegate, bool value) external;
function delegateContract(address delegate, address contract_, bool value) external;
function delegateERC721(address delegate, address contract_, uint256 tokenId, bool value) external;
function revokeAllDelegates() external;
function revokeDelegate(address delegate) external;
function revokeSelf(address vault) external;
Expand All @@ -94,7 +94,7 @@ function getDelegatesForContract(address vault, address contract_) external view
function getDelegatesForToken(address vault, address contract_, uint256 tokenId) external view returns (address[] memory);
function checkDelegateForAll(address delegate, address vault) external view returns (bool);
function checkDelegateForContract(address delegate, address vault, address contract_) external view returns (bool);
function checkDelegateForToken(address delegate, address vault, address contract_, uint256 tokenId) external view returns (bool);
function checkDelegateForERC721(address delegate, address vault, address contract_, uint256 tokenId) external view returns (bool);
```

As an NFT creator, the important ones to pay attention to are `getDelegationsByDelegate()`, which you can use on the website frontend to enumerate which vaults a specific hotwallet is delegated to act on behalf of, and `checkDelegateForToken()`, which can be called in your smart contract to ensure a hotwallet is acting on behalf of the proper vaults.
As an NFT creator, the important ones to pay attention to are `getDelegationsByDelegate()`, which you can use on the website frontend to enumerate which vaults a specific hotwallet is delegated to act on behalf of, and `checkDelegateForERC721()`, which can be called in your smart contract to ensure a hotwallet is acting on behalf of the proper vaults.
22 changes: 20 additions & 2 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@
src = 'src'
out = 'out'
libs = ['lib']
solc_version = "0.8.17"

# See more config options https://github.com/foundry-rs/foundry/tree/master/config
auto_detect_remappings = false
# remappings = []

solc_version = "0.8.21"
# EVM version must be Paris not Shanghai to prevent PUSH0 incompatibility with other EVM chains
# Extra 137 deployment size, extra 0.1% runtime gas costs from using older version
evm_version = "paris"
# Etherscan verification max is 100 million
optimizer_runs = 9_999_999
# Get reproducible bytecode across machines by removing metadata hash from runtime bytecode, also saves 41 deployment size
bytecode_hash = "none"
# Disable ir optimizer, minimal gas savings not worth the potential for bugs
via_ir = false


[fmt]
line_length = 180
wrap_comments = true # Increases readability of comments

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
26 changes: 26 additions & 0 deletions gasbenchmark10mil
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
No files changed, compilation skipped

Running 1 test for test/GasBenchmark.t.sol:GasBenchmark
[PASS] testGas(address,bytes32) (runs: 256, μ: 13573356, ~: 13573452)
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 247.64ms
| src/DelegateRegistry.sol:DelegateRegistry contract | | | | | |
|----------------------------------------------------|-----------------|--------|--------|--------|---------|
| Deployment Cost | Deployment Size | | | | |
| 2011327 | 10078 | | | | |
| Function Name | min | avg | median | max | # calls |
| checkDelegateForAll | 3002 | 3198 | 3198 | 3395 | 2 |
| checkDelegateForContract | 5491 | 5899 | 5899 | 6308 | 2 |
| checkDelegateForERC1155 | 7932 | 8550 | 8550 | 9169 | 2 |
| checkDelegateForERC20 | 7882 | 8494 | 8494 | 9106 | 2 |
| checkDelegateForERC721 | 7975 | 8607 | 8607 | 9240 | 2 |
| delegateAll | 135825 | 135825 | 135825 | 135825 | 2 |
| delegateContract | 114433 | 125383 | 125383 | 136333 | 2 |
| delegateERC1155 | 5710 | 93282 | 93282 | 180854 | 2 |
| delegateERC20 | 5357 | 81865 | 81865 | 158374 | 2 |
| delegateERC721 | 136921 | 147871 | 147871 | 158821 | 2 |
| multicall | 404294 | 404294 | 404294 | 404294 | 1 |




Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests)
27 changes: 27 additions & 0 deletions hashbenchmark10mil
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
No files changed, compilation skipped

Running 1 test for test/HashBenchmark.t.sol:HashBenchmark
[PASS] testHashGas(address,bytes32,address,uint256,address,bytes32) (runs: 256, μ: 19906, ~: 19906)
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 32.07ms
| test/HashBenchmark.t.sol:HashHarness contract | | | | | |
|-----------------------------------------------|-----------------|-----|--------|-----|---------|
| Deployment Cost | Deployment Size | | | | |
| 282524 | 1443 | | | | |
| Function Name | min | avg | median | max | # calls |
| allHash | 658 | 658 | 658 | 658 | 1 |
| allLocation | 715 | 715 | 715 | 715 | 1 |
| contractHash | 777 | 777 | 777 | 777 | 1 |
| contractLocation | 824 | 824 | 824 | 824 | 1 |
| decodeType | 371 | 371 | 371 | 371 | 1 |
| erc1155Hash | 785 | 785 | 785 | 785 | 1 |
| erc1155Location | 899 | 899 | 899 | 899 | 1 |
| erc20Hash | 756 | 756 | 756 | 756 | 1 |
| erc20Location | 793 | 793 | 793 | 793 | 1 |
| erc721Hash | 830 | 830 | 830 | 830 | 1 |
| erc721Location | 867 | 867 | 867 | 867 | 1 |
| location | 384 | 384 | 384 | 384 | 1 |




Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests)
2 changes: 1 addition & 1 deletion lib/forge-std
Submodule forge-std updated 49 files
+134 −0 .github/workflows/ci.yml
+29 −0 .github/workflows/sync.yml
+0 −26 .github/workflows/tests.yml
+1 −1 .gitignore
+1 −1 LICENSE-APACHE
+1 −1 LICENSE-MIT
+8 −4 README.md
+21 −0 foundry.toml
+1 −1 lib/ds-test
+16 −0 package.json
+35 −0 src/Base.sol
+21 −33 src/Script.sol
+376 −0 src/StdAssertions.sol
+236 −0 src/StdChains.sol
+817 −0 src/StdCheats.sol
+15 −0 src/StdError.sol
+107 −0 src/StdInvariant.sol
+179 −0 src/StdJson.sol
+43 −0 src/StdMath.sol
+378 −0 src/StdStorage.sol
+333 −0 src/StdStyle.sol
+198 −0 src/StdUtils.sol
+31 −777 src/Test.sol
+527 −138 src/Vm.sol
+406 −386 src/console2.sol
+105 −0 src/interfaces/IERC1155.sol
+12 −0 src/interfaces/IERC165.sol
+43 −0 src/interfaces/IERC20.sol
+190 −0 src/interfaces/IERC4626.sol
+164 −0 src/interfaces/IERC721.sol
+73 −0 src/interfaces/IMulticall3.sol
+13,248 −0 src/safeconsole.sol
+0 −12 src/test/Script.t.sol
+0 −599 src/test/StdAssertions.t.sol
+0 −226 src/test/StdCheats.t.sol
+0 −200 src/test/StdMath.t.sol
+1,015 −0 test/StdAssertions.t.sol
+220 −0 test/StdChains.t.sol
+610 −0 test/StdCheats.t.sol
+15 −21 test/StdError.t.sol
+212 −0 test/StdMath.t.sol
+120 −126 test/StdStorage.t.sol
+110 −0 test/StdStyle.t.sol
+342 −0 test/StdUtils.t.sol
+10 −0 test/compilation/CompilationScript.sol
+10 −0 test/compilation/CompilationScriptBase.sol
+10 −0 test/compilation/CompilationTest.sol
+10 −0 test/compilation/CompilationTestBase.sol
+187 −0 test/fixtures/broadcast.log.json
1 change: 1 addition & 0 deletions lib/murky
Submodule murky added at 40de6e
2 changes: 1 addition & 1 deletion lib/openzeppelin-contracts
4 changes: 4 additions & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ds-test/=lib/forge-std/lib/ds-test/src/
forge-std/=lib/forge-std/src/
murky/=lib/murky/src/
openzeppelin/=lib/openzeppelin-contracts/contracts/
35 changes: 21 additions & 14 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -1,34 +1,41 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.21;

import {Script} from "forge-std/Script.sol";
import {console2} from "forge-std/console2.sol";
import {DelegationRegistry} from "../src/DelegationRegistry.sol";
import {DelegateRegistry} from "../src/DelegateRegistry.sol";
import {Singlesig} from "../src/singlesig/Singlesig.sol";

interface ImmutableCreate2Factory {
function safeCreate2(bytes32 salt, bytes calldata initCode) external payable returns (address deploymentAddress);
function findCreate2Address(bytes32 salt, bytes calldata initCode)
external
view
returns (address deploymentAddress);
function findCreate2AddressViaHash(bytes32 salt, bytes32 initCodeHash)
external
view
returns (address deploymentAddress);
function findCreate2Address(bytes32 salt, bytes calldata initCode) external view returns (address deploymentAddress);
function findCreate2AddressViaHash(bytes32 salt, bytes32 initCodeHash) external view returns (address deploymentAddress);
}

contract Deploy is Script {
ImmutableCreate2Factory immutable factory = ImmutableCreate2Factory(0x0000000000FFe8B47B3e2130213B802212439497);
bytes initCode = type(DelegationRegistry).creationCode;
bytes32 salt = 0x00000000000000000000000000000000000000008b99e5a778edb02572010000;
bytes initCode = type(DelegateRegistry).creationCode;
// bytes32 salt = 0x0000000000000000000000000000000000000000fbe49ecfc3decb1164228b89;
bytes32 salt = 0x00000000000000000000000000000000000000002bbc593dd77cb93fbb932d5f;

// bytes initCode = abi.encodePacked(type(Singlesig).creationCode, abi.encode(address(0x6Ed7D526b020780f694f3c10Dfb25E1b134D3215)));
// bytes32 salt = 0x000000000000000000000000000000000000000016c7768a8c7a2824b846321d;

function run() external {
vm.startBroadcast();

// address singlesigAddress = factory.safeCreate2(salt, initCode);
// Singlesig singlesig = Singlesig(payable(singlesigAddress));
// console2.log(address(singlesig));

address registryAddress = factory.safeCreate2(salt, initCode);
DelegationRegistry registry = DelegationRegistry(registryAddress);
DelegateRegistry registry = DelegateRegistry(registryAddress);
console2.log(address(registry));

// address registryAddress = factory.safeCreate2(salt, initCode);
// DelegateRegistry registry = DelegateRegistry(registryAddress);
// console2.log(address(registry));

vm.stopBroadcast();
}
}
Loading

0 comments on commit 40d367d

Please sign in to comment.