Skip to content
72 changes: 63 additions & 9 deletions script/integration/SymbioticCoreInit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {IERC5267} from "@openzeppelin/contracts/interfaces/IERC5267.sol";
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";

import {VmSafe} from "forge-std/Vm.sol";

contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
using SafeERC20 for IERC20;
using Math for uint256;
Expand Down Expand Up @@ -67,28 +69,38 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
symbioticCore = SymbioticCoreConstants.core();
}

// if useExisting is true, the core is not deployed, but the addresses are returned
function _initCore_SymbioticCore(
bool useExisting
) internal virtual {
if (useExisting) {
_initCore_SymbioticCore();
// return existing core
symbioticCore = SymbioticCoreConstants.core();
} else {
// non-deterministic deployment (uses standard create)
(Vm.CallerMode callerMode,, address deployer) = vm.readCallers();
if (callerMode == VmSafe.CallerMode.Broadcast) {
vm.stopBroadcast();
}
if (callerMode != VmSafe.CallerMode.RecurrentBroadcast) {
vm.startBroadcast(deployer);
}
ISymbioticVaultFactory vaultFactory = ISymbioticVaultFactory(
deployCode(
string.concat(SYMBIOTIC_CORE_PROJECT_ROOT, "out/VaultFactory.sol/VaultFactory.json"),
abi.encode(tx.origin)
abi.encode(deployer)
)
);
ISymbioticDelegatorFactory delegatorFactory = ISymbioticDelegatorFactory(
deployCode(
string.concat(SYMBIOTIC_CORE_PROJECT_ROOT, "out/DelegatorFactory.sol/DelegatorFactory.json"),
abi.encode(tx.origin)
abi.encode(deployer)
)
);
ISymbioticSlasherFactory slasherFactory = ISymbioticSlasherFactory(
deployCode(
string.concat(SYMBIOTIC_CORE_PROJECT_ROOT, "out/SlasherFactory.sol/SlasherFactory.json"),
abi.encode(tx.origin)
abi.encode(deployer)
)
);
ISymbioticNetworkRegistry networkRegistry = ISymbioticNetworkRegistry(
Expand Down Expand Up @@ -186,6 +198,23 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
);
delegatorFactory.whitelist(operatorSpecificDelegatorImpl);

address operatorNetworkSpecificDelegatorImpl = deployCode(
string.concat(
SYMBIOTIC_CORE_PROJECT_ROOT,
"out/OperatorNetworkSpecificDelegator.sol/OperatorNetworkSpecificDelegator.json"
),
abi.encode(
address(operatorRegistry),
address(networkRegistry),
address(vaultFactory),
address(operatorVaultOptInService),
address(operatorNetworkOptInService),
address(delegatorFactory),
delegatorFactory.totalTypes()
)
);
delegatorFactory.whitelist(operatorNetworkSpecificDelegatorImpl);

address slasherImpl = deployCode(
string.concat(SYMBIOTIC_CORE_PROJECT_ROOT, "out/Slasher.sol/Slasher.json"),
abi.encode(
Expand Down Expand Up @@ -229,6 +258,9 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
operatorNetworkOptInService: operatorNetworkOptInService,
vaultConfigurator: vaultConfigurator
});
if (callerMode != VmSafe.CallerMode.RecurrentBroadcast) {
vm.stopBroadcast();
}
}
}

Expand All @@ -255,7 +287,11 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
function _getVault_SymbioticCore(
address collateral
) internal virtual returns (address) {
address owner = tx.origin;
(Vm.CallerMode callerMode,, address owner) = vm.readCallers();
if (callerMode == VmSafe.CallerMode.Broadcast || callerMode == VmSafe.CallerMode.RecurrentBroadcast) {
vm.stopBroadcast();
}

uint48 epochDuration = 7 days;
uint48 vetoDuration = 1 days;

Expand All @@ -265,7 +301,7 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
operatorNetworkSharesSetRoleHolders[0] = owner;
(address vault,,) = _createVault_SymbioticCore({
symbioticCore: symbioticCore,
who: tx.origin,
who: owner,
version: 1,
owner: owner,
vaultParams: abi.encode(
Expand Down Expand Up @@ -305,6 +341,9 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
})
)
});
if (callerMode == VmSafe.CallerMode.RecurrentBroadcast) {
vm.startBroadcast(owner);
}

return vault;
}
Expand Down Expand Up @@ -425,9 +464,13 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
);
}

(Vm.CallerMode callerMode,, address deployer) = vm.readCallers();
if (callerMode == VmSafe.CallerMode.Broadcast || callerMode == VmSafe.CallerMode.RecurrentBroadcast) {
vm.stopBroadcast();
}
(address vault,,) = _createVault_SymbioticCore({
symbioticCore: symbioticCore,
who: tx.origin,
who: deployer,
version: 1,
owner: owner,
vaultParams: vaultParams,
Expand All @@ -443,6 +486,9 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
_setDepositorWhitelistStatus_SymbioticCore(owner, vault, whitelistedDepositors[i], true);
}
}
if (callerMode == VmSafe.CallerMode.RecurrentBroadcast) {
vm.startBroadcast(deployer);
}

