@bananapus/address-registry-v6 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/SKILLS.md +51 -0
  4. package/deployments/nana-address-registry/arbitrum/JBAddressRegistry.json +177 -0
  5. package/deployments/nana-address-registry/arbitrum_sepolia/JBAddressRegistry.json +177 -0
  6. package/deployments/nana-address-registry/base/JBAddressRegistry.json +181 -0
  7. package/deployments/nana-address-registry/base_sepolia/JBAddressRegistry.json +181 -0
  8. package/deployments/nana-address-registry/ethereum/JBAddressRegistry.json +181 -0
  9. package/deployments/nana-address-registry/optimism/JBAddressRegistry.json +177 -0
  10. package/deployments/nana-address-registry/optimism_sepolia/JBAddressRegistry.json +181 -0
  11. package/deployments/nana-address-registry/sepolia/JBAddressRegistry.json +181 -0
  12. package/docs/book.css +13 -0
  13. package/docs/book.toml +12 -0
  14. package/docs/solidity.min.js +74 -0
  15. package/docs/src/README.md +164 -0
  16. package/docs/src/SUMMARY.md +6 -0
  17. package/docs/src/src/JBAddressRegistry.sol/contract.JBAddressRegistry.md +106 -0
  18. package/docs/src/src/README.md +5 -0
  19. package/docs/src/src/interfaces/IJBAddressRegistry.sol/interface.IJBAddressRegistry.md +33 -0
  20. package/docs/src/src/interfaces/README.md +4 -0
  21. package/foundry.toml +29 -0
  22. package/package.json +20 -0
  23. package/remappings.txt +1 -0
  24. package/script/Deploy.s.sol +37 -0
  25. package/script/helpers/AddressRegistryDeploymentLib.sol +68 -0
  26. package/slither-ci.config.json +10 -0
  27. package/sphinx.lock +476 -0
  28. package/src/JBAddressRegistry.sol +96 -0
  29. package/src/interfaces/IJBAddressRegistry.sol +22 -0
  30. package/test/JBAddressRegistry.t.sol +104 -0
  31. package/test/JBAddressRegistry_Fork.t.sol +78 -0
