Skip to content

Commit cac25bd

Browse files
committed
Add ERC-20 Vaults
move to gitmodules go from puts -> generic options builds distribute assets on excercise add vault authenticator add erc20 vault authenticity handling and factory
1 parent eb0302c commit cac25bd

File tree

7 files changed

+573
-2
lines changed

7 files changed

+573
-2
lines changed

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
ignore = dirty
55
[submodule "lib/narya-contracts"]
66
path = lib/narya-contracts
7-
url = https://github.com/NaryaAI/narya-contracts
7+
url = https://github.com/NaryaAI/narya-contracts

remappings.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
@openzeppelin/contracts=node_modules/@openzeppelin/contracts
22
@narya-ai/contracts/=lib/narya-contracts/
3-
forge-std/=lib/forge-std/src/
3+
forge-std/=lib/forge-std/src/

src/HookERC20VaultFactory.sol

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// SPDX-License-Identifier: MIT
2+
//
3+
// █████████████▌ ▐█████████████
4+
// █████████████▌ ▐█████████████
5+
// █████████████▌ ▐█████████████
6+
// █████████████▌ ▐█████████████
7+
// █████████████▌ ▐█████████████
8+
// █████████████▌ ▐█████████████
9+
// █████████████▌ ▐█████████████
10+
// █████████████▌ ▐█████████████
11+
// ██████████████ ██████████████
12+
// ██████████████ ▄▄████████████████▄▄ ▐█████████████▌
13+
// ██████████████ ▄█████████████████████████████▄ ██████████████
14+
// ██████████▀ ▄█████████████████████████████████ ██████████████▌
15+
// ██████▀ ▄██████████████████████████████████▀ ▄███████████████
16+
// ███▀ ██████████████████████████████████▀ ▄████████████████
17+
// ▀▀ ████████████████████████████████▀▀ ▄█████████████████▌
18+
// █████████████████████▀▀▀▀▀▀▀ ▄▄███████████████████▀
19+
// ██████████████████▀ ▄▄▄█████████████████████████████▀
20+
// ████████████████▀ ▄█████████████████████████████████▀ ██▄
21+
// ▐███████████████▀ ▄██████████████████████████████████▀ █████▄
22+
// ██████████████▀ ▄█████████████████████████████████▀ ▄████████
23+
// ██████████████▀ ███████████████████████████████▀ ▄████████████
24+
// ▐█████████████▌ ▀▀▀▀████████████████████▀▀▀▀ █████████████▌
25+
// ██████████████ ██████████████
26+
// █████████████▌ ██████████████
27+
// █████████████▌ ██████████████
28+
// █████████████▌ ██████████████
29+
// █████████████▌ ██████████████
30+
// █████████████▌ ██████████████
31+
// █████████████▌ ██████████████
32+
// █████████████▌ ██████████████
33+
// █████████████▌ ██████████████
34+
35+
pragma solidity ^0.8.10;
36+
37+
import "@openzeppelin/contracts/utils/Create2.sol";
38+
39+
import "./HookBeaconProxy.sol";
40+
41+
import "./interfaces/IHookERC20VaultFactory.sol";
42+
import "./interfaces/IHookERC20Vault.sol";
43+
import "./interfaces/IHookProtocol.sol";
44+
import "./interfaces/IInitializeableBeacon.sol";
45+
46+
import "./mixin/PermissionConstants.sol";
47+
48+
import "./lib/BeaconSalts.sol";
49+
50+
/// @title Hook Vault Factory
51+
/// @author Jake Nyquist-j@hook.xyz
52+
/// @dev See {IHookERC20VaultFactory}.
53+
/// @dev The factory itself is non-upgradeable; however, each vault is upgradeable (i.e. all vaults)
54+
/// created by this factory can be upgraded at one time via the beacon pattern.
55+
contract HookER20VaultFactory is IHookERC20VaultFactory, PermissionConstants {
56+
/// @notice Registry of all of the active multi-vaults within the protocol
57+
mapping(address => IHookERC20Vault) public override getVault;
58+
59+
address private immutable _hookProtocol;
60+
address private immutable _beacon;
61+
62+
constructor(address hookProtocolAddress, address beaconAddress) {
63+
require(Address.isContract(hookProtocolAddress), "hook protocol must be a contract");
64+
require(Address.isContract(beaconAddress), "beacon address must be a contract");
65+
_hookProtocol = hookProtocolAddress;
66+
_beacon = beaconAddress;
67+
}
68+
69+
/// @notice See {IHookERC29VaultFactory-makeVault}.
70+
function makeVault(address tokenAddress) public returns (IHookERC20Vault) {
71+
require(
72+
IHookProtocol(_hookProtocol).hasRole(ALLOWLISTER_ROLE, msg.sender)
73+
|| IHookProtocol(_hookProtocol).hasRole(ALLOWLISTER_ROLE, address(0)),
74+
"makeVault-Only accounts with the ALLOWLISTER role can make new vaults"
75+
);
76+
77+
require(getVault[tokenAddress] == IHookERC20Vault(address(0)), "makeVault-vault cannot already exist");
78+
79+
IInitializeableBeacon bp = IInitializeableBeacon(
80+
Create2.deploy(0, BeaconSalts.erc20VaultSalt(tokenAddress), type(HookBeaconProxy).creationCode)
81+
);
82+
83+
bp.initializeBeacon(
84+
_beacon,
85+
/// This is the ABI encoded initializer on the IHookERC20Vault.sol
86+
abi.encodeWithSignature("initialize(address,address)", tokenAddress, _hookProtocol)
87+
);
88+
89+
IHookERC20Vault vault = IHookERC20Vault(address(bp));
90+
getVault[tokenAddress] = vault;
91+
emit ERC20VaultCreated(tokenAddress, address(bp));
92+
93+
return vault;
94+
}
95+
96+
/// @notice See {IHookERC20VaultFactory-findOrCreateVault}.
97+
function findOrCreateVault(address tokenAddress) external returns (IHookERC20Vault) {
98+
if (getVault[tokenAddress] != IHookERC20Vault(address(0))) {
99+
return getVault[tokenAddress];
100+
}
101+
102+
return makeVault(tokenAddress);
103+
}
104+
}

0 commit comments

Comments
 (0)