return vault;
}
Expand Down Expand Up @@ -490,8 +536,12 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
}
uint64 slasherIndex = _randomPick_Symbiotic(slasherTypes);

return _getVault_SymbioticCore(
operators.length == 0 ? tx.origin : _randomPick_Symbiotic(operators),
(Vm.CallerMode callerMode,, address deployer) = vm.readCallers();
if (callerMode == VmSafe.CallerMode.Broadcast || callerMode == VmSafe.CallerMode.RecurrentBroadcast) {
vm.stopBroadcast();
}
address vault = _getVault_SymbioticCore(
operators.length == 0 ? deployer : _randomPick_Symbiotic(operators),
collateral,
0x000000000000000000000000000000000000dEaD,
epochDuration,
Expand All @@ -504,6 +554,10 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
slasherIndex,
vetoDuration
);
if (callerMode == VmSafe.CallerMode.RecurrentBroadcast) {
vm.startBroadcast(deployer);
}
return vault;
}

function _vaultValidating_SymbioticCore(address vault, bytes32 subnetwork) internal virtual returns (bool) {
Expand Down
24 changes: 20 additions & 4 deletions script/integration/SymbioticInit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,31 @@ contract SymbioticInit is Script, SymbioticCounter {
}

function _deal_Symbiotic(address token, address to, uint256 give) public virtual {
vm.startBroadcast(tx.origin);
(Vm.CallerMode callerMode,, address txOrigin) = vm.readCallers();
if (callerMode == VmSafe.CallerMode.Broadcast) {
vm.stopBroadcast();
}
if (callerMode != VmSafe.CallerMode.RecurrentBroadcast) {
vm.startBroadcast(txOrigin);
}
IERC20(token).safeTransfer(to, give);
vm.stopBroadcast();
if (callerMode != VmSafe.CallerMode.RecurrentBroadcast) {
vm.stopBroadcast();
}
}

function _deal_Symbiotic(address to, uint256 give) public virtual {
vm.startBroadcast(tx.origin);
(Vm.CallerMode callerMode,, address txOrigin) = vm.readCallers();
if (callerMode == VmSafe.CallerMode.Broadcast) {
vm.stopBroadcast();
}
if (callerMode != VmSafe.CallerMode.RecurrentBroadcast) {
vm.startBroadcast(txOrigin);
}
to.call{value: give}("");
vm.stopBroadcast();
if (callerMode != VmSafe.CallerMode.RecurrentBroadcast) {
vm.stopBroadcast();
}
}

function _vmWalletToAddress_Symbiotic(
Expand Down
7 changes: 4 additions & 3 deletions script/integration/examples/OnboardNetwork.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ contract OnboardNetworkScript is SymbioticCoreInit {

SYMBIOTIC_CORE_DELEGATOR_TYPES = [0, 2];

address NETWORK = tx.origin;
(,, address txOrigin) = vm.readCallers();
address NETWORK = txOrigin;
uint96 IDENTIFIER = 0;
bytes32 SUBNETWORK = NETWORK.subnetwork(IDENTIFIER);
address COLLATERAL = SymbioticCoreConstants.wstETH();
Expand All @@ -51,13 +52,13 @@ contract OnboardNetworkScript is SymbioticCoreInit {
super.run(seed);

if (COLLATERAL == SymbioticCoreConstants.wstETH()) {
uint256 balanceBefore = IERC20(COLLATERAL).balanceOf(tx.origin);
uint256 balanceBefore = IERC20(COLLATERAL).balanceOf(txOrigin);
uint256 requiredAmount = _normalizeForToken_Symbiotic(SYMBIOTIC_CORE_TOKENS_TO_SET_TIMES_1e18, COLLATERAL)
* SYMBIOTIC_CORE_NUMBER_OF_STAKERS;
if (balanceBefore < requiredAmount) {
address stETH = IwstETH(COLLATERAL).stETH();
uint256 toSend = IwstETH(COLLATERAL).getStETHByWstETH(requiredAmount - balanceBefore) * 101 / 100;
vm.startBroadcast(tx.origin);
vm.startBroadcast(txOrigin);
stETH.call{value: toSend}("");
IERC20(stETH).forceApprove(COLLATERAL, toSend);
IwstETH(COLLATERAL).wrap(toSend);
Expand Down
70 changes: 61 additions & 9 deletions test/integration/SymbioticCoreInit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,28 +65,38 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
symbioticCore = SymbioticCoreConstants.core();
}

// if useExisting is true, the core is not deployed, but the addresses are returned
function _initCore_SymbioticCore(
bool useExisting
) internal virtual {
if (useExisting) {
_initCore_SymbioticCore();
// return existing core
symbioticCore = SymbioticCoreConstants.core();
} else {
// non-deterministic deployment (uses standard create)
(VmSafe.CallerMode callerMode,, address deployer) = vm.readCallers();
if (callerMode == VmSafe.CallerMode.Prank) {
vm.stopPrank();
}
if (callerMode != VmSafe.CallerMode.RecurrentPrank) {
vm.startPrank(deployer);
}
ISymbioticVaultFactory vaultFactory = ISymbioticVaultFactory(
deployCode(
string.concat(SYMBIOTIC_CORE_PROJECT_ROOT, "out/VaultFactory.sol/VaultFactory.json"),
abi.encode(address(this))
abi.encode(deployer)
)
);
ISymbioticDelegatorFactory delegatorFactory = ISymbioticDelegatorFactory(
deployCode(
string.concat(SYMBIOTIC_CORE_PROJECT_ROOT, "out/DelegatorFactory.sol/DelegatorFactory.json"),
abi.encode(address(this))
abi.encode(deployer)
)
);
ISymbioticSlasherFactory slasherFactory = ISymbioticSlasherFactory(
deployCode(
string.concat(SYMBIOTIC_CORE_PROJECT_ROOT, "out/SlasherFactory.sol/SlasherFactory.json"),
abi.encode(address(this))
abi.encode(deployer)
)
);
ISymbioticNetworkRegistry networkRegistry = ISymbioticNetworkRegistry(
Expand Down Expand Up @@ -184,6 +194,23 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
);
delegatorFactory.whitelist(operatorSpecificDelegatorImpl);

address operatorNetworkSpecificDelegatorImpl = deployCode(
string.concat(
SYMBIOTIC_CORE_PROJECT_ROOT,
"out/OperatorNetworkSpecificDelegator.sol/OperatorNetworkSpecificDelegator.json"
),
abi.encode(
address(operatorRegistry),
address(networkRegistry),
address(vaultFactory),
address(operatorVaultOptInService),
address(operatorNetworkOptInService),
address(delegatorFactory),
delegatorFactory.totalTypes()
)
);
delegatorFactory.whitelist(operatorNetworkSpecificDelegatorImpl);

address slasherImpl = deployCode(
string.concat(SYMBIOTIC_CORE_PROJECT_ROOT, "out/Slasher.sol/Slasher.json"),
abi.encode(
Expand Down Expand Up @@ -227,6 +254,9 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
operatorNetworkOptInService: operatorNetworkOptInService,
vaultConfigurator: vaultConfigurator
});
if (callerMode != VmSafe.CallerMode.RecurrentPrank) {
vm.stopPrank();
}
}
}

Expand All @@ -253,7 +283,11 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
function _getVault_SymbioticCore(
address collateral
) internal virtual returns (address) {
address owner = address(this);
(Vm.CallerMode callerMode,, address owner) = vm.readCallers();
if (callerMode == VmSafe.CallerMode.Prank || callerMode == VmSafe.CallerMode.RecurrentPrank) {
vm.stopPrank();
}

uint48 epochDuration = 7 days;
uint48 vetoDuration = 1 days;

Expand All @@ -263,7 +297,7 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
operatorNetworkSharesSetRoleHolders[0] = owner;
(address vault,,) = _createVault_SymbioticCore({
symbioticCore: symbioticCore,
who: address(this),
who: owner,
version: 1,
owner: owner,
vaultParams: abi.encode(
Expand Down Expand Up @@ -303,6 +337,9 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
})
)
});
if (callerMode == VmSafe.CallerMode.RecurrentPrank) {
vm.startPrank(owner);
}

return vault;
}
Expand Down Expand Up @@ -423,9 +460,13 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
);
}

(Vm.CallerMode callerMode,, address deployer) = vm.readCallers();
if (callerMode == VmSafe.CallerMode.Prank || callerMode == VmSafe.CallerMode.RecurrentPrank) {
vm.stopPrank();
}
(address vault,,) = _createVault_SymbioticCore({
symbioticCore: symbioticCore,
who: address(this),
who: deployer,
version: 1,
owner: owner,
vaultParams: vaultParams,
Expand All @@ -441,6 +482,9 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
_setDepositorWhitelistStatus_SymbioticCore(owner, vault, whitelistedDepositors[i], true);
}
}
if (callerMode == VmSafe.CallerMode.RecurrentPrank) {
vm.startPrank(owner);
}

return vault;
}
Expand Down Expand Up @@ -488,8 +532,12 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
}
uint64 slasherIndex = _randomPick_Symbiotic(slasherTypes);

return _getVault_SymbioticCore(
operators.length == 0 ? address(this) : _randomPick_Symbiotic(operators),
(Vm.CallerMode callerMode,, address deployer) = vm.readCallers();
if (callerMode == VmSafe.CallerMode.Prank || callerMode == VmSafe.CallerMode.RecurrentPrank) {
vm.stopPrank();
}
address vault = _getVault_SymbioticCore(
operators.length == 0 ? deployer : _randomPick_Symbiotic(operators),
collateral,
0x000000000000000000000000000000000000dEaD,
epochDuration,
Expand All @@ -502,6 +550,10 @@ contract SymbioticCoreInit is SymbioticInit, SymbioticCoreBindings {
slasherIndex,
vetoDuration
);
if (callerMode == VmSafe.CallerMode.RecurrentPrank) {
vm.startPrank(deployer);
}
return vault;
}

function _vaultValidating_SymbioticCore(address vault, bytes32 subnetwork) internal virtual returns (bool) {
Expand Down