Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions script/CreateAndStake.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,8 @@ contract CreateAndStake is Script {
// Address of the EthMultiVault contract
address payable public constant ETH_MULTI_VAULT = payable(0x63B90A9c109fF8f137916026876171ffeEdEe714);

bytes[] public ATOM_URIS = [
bytes("intuition.systems"),
bytes("is"),
bytes("bullish"),
bytes("cat"),
bytes("internet")
];
bytes[] public ATOM_URIS =
[bytes("intuition.systems"), bytes("is"), bytes("bullish"), bytes("cat"), bytes("internet")];

uint256[] public ATOM_IDS;

Expand Down
107 changes: 73 additions & 34 deletions script/Deploy.s.sol → script/DeployToBase.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {BondingCurveRegistry} from "src/BondingCurveRegistry.sol";
import {ProgressiveCurve} from "src/ProgressiveCurve.sol";
import {LinearCurve} from "src/LinearCurve.sol";

contract DeployEthMultiVault is Script {
contract DeployToBase is Script {
// Multisig addresses for key roles in the protocol
address public admin = 0xa28d4AAcA48bE54824dA53a19b05121DE71Ef480;
address public protocolMultisig = 0xC03F0dE5b34339e1B968e4f317Cd7e7FBd421FD1;
Expand All @@ -36,17 +36,23 @@ contract DeployEthMultiVault is Script {
TimelockController public timelock;

// Bonding Curves
TransparentUpgradeableProxy public bondingCurveRegistryProxy;
BondingCurveRegistry public bondingCurveRegistry;
TransparentUpgradeableProxy public bondingCurveRegistryProxy;
LinearCurve public linearCurve; // <-- Not used in this edition of EthMultiVault
ProgressiveCurve public progressiveCurve;

error UnsupportedChainId();

function run() external {
// Begin sending tx's to network
vm.startBroadcast();

// Check if the script is running on the correct network
uint256 chainId = block.chainid;
if (chainId != 8453) revert UnsupportedChainId();

// TimelockController parameters
uint256 minDelay = 1 minutes; // 1 minute during the setup stage; should be updated to 7 days later on
uint256 minDelay = 3 days;
address[] memory proposers = new address[](1);
address[] memory executors = new address[](1);

Expand All @@ -56,11 +62,13 @@ contract DeployEthMultiVault is Script {
// deploy TimelockController
timelock = new TimelockController(
minDelay, // minimum delay for timelock transactions
proposers, // proposers (can schedule transactions)
executors, // executors (can execute transactions) - open role
address(0) // no default admin that can change things without going through the timelock process (self-administered)
proposers, // proposers (can schedule and cancel transactions)
executors, // executors (can execute transactions; address(0) means it's an open role, i.e. anyone can execute the scheduled transactions)
address(0) // no optional admin that can change things without going through the timelock process
);
console.logString("deployed TimelockController.");
console.logString("encoded constructor args: ");
console.logBytes(abi.encode(minDelay, proposers, executors, address(0)));

// deploy AtomWallet implementation contract
atomWallet = new AtomWallet();
Expand All @@ -69,72 +77,95 @@ contract DeployEthMultiVault is Script {
// deploy AtomWalletBeacon pointing to the AtomWallet implementation contract
atomWalletBeacon = new UpgradeableBeacon(address(atomWallet), address(timelock));
console.logString("deployed UpgradeableBeacon.");
console.logString("encoded constructor args: ");
console.logBytes(abi.encode(address(atomWallet), address(timelock)));

IEthMultiVault.GeneralConfig memory generalConfig = IEthMultiVault.GeneralConfig({
admin: admin, // Admin address for the EthMultiVault contract
protocolMultisig: protocolMultisig, // Protocol multisig address
feeDenominator: 10000, // Common denominator for fee calculations
minDeposit: 0.00042 ether, // Minimum deposit amount in wei
minDeposit: 0.000025 ether, // Minimum deposit amount in wei
minShare: 1e6, // Minimum share amount (e.g., for vault initialization)
atomUriMaxLength: 250, // Maximum length of the atom URI data that can be passed when creating atom vaults
decimalPrecision: 1e18, // decimal precision used for calculating share prices
minDelay: 3 days // minimum delay for timelocked transactions
minDelay: 1 days // minimum delay for timelocked transactions
});

IEthMultiVault.AtomConfig memory atomConfig = IEthMultiVault.AtomConfig({
atomWalletInitialDepositAmount: 0.00003 ether, // Fee charged for purchasing vault shares for the atom wallet upon creation
atomCreationProtocolFee: 0.0003 ether // Fee charged for creating an atom
atomWalletInitialDepositAmount: 0.000003 ether, // Fee charged for purchasing vault shares for the atom wallet upon creation
atomCreationProtocolFee: 0.000003 ether // Fee charged for creating an atom
});

IEthMultiVault.TripleConfig memory tripleConfig = IEthMultiVault.TripleConfig({
tripleCreationProtocolFee: 0.0003 ether, // Fee for creating a triple
totalAtomDepositsOnTripleCreation: 0.00003 ether, // Static fee going towards increasing the amount of assets in the underlying atom vaults
atomDepositFractionForTriple: 900 // Fee for equity in atoms when creating a triple
tripleCreationProtocolFee: 0.000003 ether, // Fee for creating a triple
atomDepositFractionOnTripleCreation: 0.000003 ether, // Static fee going towards increasing the amount of assets in the underlying atom vaults
atomDepositFractionForTriple: 300 // Fee for equity in atoms when creating a triple
});

IEthMultiVault.WalletConfig memory walletConfig = IEthMultiVault.WalletConfig({
permit2: IPermit2(address(permit2)), // Permit2 on Base
entryPoint: entryPoint, // EntryPoint address on Base
permit2: IPermit2(address(permit2)), // Permit2 on Linea
entryPoint: entryPoint, // EntryPoint address on Linea
atomWarden: atomWarden, // atomWarden address
atomWalletBeacon: address(atomWalletBeacon) // Address of the AtomWalletBeacon contract
});

IEthMultiVault.VaultFees memory vaultFees = IEthMultiVault.VaultFees({
entryFee: 500, // Entry fee for vault 0
exitFee: 500, // Exit fee for vault 0
protocolFee: 250 // Protocol fee for vault 0
protocolFee: 100 // Protocol fee for vault 0
});

IEthMultiVault.BondingCurveConfig memory bondingCurveConfig = IEthMultiVault.BondingCurveConfig({
registry: address(bondingCurveRegistry),
defaultCurveId: 1 // Unused in this edition of EthMultiVault
});

// ------------------------------- Bonding Curves----------------------------------------

// Deploy BondingCurveRegistry and take temporary ownership to add the curves
bondingCurveRegistry = new BondingCurveRegistry(msg.sender);
console.logString("deployed BondingCurveRegistry.");
bondingCurveRegistry = new BondingCurveRegistry();
console.logString("deployed BondingCurveRegistry implementation.");

address bondingCurveRegistryImplementation = address(bondingCurveRegistry);

bytes memory bondingCurveRegistryInitData =
abi.encodeWithSelector(BondingCurveRegistry.initialize.selector, msg.sender);

// Deploy BondingCurveRegistry proxy
bondingCurveRegistryProxy = new TransparentUpgradeableProxy(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the bonding curve registry is a proxy, and we don't need this. It doesn't store any important state (outside of the bonding curve IDs), so if we ever wanted a new one we can just deploy a new one and point the multivault config at it.

If we did this, we would need to ensure that any new registry just has the same bonding curve IDs as the old one. Because the curve IDs are tied to the economic state in the MultiVault, we never want to change them. Only add to them.

address(bondingCurveRegistry), // BondingCurveRegistry logic contract address
address(timelock), // Timelock controller address, which will be the owner of the ProxyAdmin contract for the proxy
bondingCurveRegistryInitData // Initialization data to call the `initialize` function in BondingCurveRegistry
);
console.logString("deployed BondingCurveRegistry proxy.");
console.logString("encoded constructor args: ");
console.logBytes(abi.encode(address(bondingCurveRegistry), address(timelock), bondingCurveRegistryInitData));

// Deploy LinearCurve
linearCurve = new LinearCurve("Linear Curve");
console.logString("deployed LinearCurve.");
console.logString("encoded constructor args: ");
console.logBytes(abi.encode("Linear Curve"));

// Deploy ProgressiveCurve
progressiveCurve = new ProgressiveCurve("Progressive Curve", 2);
console.logString("deployed ProgressiveCurve.");
progressiveCurve = new ProgressiveCurve("Progressive Curve", 0.00007054e18);
console.log("deployed ProgressiveCurve.");
console.logString("encoded constructor args: ");
console.logBytes(abi.encode("Progressive Curve", 0.00007054e18));

// Reference to the BondingCurveRegistry proxy contract
bondingCurveRegistry = BondingCurveRegistry(address(bondingCurveRegistryProxy));

// Add curves to BondingCurveRegistry
bondingCurveRegistry.addBondingCurve(address(linearCurve));
bondingCurveRegistry.addBondingCurve(address(progressiveCurve));

// Transfer ownership of BondingCurveRegistry to the timelock
bondingCurveRegistry.transferOwnership(address(timelock));
// NOTE: TimelockController needs to accept the ownership of the BondingCurveRegistry in order to become a new owner

IEthMultiVault.BondingCurveConfig memory bondingCurveConfig = IEthMultiVault.BondingCurveConfig({
registry: address(bondingCurveRegistry),
defaultCurveId: 1 // Unused in this edition of EthMultiVault
});
// Transfer ownership of BondingCurveRegistry to multisig
bondingCurveRegistry.transferOwnership(admin);

// -------------------------------------------------------------------------------------

// Prepare data for initializer function of EthMultiVault
// Prepare data for initializer function
bytes memory initData = abi.encodeWithSelector(
EthMultiVault.init.selector,
generalConfig,
Expand All @@ -147,28 +178,36 @@ contract DeployEthMultiVault is Script {

// Deploy EthMultiVault implementation contract
ethMultiVault = new EthMultiVault();
console.logString("deployed EthMultiVault implementation.");
console.logString("deployed EthMultiVault.");

// Deploy TransparentUpgradeableProxy with EthMultiVault logic contract
ethMultiVaultProxy = new TransparentUpgradeableProxy(
address(ethMultiVault), // EthMultiVault logic contract address
address(timelock), // Timelock controller address, which will be the owner of the ProxyAdmin contract for the proxy
initData // Initialization data to call the `init` function in EthMultiVault
);
console.logString("deployed EthMultiVault proxy.");
console.logString("deployed TransparentUpgradeableProxy.");
console.logString("encoded constructor args: ");
console.logBytes(abi.encode(address(ethMultiVault), address(timelock), initData));

console.log("encoded constructor args for the ProxyAdmin: ");
console.logBytes(abi.encode(address(timelock)));

// stop sending tx's
vm.stopBroadcast();

console.log("All contracts deployed successfully:");
console.log("All contracts deployed successfully!");
console.log("TimelockController address:", address(timelock));
console.log("AtomWallet implementation address:", address(atomWallet));
console.log("UpgradeableBeacon address:", address(atomWalletBeacon));
console.log("EthMultiVault implementation address:", address(ethMultiVault));
console.log("EthMultiVault proxy address:", address(ethMultiVaultProxy));
console.log("BondingCurveRegistry address:", address(bondingCurveRegistry));
console.log("BondingCurveRegistry implementation address:", bondingCurveRegistryImplementation);
console.log("BondingCurveRegistry proxy address:", address(bondingCurveRegistryProxy));
console.log("LinearCurve address:", address(linearCurve));
console.log("ProgressiveCurve address:", address(progressiveCurve));
console.log(
"To find the address of the ProxyAdmin contract for the EthMultiVault proxy, inspect the creation transaction of the EthMultiVault proxy contract on Basescan, in particular the AdminChanged event. Same applies to the CustomMulticall3 proxy contract."
"To find the address of the ProxyAdmin contract for the EthMultiVault proxy, inspect the creation transaction of the EthMultiVault proxy contract on Basescan, in particular the AdminChanged event. Same applies to the BondingCurveRegistry proxy contract."
);
}
}
Loading
Loading