@@ -0,0 +1,74 @@
1
+ hljs.registerLanguage("solidity",(()=>{"use strict";function e(){try{return!0
2
+ }catch(e){return!1}}
3
+ var a=/-?(\b0[xX]([a-fA-F0-9]_?)*[a-fA-F0-9]|(\b[1-9](_?\d)*(\.((\d_?)*\d)?)?|\.\d(_?\d)*)([eE][-+]?\d(_?\d)*)?|\b0)(?!\w|\$)/
4
+ ;e()&&(a=a.source.replace(/\\b/g,"(?<!\\$)\\b"));var s={className:"number",
5
+ begin:a,relevance:0},n={
6
+ keyword:"assembly let function if switch case default for leave break continue u256 jump jumpi stop return revert selfdestruct invalid",
7
+ built_in:"add sub mul div sdiv mod smod exp not lt gt slt sgt eq iszero and or xor byte shl shr sar addmod mulmod signextend keccak256 pc pop dup1 dup2 dup3 dup4 dup5 dup6 dup7 dup8 dup9 dup10 dup11 dup12 dup13 dup14 dup15 dup16 swap1 swap2 swap3 swap4 swap5 swap6 swap7 swap8 swap9 swap10 swap11 swap12 swap13 swap14 swap15 swap16 mload mstore mstore8 sload sstore msize gas address balance selfbalance caller callvalue calldataload calldatasize calldatacopy codesize codecopy extcodesize extcodecopy returndatasize returndatacopy extcodehash create create2 call callcode delegatecall staticcall log0 log1 log2 log3 log4 chainid origin gasprice basefee blockhash coinbase timestamp number difficulty gaslimit",
8
+ literal:"true false"},i={className:"string",
9
+ begin:/\bhex'(([0-9a-fA-F]{2}_?)*[0-9a-fA-F]{2})?'/},t={className:"string",
10
+ begin:/\bhex"(([0-9a-fA-F]{2}_?)*[0-9a-fA-F]{2})?"/};function r(e){
11
+ return e.inherit(e.APOS_STRING_MODE,{begin:/(\bunicode)?'/})}function l(e){
12
+ return e.inherit(e.QUOTE_STRING_MODE,{begin:/(\bunicode)?"/})}var o={
13
+ SOL_ASSEMBLY_KEYWORDS:n,baseAssembly:e=>{
14
+ var a=r(e),o=l(e),c=/[A-Za-z_$][A-Za-z_$0-9.]*/,d=e.inherit(e.TITLE_MODE,{
15
+ begin:/[A-Za-z$_][0-9A-Za-z$_]*/,lexemes:c,keywords:n}),u={className:"params",
16
+ begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,lexemes:c,keywords:n,
17
+ contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,o,s]},_={
18
+ className:"operator",begin:/:=|->/};return{keywords:n,lexemes:c,
19
+ contains:[a,o,i,t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s,_,{
20
+ className:"function",lexemes:c,beginKeywords:"function",end:"{",excludeEnd:!0,
21
+ contains:[d,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,_]}]}},
22
+ solAposStringMode:r,solQuoteStringMode:l,HEX_APOS_STRING_MODE:i,
23
+ HEX_QUOTE_STRING_MODE:t,SOL_NUMBER:s,isNegativeLookbehindAvailable:e}
24
+ ;const{baseAssembly:c,solAposStringMode:d,solQuoteStringMode:u,HEX_APOS_STRING_MODE:_,HEX_QUOTE_STRING_MODE:m,SOL_NUMBER:b,isNegativeLookbehindAvailable:E}=o
25
+ ;return e=>{for(var a=d(e),s=u(e),n=[],i=0;i<32;i++)n[i]=i+1
26
+ ;var t=n.map((e=>8*e)),r=[];for(i=0;i<=80;i++)r[i]=i
27
+ ;var l=n.map((e=>"bytes"+e)).join(" ")+" ",o=t.map((e=>"uint"+e)).join(" ")+" ",g=t.map((e=>"int"+e)).join(" ")+" ",M=[].concat.apply([],t.map((e=>r.map((a=>e+"x"+a))))),p={
28
+ keyword:"var bool string int uint "+g+o+"byte bytes "+l+"fixed ufixed "+M.map((e=>"fixed"+e)).join(" ")+" "+M.map((e=>"ufixed"+e)).join(" ")+" enum struct mapping address new delete if else for while continue break return throw emit try catch revert unchecked _ function modifier event constructor fallback receive error virtual override constant immutable anonymous indexed storage memory calldata external public internal payable pure view private returns import from as using pragma contract interface library is abstract type assembly",
29
+ literal:"true false wei gwei szabo finney ether seconds minutes hours days weeks years",
30
+ built_in:"self this super selfdestruct suicide now msg block tx abi blockhash gasleft assert require Error Panic sha3 sha256 keccak256 ripemd160 ecrecover addmod mulmod log0 log1 log2 log3 log4"
31
+ },O={className:"operator",begin:/[+\-!~*\/%<>&^|=]/
32
+ },C=/[A-Za-z_$][A-Za-z_$0-9]*/,N={className:"params",begin:/\(/,end:/\)/,
33
+ excludeBegin:!0,excludeEnd:!0,lexemes:C,keywords:p,
34
+ contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,s,b,"self"]},f={
35
+ begin:/\.\s*/,end:/[^A-Za-z0-9$_\.]/,excludeBegin:!0,excludeEnd:!0,keywords:{
36
+ built_in:"gas value selector address length push pop send transfer call callcode delegatecall staticcall balance code codehash wrap unwrap name creationCode runtimeCode interfaceId min max"
37
+ },relevance:2},y=e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/,
38
+ lexemes:C,keywords:p}),w={className:"built_in",
39
+ begin:(E()?"(?<!\\$)\\b":"\\b")+"(gas|value|salt)(?=:)"};function x(e,a){return{
40
+ begin:(E()?"(?<!\\$)\\b":"\\b")+e+"\\.\\s*",end:/[^A-Za-z0-9$_\.]/,
41
+ excludeBegin:!1,excludeEnd:!0,lexemes:C,keywords:{built_in:e+" "+a},
42
+ contains:[f],relevance:10}}var h=c(e),v=e.inherit(h,{
43
+ contains:h.contains.concat([{begin:/\./,end:/[^A-Za-z0-9$.]/,excludeBegin:!0,
44
+ excludeEnd:!0,keywords:{built_in:"slot offset length address selector"},
45
+ relevance:2},{begin:/_/,end:/[^A-Za-z0-9$.]/,excludeBegin:!0,excludeEnd:!0,
46
+ keywords:{built_in:"slot offset"},relevance:2}])});return{aliases:["sol"],
47
+ keywords:p,lexemes:C,
48
+ contains:[a,s,_,m,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,b,w,O,{
49
+ className:"function",lexemes:C,
50
+ beginKeywords:"function modifier event constructor fallback receive error",
51
+ end:/[{;]/,excludeEnd:!0,
52
+ contains:[y,N,w,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],illegal:/%/
53
+ },x("msg","gas value data sender sig"),x("block","blockhash coinbase difficulty gaslimit basefee number timestamp chainid"),x("tx","gasprice origin"),x("abi","decode encode encodePacked encodeWithSelector encodeWithSignature encodeCall"),x("bytes","concat"),f,{
54
+ className:"class",lexemes:C,beginKeywords:"contract interface library",end:"{",
55
+ excludeEnd:!0,illegal:/[:"\[\]]/,contains:[{beginKeywords:"is",lexemes:C
56
+ },y,N,w,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{lexemes:C,
57
+ beginKeywords:"struct enum",end:"{",excludeEnd:!0,illegal:/[:"\[\]]/,
58
+ contains:[y,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{
59
+ beginKeywords:"import",end:";",lexemes:C,keywords:"import from as",
60
+ contains:[y,a,s,_,m,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,O]},{
61
+ beginKeywords:"using",end:";",lexemes:C,keywords:"using for",
62
+ contains:[y,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,O]},{className:"meta",
63
+ beginKeywords:"pragma",end:";",lexemes:C,keywords:{
64
+ keyword:"pragma solidity experimental abicoder",
65
+ built_in:"ABIEncoderV2 SMTChecker v1 v2"},
66
+ contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.inherit(a,{
67
+ className:"meta-string"}),e.inherit(s,{className:"meta-string"})]},{
68
+ beginKeywords:"assembly",end:/\b\B/,
69
+ contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.inherit(v,{begin:"{",
70
+ end:"}",endsParent:!0,contains:v.contains.concat([e.inherit(v,{begin:"{",
71
+ end:"}",contains:v.contains.concat(["self"])})])})]}],illegal:/#/}}})());
72
+
73
+ // Ugly hack to reload HLJS
74
+ hljs.initHighlightingOnLoad();
@@ -0,0 +1,164 @@
1
+ # Bananapus Address Registry
2
+
3
+ Frontend clients need a way to verify that a Juicebox contract has a deployer they trust. `JBAddressRegistry` allows any contract deployed with `create` or `create2` to publicly register its deployer's address. Whoever deploys a contract is responsible for registering it.
4
+
5
+ <details>
6
+ <summary>Table of Contents</summary>
7
+ <ol>
8
+ <li><a href="#usage">Usage</a></li>
9
+ <ul>
10
+ <li><a href="#install">Install</a></li>
11
+ <li><a href="#develop">Develop</a></li>
12
+ <li><a href="#scripts">Scripts</a></li>
13
+ <li><a href="#deployments">Deployments</a></li>
14
+ <li><a href="#tips">Tips</a></li>
15
+ </ul>
16
+ <li><a href="#repository-layout">Repository Layout</a></li>
17
+ <li><a href="#description">Description</a></li>
18
+ <ul>
19
+ <li><a href="#overview">Overview</a></li>
20
+ <li><a href="#implementation-details">Implementation Details</a></li>
21
+ <li><a href="#risks">Risks</a></li>
22
+ </ul>
23
+ </ul>
24
+ </ol>
25
+ </details>
26
+
27
+ ## Usage
28
+
29
+ ### Install
30
+
31
+ How to install `nana-address-registry` in another project.
32
+
33
+ For projects using `npm` to manage dependencies (recommended):
34
+
35
+ ```bash
36
+ npm install @bananapus/address-registry
37
+ ```
38
+
39
+ For projects using `forge` to manage dependencies (not recommended):
40
+
41
+ ```bash
42
+ forge install Bananapus/nana-address-registry
43
+ ```
44
+
45
+ If you're using `forge` to manage dependencies, add `@bananapus/address-registry/=lib/nana-address-registry/` to `remappings.txt`.
46
+
47
+ ### Develop
48
+
49
+ `nana-address-registry` uses the [Foundry](https://github.com/foundry-rs/foundry) development toolchain for builds, tests, and deployments. To get set up, install [Foundry](https://github.com/foundry-rs/foundry):
50
+
51
+ ```bash
52
+ curl -L https://foundry.paradigm.xyz | sh
53
+ ```
54
+
55
+ You can download and install dependencies with:
56
+
57
+ ```bash
58
+ forge install
59
+ ```
60
+
61
+ If you run into trouble with `forge install`, try using `git submodule update --init --recursive` to ensure that nested submodules have been properly initialized.
62
+
63
+ Some useful commands:
64
+
65
+ | Command | Description |
66
+ | --------------------- | --------------------------------------------------- |
67
+ | `forge build` | Compile the contracts and write artifacts to `out`. |
68
+ | `forge fmt` | Lint. |
69
+ | `forge test` | Run the tests. |
70
+ | `forge build --sizes` | Get contract sizes. |
71
+ | `forge coverage` | Generate a test coverage report. |
72
+ | `foundryup` | Update foundry. Run this periodically. |
73
+ | `forge clean` | Remove the build artifacts and cache directories. |
74
+
75
+ To learn more, visit the [Foundry Book](https://book.getfoundry.sh/) docs.
76
+
77
+ ### Scripts
78
+
79
+ For convenience, several utility commands are available in `package.json`.
80
+
81
+ | Command | Description |
82
+ | --------------------------------- | -------------------------------------- |
83
+ | `npm test` | Run local tests. |
84
+ | `npm run test:fork` | Run fork tests (for use in CI). |
85
+ | `npm run coverage` | Generate an LCOV test coverage report. |
86
+
87
+ ### Deployments
88
+
89
+ To deploy, you'll need to set up a `.env` file based on `.example.env`. Then run one of the following commands:
90
+
91
+ | Command | Description |
92
+ | --------------------------------- | -------------------------------------- |
93
+ | `npm run deploy:ethereum-mainnet` | Deploy to Ethereum mainnet |
94
+ | `npm run deploy:ethereum-sepolia` | Deploy to Ethereum Sepolia testnet |
95
+ | `npm run deploy:optimism-mainnet` | Deploy to Optimism mainnet |
96
+ | `npm run deploy:optimism-testnet` | Deploy to Optimism testnet |
97
+
98
+ ### Tips
99
+
100
+ To view test coverage, run `npm run coverage` to generate an LCOV test report. You can use an extension like [Coverage Gutters](https://marketplace.visualstudio.com/items?itemName=ryanluker.vscode-coverage-gutters) to view coverage in your editor.
101
+
102
+ If you're using Nomic Foundation's [Solidity](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity) extension in VSCode, you may run into LSP errors because the extension cannot find dependencies outside of `lib`. You can often fix this by running:
103
+
104
+ ```bash
105
+ forge remappings >> remappings.txt
106
+ ```
107
+
108
+ This makes the extension aware of default remappings.
109
+
110
+ ## Repository Layout
111
+
112
+ The root directory contains this README, an MIT license, and config files.
113
+
114
+ The important source directories are:
115
+
116
+ ```
117
+ nana-address-registry/
118
+ ├── script/
119
+ │ └── Deploy.s.sol - The deployment script.
120
+ ├── src/ - The contract source code.
121
+ │ ├── JBAddressRegistry.sol - The main address registry contract.
122
+ │ └── interfaces/
123
+ │ └── IJBAddressRegistry.sol - The address registry interface.
124
+ └── test/
125
+ ├── JBAddressRegistry.t.sol - Unit tests.
126
+ └── JBAddressRegistry_Fork.t.sol - Fork tests.
127
+ ```
128
+
129
+ Other directories:
130
+
131
+ ```
132
+ nana-address-registry/
133
+ ├── .github/
134
+ │ └── workflows/ - CI/CD workflows.
135
+ └── broadcast/ - Deployment logs.
136
+ ```
137
+
138
+ ## Description
139
+
140
+ ### Overview
141
+
142
+ `JBAddressRegistry` is intended for registering the deployers of Juicebox pay/redeem hooks, but does not enforce adherence to an interface, and can be used for any `create`/`create2` deployer.
143
+
144
+ The addresses of the deployed contracts are computed deterministically based on the deployer's address, and a nonce (for `create`) or `create2` salt and deployment bytecode (for `create2`). That address is then used as a key to store the deployer's address. This allows clients to easily and trustlessly check a given hook's deployer, which can be used to help figure out whether a hook is "safe" or not, as determined by the client's developers.
145
+
146
+ _If you're having trouble understanding this contract, take a look at the [core protocol contracts](https://github.com/Bananapus/nana-core) and the [documentation](https://docs.juicebox.money/) first. If you have questions, reach out on [Discord](https://discord.com/invite/ErQYmth4dS)._
147
+
148
+
149
+ ### Implementation Details
150
+
151
+ - After deploying a Juicebox pay/redeem hook, any addresses can call `JBAddressRegistry.registerAddress(address deployer, uint256 nonce)` to add it to the registry. The registry will compute and store the corresponding hook address.
152
+ - Alternatively, `JBAddressRegistry.registerAddress(address deployer, bytes32 salt, bytes calldata bytecode)` will compute and store the hook deployed from a contract using `create2`.
153
+
154
+ The registry doesn't enforce `IERC165` or the implementation of any hook interfaces, meaning it can be used for any contract deployed with `create`/`create2`.
155
+
156
+ Clients can retrieve the nonce for the contract and an EOA using `provider.getTransactionCount(address)` from `ethers.js` or `web3.eth.getTransactionCount` from `web3.js` just *before* the hook's deployment. If registering a hook later on, clients may need to manually calculate the nonce.
157
+
158
+ The `create2` salt is determined by a given deployer's logic. The deployment bytecode can be retrieved offchain (from the deployment transaction) or onchain (with `abi.encodePacked(type(deployedContract).creationCode, abi.encode(constructorArguments))`).
159
+
160
+ ### Risks
161
+
162
+ Hooks have token minting access, making malicious hooks dangerous. Clients should warn project owners and users about any potential for unintended or adversarial behaviour, especially for unknown hooks.
163
+
164
+ Deployers can be exploited. Clients should still communicate risk to users.
@@ -0,0 +1,6 @@
1
+ # Summary
2
+ - [Home](README.md)
3
+ # src
4
+ - [❱ interfaces](src/interfaces/README.md)
5
+ - [IJBAddressRegistry](src/interfaces/IJBAddressRegistry.sol/interface.IJBAddressRegistry.md)
6
+ - [JBAddressRegistry](src/JBAddressRegistry.sol/contract.JBAddressRegistry.md)
@@ -0,0 +1,106 @@
1
+ # JBAddressRegistry
2
+ [Git Source](https://github.com/Bananapus/nana-address-registry/blob/922b48185d8a792b44854cf6d3257339a9d73eaa/src/JBAddressRegistry.sol)
3
+
4
+ **Inherits:**
5
+ [IJBAddressRegistry](/src/interfaces/IJBAddressRegistry.sol/interface.IJBAddressRegistry.md)
6
+
7
+ Frontend clients need a way to verify that a Juicebox contract has a deployer they trust. `JBAddressRegistry`
8
+ allows any contract deployed with `create` or `create2` to publicly register its deployer's address. Whoever deploys
9
+ a contract is reponsible for registering it.
10
+
11
+ *`JBAddressRegistry` is intended for registering the deployers of Juicebox pay/redeem hooks, but does not
12
+ enforce adherence to an interface, and can be used for any `create`/`create2` deployer.*
13
+
14
+ *The addresses of the deployed contracts are computed deterministically based on the deployer's address, and a
15
+ nonce (for `create`) or `create2` salt and deployment bytecode (for `create2`).*
16
+
17
+
18
+ ## State Variables
19
+ ### deployerOf
20
+ Returns the deployer of a given contract which has been registered.
21
+
22
+ *Whoever deploys a contract is responsible for registering it.*
23
+
24
+
25
+ ```solidity
26
+ mapping(address addr => address deployer) public override deployerOf;
27
+ ```
28
+
29
+
30
+ ## Functions
31
+ ### registerAddress
32
+
33
+ Register a deployed contract's address.
34
+
35
+ *The contract must be deployed using `create`.*
36
+
37
+
38
+ ```solidity
39
+ function registerAddress(address deployer, uint256 nonce) external override;
40
+ ```
41
+ **Parameters**
42
+
43
+ |Name|Type|Description|
44
+ |----|----|-----------|
45
+ |`deployer`|`address`|The address of the contract's deployer.|
46
+ |`nonce`|`uint256`|The nonce used to deploy the contract.|
47
+
48
+
49
+ ### registerAddress
50
+
51
+ Register a deployed contract's address.
52
+
53
+ *The contract must be deployed using `create2`.*
54
+
55
+ *The `create2` salt is determined by the deployer's logic. The deployment bytecode can be retrieved offchain
56
+ (from the deployment transaction) or onchain (with `abi.encodePacked(type(deployedContract).creationCode,
57
+ abi.encode(constructorArguments))`).*
58
+
59
+
60
+ ```solidity
61
+ function registerAddress(address deployer, bytes32 salt, bytes calldata bytecode) external override;
62
+ ```
63
+ **Parameters**
64
+
65
+ |Name|Type|Description|
66
+ |----|----|-----------|
67
+ |`deployer`|`address`|The address of the contract's deployer.|
68
+ |`salt`|`bytes32`|The `create2` salt used to deploy the contract.|
69
+ |`bytecode`|`bytes`|The contract's deployment bytecode, including the constructor arguments.|
70
+
71
+
72
+ ### _addressFrom
73
+
74
+ Compute the address of a contract deployed using `create` based on the deployer's address and nonce.
75
+
76
+ *Taken from https://ethereum.stackexchange.com/a/87840/68134 - this won't work for nonces > 2**32. If
77
+ you reach that nonce please: 1) ping us, because wow 2) use another deployer.*
78
+
79
+
80
+ ```solidity
81
+ function _addressFrom(address origin, uint256 nonce) internal pure returns (address addr);
82
+ ```
83
+ **Parameters**
84
+
85
+ |Name|Type|Description|
86
+ |----|----|-----------|
87
+ |`origin`|`address`|The deployer's address.|
88
+ |`nonce`|`uint256`|The nonce used to deploy the contract.|
89
+
90
+
91
+ ### _registerAddress
92
+
93
+ Register a contract's deployer in the `deployerOf` mapping.
94
+
95
+
96
+ ```solidity
97
+ function _registerAddress(address addr, address deployer) internal;
98
+ ```
99
+ **Parameters**
100
+
101
+ |Name|Type|Description|
102
+ |----|----|-----------|
103
+ |`addr`|`address`|The deployed contract's address.|
104
+ |`deployer`|`address`|The deployer's address.|
105
+
106
+
@@ -0,0 +1,5 @@
1
+
2
+
3
+ # Contents
4
+ - [interfaces](/src/interfaces)
5
+ - [JBAddressRegistry](JBAddressRegistry.sol/contract.JBAddressRegistry.md)
@@ -0,0 +1,33 @@
1
+ # IJBAddressRegistry
2
+ [Git Source](https://github.com/Bananapus/nana-address-registry/blob/922b48185d8a792b44854cf6d3257339a9d73eaa/src/interfaces/IJBAddressRegistry.sol)
3
+
4
+
5
+ ## Functions
6
+ ### deployerOf
7
+
8
+
9
+ ```solidity
10
+ function deployerOf(address addr) external view returns (address deployer);
11
+ ```
12
+
13
+ ### registerAddress
14
+
15
+
16
+ ```solidity
17
+ function registerAddress(address deployer, uint256 nonce) external;
18
+ ```
19
+
20
+ ### registerAddress
21
+
22
+
23
+ ```solidity
24
+ function registerAddress(address deployer, bytes32 salt, bytes calldata bytecode) external;
25
+ ```
26
+
27
+ ## Events
28
+ ### AddressRegistered
29
+
30
+ ```solidity
31
+ event AddressRegistered(address indexed addr, address indexed deployer, address caller);
32
+ ```
33
+
@@ -0,0 +1,4 @@
1
+
2
+
3
+ # Contents
4
+ - [IJBAddressRegistry](IJBAddressRegistry.sol/interface.IJBAddressRegistry.md)
package/foundry.toml ADDED
@@ -0,0 +1,29 @@
1
+ [profile.default]
2
+ solc = '0.8.23'
3
+ evm_version = 'paris' # Required for L2s (Optimism, Arbitrum, etc.)
4
+ sizes = true
5
+ verbosity = 3 # display errors
6
+ optimizer_runs = 10000000
7
+ block_number = 14126430
8
+ block_timestamp = 1643802347
9
+ runs = 4096
10
+ extra_output = ['storageLayout']
11
+ fs_permissions = [{ access = "read-write", path = "./"}]
12
+
13
+ [rpc_endpoints]
14
+ ethereum ="${RPC_ETHEREUM_MAINNET}"
15
+ optimism = "${RPC_OPTIMISM_MAINNET}"
16
+ polygon = "${RPC_POLYGON_MUMBAI}"
17
+ arbitrum = "${RPC_ARBITRUM_MAINNET}"
18
+ base = "${RPC_BASE_MAINNET}"
19
+ arbitrum_sepolia = "${RPC_ARBITRUM_SEPOLIA}"
20
+ ethereum_sepolia ="${RPC_ETHEREUM_SEPOLIA}"
21
+ optimism_sepolia = "${RPC_OPTIMISM_SEPOLIA}"
22
+ polygon_mumbai = "${RPC_POLYGON_MUMBAI}"
23
+ base_sepolia = "${RPC_BASE_SEPOLIA}"
24
+
25
+
26
+ [fmt]
27
+ number_underscore = "thousands"
28
+ multiline_func_header = "all"
29
+ wrap_comments = true
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@bananapus/address-registry-v6",
3
+ "version": "0.0.1",
4
+ "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/Bananapus/nana-address-registry-v6"
8
+ },
9
+ "scripts": {
10
+ "test": "forge test",
11
+ "test:fork": "FOUNDRY_PROFILE=CI forge test",
12
+ "coverage": "forge coverage --match-path \"./src/*.sol\" --report lcov --report summary",
13
+ "deploy:mainnets": "source ./.env && npx sphinx propose ./script/Deploy.s.sol --networks mainnets",
14
+ "deploy:testnets": "source ./.env && npx sphinx propose ./script/Deploy.s.sol --networks testnets",
15
+ "artifacts": "source ./.env && npx sphinx artifacts --org-id 'ea165b21-7cdc-4d7b-be59-ecdd4c26bee4' --project-name 'nana-address-registry-v5'"
16
+ },
17
+ "dependencies": {
18
+ "@sphinx-labs/plugins": "^0.33.1"
19
+ }
20
+ }
package/remappings.txt ADDED
@@ -0,0 +1 @@
1
+ @sphinx-labs/contracts/=lib/sphinx/packages/contracts/contracts/foundry
@@ -0,0 +1,37 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ import "@sphinx-labs/contracts/SphinxPlugin.sol";
5
+ import {Script, stdJson, VmSafe} from "forge-std/Script.sol";
6
+
7
+ import "src/JBAddressRegistry.sol";
8
+
9
+ contract Deploy is Script, Sphinx {
10
+ bytes32 constant ADDRESS_REGISTRY_SALT = "_JBAddressRegistryV6_";
11
+
12
+ function configureSphinx() public override {
13
+ // TODO: Update to contain JB Emergency Developers
14
+ sphinxConfig.projectName = "nana-address-registry-v6";
15
+ sphinxConfig.mainnets = ["ethereum", "optimism", "base", "arbitrum"];
16
+ sphinxConfig.testnets = ["ethereum_sepolia", "optimism_sepolia", "base_sepolia", "arbitrum_sepolia"];
17
+ }
18
+
19
+ function run() public sphinx {
20
+ // Only deploy if this bytecode is not already deployed.
21
+ if (!_isDeployed(ADDRESS_REGISTRY_SALT, type(JBAddressRegistry).creationCode, "")) {
22
+ new JBAddressRegistry{salt: ADDRESS_REGISTRY_SALT}();
23
+ }
24
+ }
25
+
26
+ function _isDeployed(bytes32 salt, bytes memory creationCode, bytes memory arguments) internal view returns (bool) {
27
+ address _deployedTo = vm.computeCreate2Address({
28
+ salt: salt,
29
+ initCodeHash: keccak256(abi.encodePacked(creationCode, arguments)),
30
+ // Arachnid/deterministic-deployment-proxy address.
31
+ deployer: address(0x4e59b44847b379578588920cA78FbF26c0B4956C)
32
+ });
33
+
34
+ // Return if code is already present at this address.
35
+ return address(_deployedTo).code.length != 0;
36
+ }
37
+ }
@@ -0,0 +1,68 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.23;
3
+
4
+ import {stdJson} from "forge-std/Script.sol";
5
+ import {Vm} from "forge-std/Vm.sol";
6
+
7
+ import {SphinxConstants, NetworkInfo} from "@sphinx-labs/contracts/SphinxConstants.sol";
8
+ import {IJBAddressRegistry} from "../../src/interfaces/IJBAddressRegistry.sol";
9
+
10
+ struct AddressRegistryDeployment {
11
+ IJBAddressRegistry registry;
12
+ }
13
+
14
+ library AddressRegistryDeploymentLib {
15
+ // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.
16
+ address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code"))));
17
+ Vm internal constant vm = Vm(VM_ADDRESS);
18
+
19
+ function getDeployment(string memory path) internal returns (AddressRegistryDeployment memory deployment) {
20
+ // get chainId for which we need to get the deployment.
21
+ uint256 chainId = block.chainid;
22
+
23
+ // Deploy to get the constants.
24
+ // TODO: get constants without deploy.
25
+ SphinxConstants sphinxConstants = new SphinxConstants();
26
+ NetworkInfo[] memory networks = sphinxConstants.getNetworkInfoArray();
27
+
28
+ for (uint256 _i; _i < networks.length; _i++) {
29
+ if (networks[_i].chainId == chainId) {
30
+ return getDeployment(path, networks[_i].name);
31
+ }
32
+ }
33
+
34
+ revert("ChainID is not (currently) supported by Sphinx.");
35
+ }
36
+
37
+ function getDeployment(
38
+ string memory path,
39
+ string memory network_name
40
+ )
41
+ internal
42
+ view
43
+ returns (AddressRegistryDeployment memory deployment)
44
+ {
45
+ deployment.registry =
46
+ IJBAddressRegistry(_getDeploymentAddress(path, "nana-address-registry", network_name, "JBAddressRegistry"));
47
+ }
48
+
49
+ /// @notice Get the address of a contract that was deployed by the Deploy script.
50
+ /// @dev Reverts if the contract was not found.
51
+ /// @param path The path to the deployment file.
52
+ /// @param contractName The name of the contract to get the address of.
53
+ /// @return The address of the contract.
54
+ function _getDeploymentAddress(
55
+ string memory path,
56
+ string memory project_name,
57
+ string memory network_name,
58
+ string memory contractName
59
+ )
60
+ internal
61
+ view
62
+ returns (address)
63
+ {
64
+ string memory deploymentJson =
65
+ vm.readFile(string.concat(path, project_name, "/", network_name, "/", contractName, ".json"));
66
+ return stdJson.readAddress(deploymentJson, ".address");
67
+ }
68
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "detectors_to_exclude": "timestamp,uninitialized-local,naming-convention,solc-version,shadowing-local",
3
+ "exclude_informational": true,
4
+ "exclude_low": false,
5
+ "exclude_medium": false,
6
+ "exclude_high": false,
7
+ "disable_color": false,
8
+ "filter_paths": "(mocks/|test/|node_modules/)",
9
+ "legacy_ast": false
10
+ }